summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/CMakeLists.txt6
-rw-r--r--storage/connect/ha_connect.cc1
-rw-r--r--storage/connect/jdbconn.cpp1
-rw-r--r--storage/connect/mysql-test/connect/disabled.def1
-rw-r--r--storage/connect/mysql-test/connect/t/ini_grant.result89
-rw-r--r--storage/connect/tabrest.h5
-rw-r--r--storage/innobase/btr/btr0btr.cc98
-rw-r--r--storage/innobase/btr/btr0bulk.cc133
-rw-r--r--storage/innobase/btr/btr0cur.cc427
-rw-r--r--storage/innobase/btr/btr0defragment.cc14
-rw-r--r--storage/innobase/btr/btr0pcur.cc26
-rw-r--r--storage/innobase/btr/btr0scrub.cc2
-rw-r--r--storage/innobase/btr/btr0sea.cc645
-rw-r--r--storage/innobase/buf/buf0buddy.cc43
-rw-r--r--storage/innobase/buf/buf0buf.cc501
-rw-r--r--storage/innobase/buf/buf0dblwr.cc165
-rw-r--r--storage/innobase/buf/buf0dump.cc13
-rw-r--r--storage/innobase/buf/buf0flu.cc66
-rw-r--r--storage/innobase/buf/buf0lru.cc280
-rw-r--r--storage/innobase/buf/buf0rea.cc38
-rw-r--r--storage/innobase/data/data0data.cc47
-rw-r--r--storage/innobase/dict/dict0boot.cc2
-rw-r--r--storage/innobase/dict/dict0crea.cc71
-rw-r--r--storage/innobase/dict/dict0dict.cc314
-rw-r--r--storage/innobase/dict/dict0load.cc20
-rw-r--r--storage/innobase/dict/dict0mem.cc161
-rw-r--r--storage/innobase/dict/dict0stats.cc162
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc14
-rw-r--r--storage/innobase/eval/eval0eval.cc295
-rw-r--r--storage/innobase/fil/fil0crypt.cc207
-rw-r--r--storage/innobase/fil/fil0fil.cc368
-rw-r--r--storage/innobase/fil/fil0pagecompress.cc16
-rw-r--r--storage/innobase/fsp/fsp0file.cc21
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc290
-rw-r--r--storage/innobase/fts/fts0config.cc20
-rw-r--r--storage/innobase/fts/fts0fts.cc1852
-rw-r--r--storage/innobase/fts/fts0opt.cc101
-rw-r--r--storage/innobase/fts/fts0que.cc66
-rw-r--r--storage/innobase/fts/fts0sql.cc11
-rw-r--r--storage/innobase/gis/gis0geo.cc55
-rw-r--r--storage/innobase/gis/gis0rtree.cc71
-rw-r--r--storage/innobase/gis/gis0sea.cc268
-rw-r--r--storage/innobase/handler/ha_innodb.cc782
-rw-r--r--storage/innobase/handler/ha_innodb.h25
-rw-r--r--storage/innobase/handler/ha_xtradb.h23
-rw-r--r--storage/innobase/handler/handler0alter.cc105
-rw-r--r--storage/innobase/handler/i_s.cc87
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc104
-rw-r--r--storage/innobase/include/btr0btr.h7
-rw-r--r--storage/innobase/include/btr0btr.ic2
-rw-r--r--storage/innobase/include/btr0bulk.h10
-rw-r--r--storage/innobase/include/btr0cur.h54
-rw-r--r--storage/innobase/include/btr0defragment.h2
-rw-r--r--storage/innobase/include/btr0pcur.h11
-rw-r--r--storage/innobase/include/btr0pcur.ic8
-rw-r--r--storage/innobase/include/btr0sea.h70
-rw-r--r--storage/innobase/include/btr0sea.ic41
-rw-r--r--storage/innobase/include/buf0buf.h81
-rw-r--r--storage/innobase/include/buf0buf.ic14
-rw-r--r--storage/innobase/include/buf0lru.h11
-rw-r--r--storage/innobase/include/data0data.h6
-rw-r--r--storage/innobase/include/data0data.ic20
-rw-r--r--storage/innobase/include/dict0crea.h10
-rw-r--r--storage/innobase/include/dict0dict.h25
-rw-r--r--storage/innobase/include/dict0dict.ic8
-rw-r--r--storage/innobase/include/dict0load.h10
-rw-r--r--storage/innobase/include/dict0mem.h252
-rw-r--r--storage/innobase/include/dict0stats.h12
-rw-r--r--storage/innobase/include/dict0stats.ic43
-rw-r--r--storage/innobase/include/dyn0buf.h96
-rw-r--r--storage/innobase/include/fil0fil.h136
-rw-r--r--storage/innobase/include/fsp0fsp.h113
-rw-r--r--storage/innobase/include/fts0ast.h2
-rw-r--r--storage/innobase/include/fts0fts.h56
-rw-r--r--storage/innobase/include/fts0priv.h8
-rw-r--r--storage/innobase/include/fts0priv.ic10
-rw-r--r--storage/innobase/include/fts0types.h23
-rw-r--r--storage/innobase/include/fts0types.ic11
-rw-r--r--storage/innobase/include/gis0geo.h13
-rw-r--r--storage/innobase/include/gis0rtree.h39
-rw-r--r--storage/innobase/include/gis0rtree.ic22
-rw-r--r--storage/innobase/include/gis0type.h8
-rw-r--r--storage/innobase/include/ha_prototypes.h23
-rw-r--r--storage/innobase/include/handler0alter.h4
-rw-r--r--storage/innobase/include/hash0hash.h12
-rw-r--r--storage/innobase/include/ib0mutex.h6
-rw-r--r--storage/innobase/include/lock0lock.h19
-rw-r--r--storage/innobase/include/lock0priv.h3
-rw-r--r--storage/innobase/include/lock0priv.ic2
-rw-r--r--storage/innobase/include/log0log.h25
-rw-r--r--storage/innobase/include/log0log.ic25
-rw-r--r--storage/innobase/include/log0recv.h85
-rw-r--r--storage/innobase/include/mem0mem.h11
-rw-r--r--storage/innobase/include/mem0mem.ic34
-rw-r--r--storage/innobase/include/mtr0mtr.h12
-rw-r--r--storage/innobase/include/mtr0mtr.ic4
-rw-r--r--storage/innobase/include/mtr0types.h7
-rw-r--r--storage/innobase/include/os0file.h3
-rw-r--r--storage/innobase/include/os0once.h118
-rw-r--r--storage/innobase/include/page0cur.h15
-rw-r--r--storage/innobase/include/page0cur.ic4
-rw-r--r--storage/innobase/include/page0page.h41
-rw-r--r--storage/innobase/include/page0page.ic30
-rw-r--r--storage/innobase/include/page0size.h2
-rw-r--r--storage/innobase/include/page0types.h3
-rw-r--r--storage/innobase/include/page0zip.h25
-rw-r--r--storage/innobase/include/page0zip.ic4
-rw-r--r--storage/innobase/include/pars0grm.h158
-rw-r--r--storage/innobase/include/pars0pars.h35
-rw-r--r--storage/innobase/include/que0que.h15
-rw-r--r--storage/innobase/include/que0que.ic15
-rw-r--r--storage/innobase/include/rem0cmp.h68
-rw-r--r--storage/innobase/include/rem0cmp.ic35
-rw-r--r--storage/innobase/include/rem0rec.h147
-rw-r--r--storage/innobase/include/rem0rec.ic123
-rw-r--r--storage/innobase/include/rem0types.h4
-rw-r--r--storage/innobase/include/row0ftsort.h3
-rw-r--r--storage/innobase/include/row0ins.h15
-rw-r--r--storage/innobase/include/row0log.h8
-rw-r--r--storage/innobase/include/row0merge.h16
-rw-r--r--storage/innobase/include/row0mysql.h42
-rw-r--r--storage/innobase/include/row0row.h24
-rw-r--r--storage/innobase/include/row0row.ic8
-rw-r--r--storage/innobase/include/row0upd.h55
-rw-r--r--storage/innobase/include/row0upd.ic2
-rw-r--r--storage/innobase/include/row0vers.h6
-rw-r--r--storage/innobase/include/span.h145
-rw-r--r--storage/innobase/include/srv0mon.h10
-rw-r--r--storage/innobase/include/srv0srv.h24
-rw-r--r--storage/innobase/include/srv0start.h2
-rw-r--r--storage/innobase/include/sync0rw.h8
-rw-r--r--storage/innobase/include/sync0sync.h4
-rw-r--r--storage/innobase/include/sync0types.h16
-rw-r--r--storage/innobase/include/trx0rec.h4
-rw-r--r--storage/innobase/include/trx0roll.h11
-rw-r--r--storage/innobase/include/trx0trx.h32
-rw-r--r--storage/innobase/include/univ.i61
-rw-r--r--storage/innobase/include/ut0mutex.h16
-rw-r--r--storage/innobase/include/ut0pool.h23
-rw-r--r--storage/innobase/include/ut0rnd.h79
-rw-r--r--storage/innobase/include/ut0rnd.ic94
-rw-r--r--storage/innobase/include/ut0ut.h85
-rw-r--r--storage/innobase/innodb.cmake8
-rw-r--r--storage/innobase/lock/lock0lock.cc380
-rw-r--r--storage/innobase/lock/lock0wait.cc10
-rw-r--r--storage/innobase/log/log0log.cc22
-rw-r--r--storage/innobase/log/log0recv.cc478
-rw-r--r--storage/innobase/mem/mem0mem.cc14
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc83
-rw-r--r--storage/innobase/os/os0file.cc147
-rw-r--r--storage/innobase/os/os0proc.cc15
-rw-r--r--storage/innobase/os/os0thread.cc10
-rw-r--r--storage/innobase/page/page0cur.cc171
-rw-r--r--storage/innobase/page/page0page.cc116
-rw-r--r--storage/innobase/page/page0zip.cc269
-rw-r--r--storage/innobase/pars/lexyy.cc1166
-rw-r--r--storage/innobase/pars/pars0grm.cc2116
-rw-r--r--storage/innobase/pars/pars0grm.y118
-rw-r--r--storage/innobase/pars/pars0lex.l84
-rw-r--r--storage/innobase/pars/pars0pars.cc144
-rw-r--r--storage/innobase/que/que0que.cc4
-rw-r--r--storage/innobase/rem/rem0cmp.cc114
-rw-r--r--storage/innobase/rem/rem0rec.cc123
-rw-r--r--storage/innobase/row/row0ext.cc6
-rw-r--r--storage/innobase/row/row0ftsort.cc52
-rw-r--r--storage/innobase/row/row0import.cc211
-rw-r--r--storage/innobase/row/row0ins.cc352
-rw-r--r--storage/innobase/row/row0log.cc101
-rw-r--r--storage/innobase/row/row0merge.cc175
-rw-r--r--storage/innobase/row/row0mysql.cc201
-rw-r--r--storage/innobase/row/row0purge.cc36
-rw-r--r--storage/innobase/row/row0row.cc39
-rw-r--r--storage/innobase/row/row0sel.cc412
-rw-r--r--storage/innobase/row/row0trunc.cc13
-rw-r--r--storage/innobase/row/row0uins.cc8
-rw-r--r--storage/innobase/row/row0umod.cc30
-rw-r--r--storage/innobase/row/row0undo.cc23
-rw-r--r--storage/innobase/row/row0upd.cc291
-rw-r--r--storage/innobase/row/row0vers.cc98
-rw-r--r--storage/innobase/srv/srv0conc.cc11
-rw-r--r--storage/innobase/srv/srv0srv.cc66
-rw-r--r--storage/innobase/srv/srv0start.cc51
-rw-r--r--storage/innobase/sync/sync0arr.cc8
-rw-r--r--storage/innobase/sync/sync0debug.cc29
-rw-r--r--storage/innobase/sync/sync0rw.cc56
-rw-r--r--storage/innobase/sync/sync0sync.cc4
-rw-r--r--storage/innobase/trx/trx0i_s.cc15
-rw-r--r--storage/innobase/trx/trx0purge.cc13
-rw-r--r--storage/innobase/trx/trx0rec.cc33
-rw-r--r--storage/innobase/trx/trx0roll.cc80
-rw-r--r--storage/innobase/trx/trx0rseg.cc8
-rw-r--r--storage/innobase/trx/trx0sys.cc4
-rw-r--r--storage/innobase/trx/trx0trx.cc249
-rw-r--r--storage/innobase/trx/trx0undo.cc8
-rw-r--r--storage/innobase/ut/ut0crc32.cc27
-rw-r--r--storage/innobase/ut/ut0rnd.cc7
-rw-r--r--storage/innobase/ut/ut0ut.cc18
-rw-r--r--storage/maria/ha_maria.cc2
-rw-r--r--storage/maria/ma_bitmap.c1
-rw-r--r--storage/maria/ma_check.c1
-rw-r--r--storage/maria/ma_close.c3
-rw-r--r--storage/maria/ma_create.c9
-rw-r--r--storage/maria/ma_loghandler.c10
-rw-r--r--storage/maria/ma_packrec.c49
-rw-r--r--storage/maria/ma_page.c3
-rw-r--r--storage/maria/ma_pagecrc.c3
-rw-r--r--storage/maria/ma_recovery.c21
-rw-r--r--storage/maria/ma_write.c15
-rw-r--r--storage/maria/maria_pack.c16
-rw-r--r--storage/mroonga/mrn_table.cpp2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_decimal.result2
-rw-r--r--storage/mroonga/vendor/groonga/lib/db.c3
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_tokenizers.h1
-rw-r--r--storage/mroonga/vendor/groonga/lib/tokenizers.c30
-rw-r--r--storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c11
-rwxr-xr-xstorage/myisam/ftbench/Ecompare.pl2
-rwxr-xr-xstorage/myisam/ftbench/Ecreate.pl2
-rwxr-xr-xstorage/myisam/ftbench/Ereport.pl2
-rw-r--r--storage/myisam/mi_check.c6
-rw-r--r--storage/myisam/mi_close.c4
-rw-r--r--storage/myisam/mi_create.c9
-rw-r--r--storage/myisam/mi_packrec.c49
-rw-r--r--storage/myisammrg/myrg_extra.c2
-rw-r--r--storage/myisammrg/myrg_open.c13
-rw-r--r--storage/perfschema/CMakeLists.txt15
-rw-r--r--storage/perfschema/cursor_by_account.cc13
-rw-r--r--storage/perfschema/cursor_by_account.h13
-rw-r--r--storage/perfschema/cursor_by_host.cc13
-rw-r--r--storage/perfschema/cursor_by_host.h13
-rw-r--r--storage/perfschema/cursor_by_thread.cc13
-rw-r--r--storage/perfschema/cursor_by_thread.h13
-rw-r--r--storage/perfschema/cursor_by_thread_connect_attr.cc13
-rw-r--r--storage/perfschema/cursor_by_thread_connect_attr.h13
-rw-r--r--storage/perfschema/cursor_by_user.cc13
-rw-r--r--storage/perfschema/cursor_by_user.h13
-rw-r--r--storage/perfschema/gen_pfs_lex_token.cc13
-rw-r--r--storage/perfschema/ha_perfschema.cc13
-rw-r--r--storage/perfschema/ha_perfschema.h13
-rw-r--r--storage/perfschema/pfs.cc13
-rw-r--r--storage/perfschema/pfs.h13
-rw-r--r--storage/perfschema/pfs_account.cc13
-rw-r--r--storage/perfschema/pfs_account.h13
-rw-r--r--storage/perfschema/pfs_atomic.h13
-rw-r--r--storage/perfschema/pfs_autosize.cc13
-rw-r--r--storage/perfschema/pfs_column_types.h13
-rw-r--r--storage/perfschema/pfs_column_values.cc13
-rw-r--r--storage/perfschema/pfs_column_values.h13
-rw-r--r--storage/perfschema/pfs_con_slice.cc13
-rw-r--r--storage/perfschema/pfs_con_slice.h13
-rw-r--r--storage/perfschema/pfs_defaults.cc13
-rw-r--r--storage/perfschema/pfs_defaults.h13
-rw-r--r--storage/perfschema/pfs_digest.cc13
-rw-r--r--storage/perfschema/pfs_digest.h13
-rw-r--r--storage/perfschema/pfs_engine_table.cc13
-rw-r--r--storage/perfschema/pfs_engine_table.h13
-rw-r--r--storage/perfschema/pfs_events.h13
-rw-r--r--storage/perfschema/pfs_events_stages.cc13
-rw-r--r--storage/perfschema/pfs_events_stages.h13
-rw-r--r--storage/perfschema/pfs_events_statements.cc13
-rw-r--r--storage/perfschema/pfs_events_statements.h13
-rw-r--r--storage/perfschema/pfs_events_waits.cc13
-rw-r--r--storage/perfschema/pfs_events_waits.h13
-rw-r--r--storage/perfschema/pfs_global.cc13
-rw-r--r--storage/perfschema/pfs_global.h13
-rw-r--r--storage/perfschema/pfs_host.cc13
-rw-r--r--storage/perfschema/pfs_host.h13
-rw-r--r--storage/perfschema/pfs_instr.cc13
-rw-r--r--storage/perfschema/pfs_instr.h13
-rw-r--r--storage/perfschema/pfs_instr_class.cc15
-rw-r--r--storage/perfschema/pfs_instr_class.h13
-rw-r--r--storage/perfschema/pfs_lock.h13
-rw-r--r--storage/perfschema/pfs_server.cc13
-rw-r--r--storage/perfschema/pfs_server.h13
-rw-r--r--storage/perfschema/pfs_setup_actor.cc13
-rw-r--r--storage/perfschema/pfs_setup_actor.h13
-rw-r--r--storage/perfschema/pfs_setup_object.cc13
-rw-r--r--storage/perfschema/pfs_setup_object.h13
-rw-r--r--storage/perfschema/pfs_stat.h13
-rw-r--r--storage/perfschema/pfs_timer.cc13
-rw-r--r--storage/perfschema/pfs_timer.h13
-rw-r--r--storage/perfschema/pfs_user.cc13
-rw-r--r--storage/perfschema/pfs_user.h13
-rw-r--r--storage/perfschema/pfs_visitor.cc13
-rw-r--r--storage/perfschema/pfs_visitor.h13
-rw-r--r--storage/perfschema/table_accounts.cc13
-rw-r--r--storage/perfschema/table_accounts.h13
-rw-r--r--storage/perfschema/table_all_instr.cc13
-rw-r--r--storage/perfschema/table_all_instr.h13
-rw-r--r--storage/perfschema/table_esgs_by_account_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_by_account_by_event_name.h13
-rw-r--r--storage/perfschema/table_esgs_by_host_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_by_host_by_event_name.h13
-rw-r--r--storage/perfschema/table_esgs_by_thread_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_by_thread_by_event_name.h13
-rw-r--r--storage/perfschema/table_esgs_by_user_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_by_user_by_event_name.h13
-rw-r--r--storage/perfschema/table_esgs_global_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_global_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_by_account_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_by_account_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_by_digest.cc13
-rw-r--r--storage/perfschema/table_esms_by_digest.h13
-rw-r--r--storage/perfschema/table_esms_by_host_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_by_host_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_by_thread_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_by_thread_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_by_user_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_by_user_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_global_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_global_by_event_name.h13
-rw-r--r--storage/perfschema/table_events_stages.cc13
-rw-r--r--storage/perfschema/table_events_stages.h13
-rw-r--r--storage/perfschema/table_events_statements.cc13
-rw-r--r--storage/perfschema/table_events_statements.h13
-rw-r--r--storage/perfschema/table_events_waits.cc13
-rw-r--r--storage/perfschema/table_events_waits.h13
-rw-r--r--storage/perfschema/table_events_waits_summary.cc13
-rw-r--r--storage/perfschema/table_events_waits_summary.h13
-rw-r--r--storage/perfschema/table_ews_by_account_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_by_account_by_event_name.h13
-rw-r--r--storage/perfschema/table_ews_by_host_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_by_host_by_event_name.h13
-rw-r--r--storage/perfschema/table_ews_by_thread_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_by_thread_by_event_name.h13
-rw-r--r--storage/perfschema/table_ews_by_user_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_by_user_by_event_name.h13
-rw-r--r--storage/perfschema/table_ews_global_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_global_by_event_name.h13
-rw-r--r--storage/perfschema/table_file_instances.cc13
-rw-r--r--storage/perfschema/table_file_instances.h13
-rw-r--r--storage/perfschema/table_file_summary_by_event_name.cc13
-rw-r--r--storage/perfschema/table_file_summary_by_event_name.h13
-rw-r--r--storage/perfschema/table_file_summary_by_instance.cc13
-rw-r--r--storage/perfschema/table_file_summary_by_instance.h13
-rw-r--r--storage/perfschema/table_helper.cc13
-rw-r--r--storage/perfschema/table_helper.h13
-rw-r--r--storage/perfschema/table_host_cache.cc13
-rw-r--r--storage/perfschema/table_host_cache.h13
-rw-r--r--storage/perfschema/table_hosts.cc13
-rw-r--r--storage/perfschema/table_hosts.h13
-rw-r--r--storage/perfschema/table_os_global_by_type.cc13
-rw-r--r--storage/perfschema/table_os_global_by_type.h13
-rw-r--r--storage/perfschema/table_performance_timers.cc13
-rw-r--r--storage/perfschema/table_performance_timers.h13
-rw-r--r--storage/perfschema/table_session_account_connect_attrs.cc13
-rw-r--r--storage/perfschema/table_session_account_connect_attrs.h13
-rw-r--r--storage/perfschema/table_session_connect.cc13
-rw-r--r--storage/perfschema/table_session_connect.h13
-rw-r--r--storage/perfschema/table_session_connect_attrs.cc13
-rw-r--r--storage/perfschema/table_session_connect_attrs.h13
-rw-r--r--storage/perfschema/table_setup_actors.cc13
-rw-r--r--storage/perfschema/table_setup_actors.h13
-rw-r--r--storage/perfschema/table_setup_consumers.cc13
-rw-r--r--storage/perfschema/table_setup_consumers.h13
-rw-r--r--storage/perfschema/table_setup_instruments.cc13
-rw-r--r--storage/perfschema/table_setup_instruments.h13
-rw-r--r--storage/perfschema/table_setup_objects.cc13
-rw-r--r--storage/perfschema/table_setup_objects.h13
-rw-r--r--storage/perfschema/table_setup_timers.cc13
-rw-r--r--storage/perfschema/table_setup_timers.h13
-rw-r--r--storage/perfschema/table_socket_instances.cc13
-rw-r--r--storage/perfschema/table_socket_instances.h13
-rw-r--r--storage/perfschema/table_socket_summary_by_event_name.cc13
-rw-r--r--storage/perfschema/table_socket_summary_by_event_name.h13
-rw-r--r--storage/perfschema/table_socket_summary_by_instance.cc13
-rw-r--r--storage/perfschema/table_socket_summary_by_instance.h13
-rw-r--r--storage/perfschema/table_sync_instances.cc13
-rw-r--r--storage/perfschema/table_sync_instances.h13
-rw-r--r--storage/perfschema/table_threads.cc13
-rw-r--r--storage/perfschema/table_threads.h13
-rw-r--r--storage/perfschema/table_tiws_by_index_usage.cc13
-rw-r--r--storage/perfschema/table_tiws_by_index_usage.h13
-rw-r--r--storage/perfschema/table_tiws_by_table.cc13
-rw-r--r--storage/perfschema/table_tiws_by_table.h13
-rw-r--r--storage/perfschema/table_tlws_by_table.cc13
-rw-r--r--storage/perfschema/table_tlws_by_table.h13
-rw-r--r--storage/perfschema/table_users.cc13
-rw-r--r--storage/perfschema/table_users.h13
-rw-r--r--storage/perfschema/unittest/CMakeLists.txt15
-rw-r--r--storage/perfschema/unittest/conf.txt13
-rw-r--r--storage/perfschema/unittest/pfs-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_account-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_connect_attr-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_host-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_instr-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_instr-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_instr_class-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_instr_class-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_misc-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_server_stubs.cc13
-rw-r--r--storage/perfschema/unittest/pfs_timer-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_user-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/stub_pfs_defaults.h13
-rw-r--r--storage/perfschema/unittest/stub_pfs_global.h13
-rw-r--r--storage/perfschema/unittest/stub_print_error.h13
-rw-r--r--storage/rocksdb/CMakeLists.txt12
-rw-r--r--storage/rocksdb/build_rocksdb.cmake123
-rw-r--r--storage/rocksdb/ha_rocksdb.cc8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/concurrent_alter.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/shutdown.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_compaction_readahead_size_basic.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_force_index_records_in_range_basic.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_rate_limiter_bytes_per_sec_basic.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test4
-rw-r--r--storage/rocksdb/rdb_sst_info.cc2
m---------storage/rocksdb/rocksdb0
-rw-r--r--storage/rocksdb/ut0counter.h12
-rw-r--r--storage/spider/ha_spider.cc179
-rw-r--r--storage/spider/mysql-test/spider/r/pushdown_not_like.result63
-rw-r--r--storage/spider/mysql-test/spider/t/pushdown_not_like.test138
-rw-r--r--storage/spider/spd_conn.cc22
-rw-r--r--storage/spider/spd_db_conn.cc772
-rw-r--r--storage/spider/spd_db_include.h2
-rw-r--r--storage/spider/spd_db_mysql.cc613
-rw-r--r--storage/spider/spd_db_oracle.cc492
-rw-r--r--storage/spider/spd_include.h4
-rw-r--r--storage/spider/spd_table.cc7
-rw-r--r--storage/tokudb/CMakeLists.txt5
-rw-r--r--storage/tokudb/PerconaFT/DartConfig.cmake10
-rw-r--r--storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake2
-rw-r--r--storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake29
-rw-r--r--storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc10
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-flusher.cc44
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-internal.h21
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-ops.cc56
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-ops.h4
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-recount-rows.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-test-helpers.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-verify.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/ft.cc28
-rw-r--r--storage/tokudb/PerconaFT/ft/ft.h10
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/logger.cc15
-rw-r--r--storage/tokudb/PerconaFT/ft/node.cc18
-rw-r--r--storage/tokudb/PerconaFT/ft/node.h21
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/block_table.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc12
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h1
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc10
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc14
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/make-tree.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/mempool-115.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/msnfilter.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc20
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test3884.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/rollback.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/txn.cc4
-rw-r--r--storage/tokudb/PerconaFT/ftcxx/cursor.hpp4
-rw-r--r--storage/tokudb/PerconaFT/locktree/lock_request.cc4
-rw-r--r--storage/tokudb/PerconaFT/locktree/lock_request.h1
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc2
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc2
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc2
-rw-r--r--storage/tokudb/PerconaFT/portability/portability.cc2
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc9
l---------storage/tokudb/PerconaFT/scripts/tokuvalgrind1
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test.h4
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h6
-rw-r--r--storage/tokudb/PerconaFT/src/ydb.cc56
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_db.cc8
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_db.h1
-rw-r--r--storage/tokudb/PerconaFT/tools/tokuftdump.cc2
-rw-r--r--storage/tokudb/ha_tokudb.cc4
-rw-r--r--storage/tokudb/man/CMakeLists.txt2
-rw-r--r--storage/tokudb/man/tokuft_logprint.116
-rw-r--r--storage/tokudb/man/tokuftdump.1237
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt4
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result5
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/type_ranges.result6
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result8
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/r/partition_syntax_tokudb.result74
-rw-r--r--storage/tokudb/tokudb_status.h4
-rw-r--r--storage/xtradb/CMakeLists.txt5
-rw-r--r--storage/xtradb/btr/btr0cur.cc18
-rw-r--r--storage/xtradb/buf/buf0buf.cc19
-rw-r--r--storage/xtradb/buf/buf0dblwr.cc18
-rw-r--r--storage/xtradb/buf/buf0dump.cc8
-rw-r--r--storage/xtradb/buf/buf0flu.cc9
-rw-r--r--storage/xtradb/buf/buf0lru.cc4
-rw-r--r--storage/xtradb/buf/buf0rea.cc65
-rw-r--r--storage/xtradb/dict/dict0dict.cc7
-rw-r--r--storage/xtradb/dict/dict0mem.cc66
-rw-r--r--storage/xtradb/fil/fil0crypt.cc181
-rw-r--r--storage/xtradb/fil/fil0fil.cc160
-rw-r--r--storage/xtradb/fil/fil0pagecompress.cc14
-rw-r--r--storage/xtradb/fsp/fsp0fsp.cc99
-rw-r--r--storage/xtradb/fts/fts0fts.cc87
-rw-r--r--storage/xtradb/fts/fts0que.cc19
-rw-r--r--storage/xtradb/handler/ha_innodb.cc266
-rw-r--r--storage/xtradb/handler/handler0alter.cc6
-rw-r--r--storage/xtradb/handler/i_s.cc30
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.cc71
-rw-r--r--storage/xtradb/include/buf0buf.h4
-rw-r--r--storage/xtradb/include/dict0dict.ic8
-rw-r--r--storage/xtradb/include/dict0mem.h4
-rw-r--r--storage/xtradb/include/fil0fil.h51
-rw-r--r--storage/xtradb/include/fts0ast.h15
-rw-r--r--storage/xtradb/include/fts0fts.h12
-rw-r--r--storage/xtradb/include/lock0lock.h3
-rw-r--r--storage/xtradb/include/mtr0mtr.h12
-rw-r--r--storage/xtradb/include/mtr0mtr.ic15
-rw-r--r--storage/xtradb/include/page0page.h17
-rw-r--r--storage/xtradb/include/sync0rw.h8
-rw-r--r--storage/xtradb/include/trx0trx.h14
-rw-r--r--storage/xtradb/include/univ.i4
-rw-r--r--storage/xtradb/lock/lock0lock.cc13
-rw-r--r--storage/xtradb/lock/lock0wait.cc7
-rw-r--r--storage/xtradb/mtr/mtr0mtr.cc10
-rw-r--r--storage/xtradb/os/os0file.cc1
-rw-r--r--storage/xtradb/page/page0cur.cc47
-rw-r--r--storage/xtradb/page/page0page.cc40
-rw-r--r--storage/xtradb/page/page0zip.cc37
-rw-r--r--storage/xtradb/row/row0import.cc32
-rw-r--r--storage/xtradb/row/row0ins.cc45
-rw-r--r--storage/xtradb/row/row0mysql.cc17
-rw-r--r--storage/xtradb/row/row0sel.cc32
-rw-r--r--storage/xtradb/row/row0upd.cc4
-rw-r--r--storage/xtradb/srv/srv0conc.cc11
-rw-r--r--storage/xtradb/srv/srv0srv.cc3
-rw-r--r--storage/xtradb/srv/srv0start.cc10
-rw-r--r--storage/xtradb/sync/sync0arr.cc4
-rw-r--r--storage/xtradb/trx/trx0roll.cc11
-rw-r--r--storage/xtradb/trx/trx0rseg.cc6
-rw-r--r--storage/xtradb/trx/trx0sys.cc4
-rw-r--r--storage/xtradb/trx/trx0trx.cc8
553 files changed, 13209 insertions, 13928 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 7eedba08bee..2c1656e4431 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -318,7 +318,7 @@ ENDIF(CONNECT_WITH_MONGO)
OPTION(CONNECT_WITH_REST "Compile CONNECT storage engine with REST support" ON)
IF(CONNECT_WITH_REST)
-# MESSAGE(STATUS "=====> REST support is ON")
+ MESSAGE_ONCE(CONNECT_WITH_REST "REST support is ON")
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp tabrest.h)
add_definitions(-DREST_SUPPORT)
FIND_PACKAGE(cpprestsdk QUIET)
@@ -338,8 +338,8 @@ IF(CONNECT_WITH_REST)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} restget.cpp)
add_definitions(-DREST_SOURCE)
# ENDIF()
-# ELSE(NOT cpprestsdk_FOUND)
-# MESSAGE(STATUS "=====> cpprestsdk package not found")
+ ELSE(NOT cpprestsdk_FOUND)
+# MESSAGE(STATUS "=====> cpprestsdk package not found")
ENDIF (cpprestsdk_FOUND)
ENDIF(CONNECT_WITH_REST)
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index a3dfc50562d..738e3d671a0 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -253,6 +253,7 @@ int GetConvSize(void);
TYPCONV GetTypeConv(void);
bool JsonAllPath(void);
char *GetJsonNull(void);
+int GetDefaultDepth(void);
uint GetJsonGrpSize(void);
char *GetJavaWrapper(void);
size_t GetWorkSize(void);
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index 2cb75e0adc1..2dab385a36f 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -766,7 +766,6 @@ void JDBConn::AddJars(PSTRG jpop, char sep)
/***********************************************************************/
bool JDBConn::Connect(PJPARM sop)
{
- int irc = RC_FX;
bool err = false;
jint rc;
jboolean jt = (trace(1));
diff --git a/storage/connect/mysql-test/connect/disabled.def b/storage/connect/mysql-test/connect/disabled.def
index 1de4deb0a60..a4d629fc3d1 100644
--- a/storage/connect/mysql-test/connect/disabled.def
+++ b/storage/connect/mysql-test/connect/disabled.def
@@ -20,4 +20,5 @@ mongo_c : Need MongoDB running and its C Driver installed
mongo_java_2 : Need MongoDB running and its Java Driver installed
mongo_java_3 : Need MongoDB running and its Java Driver installed
tbl_thread : Bug MDEV-9844,10179,14214 03/01/2018 OB Option THREAD removed
+grant2 : Until fixed
#vcol : Different error code on different versions
diff --git a/storage/connect/mysql-test/connect/t/ini_grant.result b/storage/connect/mysql-test/connect/t/ini_grant.result
new file mode 100644
index 00000000000..96d5e192c7d
--- /dev/null
+++ b/storage/connect/mysql-test/connect/t/ini_grant.result
@@ -0,0 +1,89 @@
+#
+# Checking FILE privileges
+#
+set sql_mode="";
+GRANT ALL PRIVILEGES ON *.* TO user@localhost;
+REVOKE FILE ON *.* FROM user@localhost;
+set sql_mode=default;
+connect user,localhost,user,,;
+connection user;
+SELECT user();
+user()
+user@localhost
+CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=INI;
+Warnings:
+Warning 1105 No file name. Table will use t1.ini
+INSERT INTO t1 VALUES ('sec1','val1');
+SELECT * FROM t1;
+sec val
+sec1 val1
+UPDATE t1 SET val='val11';
+SELECT * FROM t1;
+sec val
+sec1 val11
+DELETE FROM t1;
+SELECT * FROM t1;
+sec val
+INSERT INTO t1 VALUES('sec2','val2');
+TRUNCATE TABLE t1;
+SELECT * FROM t1;
+sec val
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM v1;
+sec val
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.EXT';
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+connection default;
+SELECT user();
+user()
+root@localhost
+CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.EXT';
+INSERT INTO t1 VALUES ('sec1','val1');
+connection user;
+SELECT user();
+user()
+user@localhost
+INSERT INTO t1 VALUES ('sec2','val2');
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+SELECT * FROM t1;
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+UPDATE t1 SET val='val11';
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+DELETE FROM t1;
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+TRUNCATE TABLE t1;
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+ALTER TABLE t1 READONLY=1;
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+DROP TABLE t1;
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+CREATE VIEW v1 AS SELECT * FROM t1;
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+# Testing a VIEW created with FILE privileges but accessed with no FILE
+connection default;
+SELECT user();
+user()
+root@localhost
+CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
+connection user;
+SELECT user();
+user()
+user@localhost
+SELECT * FROM v1;
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+INSERT INTO v1 VALUES ('sec3','val3');
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+UPDATE v1 SET val='val11';
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+DELETE FROM v1;
+ERROR 42000: Access denied; you need (at least one of) the FILE privilege(s) for this operation
+disconnect user;
+connection default;
+DROP VIEW v1;
+DROP TABLE t1;
+DROP USER user@localhost;
+#
+# Checking FILE privileges: done
+#
diff --git a/storage/connect/tabrest.h b/storage/connect/tabrest.h
index 9cf2d10a6b8..f08ac7984c9 100644
--- a/storage/connect/tabrest.h
+++ b/storage/connect/tabrest.h
@@ -5,10 +5,7 @@
/***********************************************************************/
#pragma once
-#if defined(__WIN__)
-static PCSZ slash = "\\";
-#else // !__WIN__
-static PCSZ slash = "/";
+#ifndef __WIN__
#define stricmp strcasecmp
#endif // !__WIN__
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index bb0b5c82f06..3b0e755bc91 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -723,8 +723,10 @@ void btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
{
ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table));
#ifdef BTR_CUR_HASH_ADAPT
- ut_ad(!block->index || !blob);
- ut_ad(!block->index || page_is_leaf(block->frame));
+ if (block->index && !block->index->freed()) {
+ ut_ad(!blob);
+ ut_ad(page_is_leaf(block->frame));
+ }
#endif
ut_ad(index->space == block->page.id.space());
/* The root page is freed by btr_free_root(). */
@@ -751,7 +753,7 @@ void btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
fseg_free_page(seg_header,
block->page.id.space(),
block->page.id.page_no(),
- block->index != NULL, mtr);
+ mtr);
/* The page was marked free in the allocation bitmap, but it
should remain exclusively latched until mtr_t::commit() or until it
@@ -777,7 +779,7 @@ btr_node_ptr_set_child_page_no(
rec_t* rec, /*!< in: node pointer record */
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint page_no,/*!< in: child node address */
mtr_t* mtr) /*!< in: mtr */
{
@@ -812,7 +814,7 @@ btr_node_ptr_get_child(
/*===================*/
const rec_t* node_ptr,/*!< in: node pointer */
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(rec_offs_validate(node_ptr, index, offsets));
@@ -830,10 +832,10 @@ Returns the upper level node pointer to a page. It is assumed that mtr holds
an sx-latch on the tree.
@return rec_get_offsets() of the node pointer record */
static
-ulint*
+rec_offs*
btr_page_get_father_node_ptr_func(
/*==============================*/
- ulint* offsets,/*!< in: work area for the return value */
+ rec_offs* offsets,/*!< in: work area for the return value */
mem_heap_t* heap, /*!< in: memory heap to use */
btr_cur_t* cursor, /*!< in: cursor pointing to user record,
out: cursor on node pointer record,
@@ -876,7 +878,7 @@ btr_page_get_father_node_ptr_func(
err = btr_cur_search_to_nth_level(
index, level + 1, tuple,
PAGE_CUR_LE, latch_mode, cursor, 0,
- file, line, mtr);
+ file, line, mtr, 0);
if (err != DB_SUCCESS) {
ib::warn() << " Error code: " << err
@@ -937,10 +939,10 @@ Returns the upper level node pointer to a page. It is assumed that mtr holds
an x-latch on the tree.
@return rec_get_offsets() of the node pointer record */
static
-ulint*
+rec_offs*
btr_page_get_father_block(
/*======================*/
- ulint* offsets,/*!< in: work area for the return value */
+ rec_offs* offsets,/*!< in: work area for the return value */
mem_heap_t* heap, /*!< in: memory heap to use */
dict_index_t* index, /*!< in: b-tree index */
buf_block_t* block, /*!< in: child page in the index */
@@ -1005,7 +1007,7 @@ static void btr_free_root(buf_block_t* block, mtr_t* mtr, bool invalidate)
BTR_FREED_INDEX_ID, mtr);
}
- while (!fseg_free_step(header, true, mtr)) {
+ while (!fseg_free_step(header, mtr)) {
/* Free the entire segment in small steps. */
}
}
@@ -1084,8 +1086,7 @@ btr_create(
if (type & DICT_IBUF) {
/* Allocate first the ibuf header page */
buf_block_t* ibuf_hdr_block = fseg_create(
- space, 0,
- IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
+ space, IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
if (ibuf_hdr_block == NULL) {
return(FIL_NULL);
@@ -1116,7 +1117,7 @@ btr_create(
flst_init(block->frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
mtr);
} else {
- block = fseg_create(space, 0,
+ block = fseg_create(space,
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
if (block == NULL) {
@@ -1125,8 +1126,9 @@ btr_create(
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
- if (!fseg_create(space, block->page.id.page_no(),
- PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
+ if (!fseg_create(space,
+ PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr,
+ block)) {
/* Not enough space for new segment, free root
segment before return. */
btr_free_root(block, mtr,
@@ -1254,7 +1256,7 @@ leaf_loop:
fsp0fsp. */
finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
- true, &mtr);
+ &mtr);
mtr_commit(&mtr);
if (!finished) {
@@ -1274,7 +1276,7 @@ top_loop:
#endif /* UNIV_BTR_DEBUG */
finished = fseg_free_step_not_header(
- root + PAGE_HEADER + PAGE_BTR_SEG_TOP, true, &mtr);
+ root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
mtr_commit(&mtr);
if (!finished) {
@@ -1814,7 +1816,7 @@ btr_root_raise_and_insert(
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
- ulint** offsets,/*!< out: offsets on inserted record */
+ rec_offs** offsets,/*!< out: offsets on inserted record */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
@@ -2125,7 +2127,7 @@ btr_page_get_split_rec(
rec_t* next_rec;
ulint n;
mem_heap_t* heap;
- ulint* offsets;
+ rec_offs* offsets;
page = btr_cur_get_page(cursor);
@@ -2231,7 +2233,7 @@ btr_page_insert_fits(
const rec_t* split_rec,/*!< in: suggestion for first record
on upper half-page, or NULL if
tuple to be inserted should be first */
- ulint** offsets,/*!< in: rec_get_offsets(
+ rec_offs** offsets,/*!< in: rec_get_offsets(
split_rec, cursor->index); out: garbage */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
@@ -2331,8 +2333,8 @@ btr_insert_on_non_leaf_level_func(
dberr_t err;
rec_t* rec;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
rtr_info_t rtr_info;
@@ -2342,7 +2344,7 @@ btr_insert_on_non_leaf_level_func(
dberr_t err = btr_cur_search_to_nth_level(
index, level, tuple, PAGE_CUR_LE,
BTR_CONT_MODIFY_TREE,
- &cursor, 0, file, line, mtr);
+ &cursor, 0, file, line, mtr, 0);
if (err != DB_SUCCESS) {
ib::warn() << " Error code: " << err
@@ -2363,7 +2365,7 @@ btr_insert_on_non_leaf_level_func(
btr_cur_search_to_nth_level(index, level, tuple,
PAGE_CUR_RTREE_INSERT,
BTR_CONT_MODIFY_TREE,
- &cursor, 0, file, line, mtr);
+ &cursor, 0, file, line, mtr, 0);
}
ut_ad(cursor.flag == BTR_CUR_BINARY);
@@ -2441,7 +2443,7 @@ btr_attach_half_pages(
if (direction == FSP_DOWN) {
btr_cur_t cursor;
- ulint* offsets;
+ rec_offs* offsets;
lower_page = buf_block_get_frame(new_block);
lower_page_no = new_block->page.id.page_no();
@@ -2564,7 +2566,7 @@ btr_page_tuple_smaller(
/*===================*/
btr_cur_t* cursor, /*!< in: b-tree cursor */
const dtuple_t* tuple, /*!< in: tuple to consider */
- ulint** offsets,/*!< in/out: temporary storage */
+ rec_offs** offsets,/*!< in/out: temporary storage */
ulint n_uniq, /*!< in: number of unique fields
in the index page records */
mem_heap_t** heap) /*!< in/out: heap for offsets */
@@ -2604,7 +2606,7 @@ rec_t*
btr_insert_into_right_sibling(
ulint flags,
btr_cur_t* cursor,
- ulint** offsets,
+ rec_offs** offsets,
mem_heap_t* heap,
const dtuple_t* tuple,
ulint n_ext,
@@ -2741,7 +2743,7 @@ btr_page_split_and_insert(
btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
- ulint** offsets,/*!< out: offsets on inserted record */
+ rec_offs** offsets,/*!< out: offsets on inserted record */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
@@ -3302,7 +3304,7 @@ btr_lift_page_up(
{
btr_cur_t cursor;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
mem_heap_t* heap = mem_heap_create(
sizeof(*offsets)
* (REC_OFFS_HEADER_SIZE + 1 + 1 + index->n_fields));
@@ -3487,7 +3489,7 @@ btr_compress(
page_t* page;
btr_cur_t father_cursor;
mem_heap_t* heap;
- ulint* offsets;
+ rec_offs* offsets;
ulint nth_rec = 0; /* remove bogus warning */
bool mbr_changed = false;
#ifdef UNIV_DEBUG
@@ -3631,7 +3633,7 @@ retry:
if (is_left) {
btr_cur_t cursor2;
rtr_mbr_t new_mbr;
- ulint* offsets2 = NULL;
+ rec_offs* offsets2 = NULL;
/* For rtree, we need to update father's mbr. */
if (dict_index_is_spatial(index)) {
@@ -3829,7 +3831,7 @@ retry:
/* For rtree, we need to update father's mbr. */
if (dict_index_is_spatial(index)) {
- ulint* offsets2;
+ rec_offs* offsets2;
ulint rec_info;
offsets2 = rec_get_offsets(
@@ -4276,7 +4278,7 @@ btr_print_recursive(
ulint width, /*!< in: print this many entries from start
and end */
mem_heap_t** heap, /*!< in/out: heap for rec_get_offsets() */
- ulint** offsets,/*!< in/out: buffer for rec_get_offsets() */
+ rec_offs** offsets,/*!< in/out: buffer for rec_get_offsets() */
mtr_t* mtr) /*!< in: mtr */
{
const page_t* page = buf_block_get_frame(block);
@@ -4340,8 +4342,8 @@ btr_print_index(
mtr_t mtr;
buf_block_t* root;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
fputs("--------------------------\n"
@@ -4375,7 +4377,7 @@ btr_check_node_ptr(
{
mem_heap_t* heap;
dtuple_t* tuple;
- ulint* offsets;
+ rec_offs* offsets;
btr_cur_t cursor;
page_t* page = buf_block_get_frame(block);
@@ -4457,8 +4459,8 @@ btr_index_rec_validate(
ulint i;
const page_t* page;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
page = page_align(rec);
@@ -4691,8 +4693,8 @@ btr_validate_level(
bool ret = true;
mtr_t mtr;
mem_heap_t* heap = mem_heap_create(256);
- ulint* offsets = NULL;
- ulint* offsets2= NULL;
+ rec_offs* offsets = NULL;
+ rec_offs* offsets2= NULL;
#ifdef UNIV_ZIP_DEBUG
page_zip_des_t* page_zip;
#endif /* UNIV_ZIP_DEBUG */
@@ -5026,11 +5028,13 @@ loop:
mtr_release_block_at_savepoint(
&mtr, savepoint, right_block);
- btr_block_get(
- page_id_t(index->space,
- parent_right_page_no),
- table_page_size,
- RW_SX_LATCH, index, &mtr);
+ if (parent_right_page_no != FIL_NULL) {
+ btr_block_get(
+ page_id_t(index->space,
+ parent_right_page_no),
+ table_page_size,
+ RW_SX_LATCH, index, &mtr);
+ }
right_block = btr_block_get(
page_id_t(index->space,
diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index 262709bc679..96ff81c9fab 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2019, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -29,6 +29,7 @@ Created 03/11/2014 Shaohua Wang
#include "btr0cur.h"
#include "btr0pcur.h"
#include "ibuf0ibuf.h"
+#include "page0page.h"
#include "trx0trx.h"
/** Innodb B-tree index fill factor for bulk load. */
@@ -143,7 +144,6 @@ PageBulk::init()
}
m_block = new_block;
- m_block->skip_flush_check = true;
m_page = new_page;
m_page_zip = new_page_zip;
m_page_no = new_page_no;
@@ -163,7 +163,9 @@ PageBulk::init()
UNIV_PAGE_SIZE - dict_index_zip_pad_optimal_page_size(m_index);
m_heap_top = page_header_get_ptr(new_page, PAGE_HEAP_TOP);
m_rec_no = page_header_get_field(new_page, PAGE_N_RECS);
-
+ ut_ad(page_header_get_field(m_page, PAGE_DIRECTION)
+ == PAGE_NO_DIRECTION);
+ page_header_set_field(m_page, NULL, PAGE_DIRECTION, 0);
ut_d(m_total_data = 0);
/* See page_copy_rec_list_end_to_created_page() */
ut_d(page_header_set_field(m_page, NULL, PAGE_HEAP_TOP,
@@ -178,7 +180,7 @@ PageBulk::init()
void
PageBulk::insert(
const rec_t* rec,
- ulint* offsets)
+ rec_offs* offsets)
{
ulint rec_size;
@@ -188,9 +190,9 @@ PageBulk::insert(
#ifdef UNIV_DEBUG
/* Check whether records are in order. */
- if (!page_rec_is_infimum(m_cur_rec)) {
+ if (!page_rec_is_infimum_low(page_offset(m_cur_rec))) {
rec_t* old_rec = m_cur_rec;
- ulint* old_offsets = rec_get_offsets(
+ rec_offs* old_offsets = rec_get_offsets(
old_rec, m_index, NULL, page_rec_is_leaf(old_rec),
ULINT_UNDEFINED, &m_heap);
@@ -206,18 +208,21 @@ PageBulk::insert(
rec_offs_make_valid(insert_rec, m_index, offsets);
/* 2. Insert the record in the linked list. */
- rec_t* next_rec = page_rec_get_next(m_cur_rec);
-
- page_rec_set_next(insert_rec, next_rec);
- page_rec_set_next(m_cur_rec, insert_rec);
-
/* 3. Set the n_owned field in the inserted record to zero,
and set the heap_no field. */
if (m_is_comp) {
+ ulint next_offs = rec_get_next_offs(m_cur_rec, TRUE);
+ rec_set_next_offs_new(insert_rec, next_offs);
+ rec_set_next_offs_new(m_cur_rec, page_offset(insert_rec));
+
rec_set_n_owned_new(insert_rec, NULL, 0);
rec_set_heap_no_new(insert_rec,
PAGE_HEAP_NO_USER_LOW + m_rec_no);
} else {
+ ulint next_offs = rec_get_next_offs(m_cur_rec, FALSE);
+ rec_set_next_offs_old(insert_rec, next_offs);
+ rec_set_next_offs_old(m_cur_rec, page_offset(insert_rec));
+
rec_set_n_owned_old(insert_rec, 0);
rec_set_heap_no_old(insert_rec,
PAGE_HEAP_NO_USER_LOW + m_rec_no);
@@ -245,17 +250,54 @@ PageBulk::insert(
m_cur_rec = insert_rec;
}
+inline bool PageBulk::needs_finish() const
+{
+ ut_ad(page_align(m_cur_rec) == m_block->frame);
+ ut_ad(m_page == m_block->frame);
+ ulint n_heap= page_header_get_field(m_page, PAGE_N_HEAP);
+ if (!n_heap || !page_header_get_field(m_page, PAGE_DIRECTION))
+ return true;
+ ulint heap_no;
+ if (n_heap & 0x8000)
+ {
+ n_heap&= 0x7fff;
+ heap_no= rec_get_heap_no_new(m_cur_rec);
+ if (heap_no == PAGE_HEAP_NO_INFIMUM &&
+ page_header_get_field(m_page, PAGE_HEAP_TOP) == PAGE_NEW_SUPREMUM_END)
+ return false;
+ }
+ else
+ {
+ heap_no= rec_get_heap_no_old(m_cur_rec);
+ if (heap_no == PAGE_HEAP_NO_INFIMUM &&
+ page_header_get_field(m_page, PAGE_HEAP_TOP) == PAGE_OLD_SUPREMUM_END)
+ return false;
+ }
+ return heap_no != n_heap - 1;
+}
+
/** Mark end of insertion to the page. Scan all records to set page dirs,
and set page header members.
Note: we refer to page_copy_rec_list_end_to_created_page. */
void
PageBulk::finish()
{
- ut_ad(m_rec_no > 0);
+ ut_ad(!dict_index_is_spatial(m_index));
+
+ if (!needs_finish()) {
+ return;
+ }
+
ut_ad(m_total_data + page_dir_calc_reserved_space(m_rec_no)
<= page_get_free_space_of_empty(m_is_comp));
+#ifdef UNIV_DEBUG
/* See page_copy_rec_list_end_to_created_page() */
- ut_d(page_dir_set_n_slots(m_page, NULL, srv_page_size / 2));
+ if (m_rec_no) {
+ page_dir_set_n_slots(m_page, NULL, srv_page_size / 2);
+ }
+ mach_write_to_2(PAGE_HEADER + PAGE_HEAP_TOP + m_page,
+ ulint(m_heap_top - m_page));
+#endif
ulint count = 0;
ulint n_recs = 0;
@@ -264,8 +306,7 @@ PageBulk::finish()
page_dir_slot_t* slot = NULL;
/* Set owner & dir. */
- do {
-
+ while (!page_rec_is_supremum(insert_rec)) {
count++;
n_recs++;
@@ -282,7 +323,7 @@ PageBulk::finish()
}
insert_rec = page_rec_get_next(insert_rec);
- } while (!page_rec_is_supremum(insert_rec));
+ }
if (slot_index > 0
&& (count + 1 + (PAGE_DIR_SLOT_MAX_N_OWNED + 1) / 2
@@ -305,9 +346,10 @@ PageBulk::finish()
page_dir_slot_set_rec(slot, page_get_supremum_rec(m_page));
page_dir_slot_set_n_owned(slot, NULL, count + 1);
- ut_ad(!dict_index_is_spatial(m_index));
-
- if (!m_flush_observer && !m_page_zip) {
+ if (!m_rec_no) {
+ page_header_set_field(m_page, NULL, PAGE_DIRECTION,
+ PAGE_NO_DIRECTION);
+ } else if (!m_flush_observer && !m_page_zip) {
mlog_write_ulint(PAGE_HEADER + PAGE_N_DIR_SLOTS + m_page,
2 + slot_index, MLOG_2BYTES, &m_mtr);
mlog_write_ulint(PAGE_HEADER + PAGE_HEAP_TOP + m_page,
@@ -344,26 +386,18 @@ PageBulk::finish()
mach_write_to_2(PAGE_HEADER + PAGE_N_DIRECTION + m_page, 0);
}
- m_block->skip_flush_check = false;
+ ut_ad(!needs_finish());
+ ut_ad(page_validate(m_page, m_index));
}
/** Commit inserts done to the page
@param[in] success Flag whether all inserts succeed. */
-void
-PageBulk::commit(
- bool success)
+void PageBulk::commit(bool success)
{
- if (success) {
- ut_ad(page_validate(m_page, m_index));
-
- /* Set no free space left and no buffered changes in ibuf. */
- if (!dict_index_is_clust(m_index) && page_is_leaf(m_page)) {
- ibuf_set_bitmap_for_bulk_load(
- m_block, innobase_fill_factor == 100);
- }
- }
-
- m_mtr.commit();
+ finish();
+ if (success && !dict_index_is_clust(m_index) && page_is_leaf(m_page))
+ ibuf_set_bitmap_for_bulk_load(m_block, innobase_fill_factor == 100);
+ m_mtr.commit();
}
/** Compress a page of compressed table
@@ -402,7 +436,7 @@ rec_t*
PageBulk::getSplitRec()
{
rec_t* rec;
- ulint* offsets;
+ rec_offs* offsets;
ulint total_used_size;
ulint total_recs_size;
ulint n_recs;
@@ -448,7 +482,7 @@ PageBulk::copyIn(
{
rec_t* rec = split_rec;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
ut_ad(m_rec_no == 0);
ut_ad(page_rec_is_user_rec(rec));
@@ -494,7 +528,7 @@ PageBulk::copyOut(
ut_ad(n > 0);
/* Set last record's next in page */
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
rec = page_rec_get_prev(split_rec);
offsets = rec_get_offsets(rec, m_index, offsets,
page_rec_is_leaf(split_rec),
@@ -604,9 +638,11 @@ the blob data is logged first, then the record is logged in bulk mode.
dberr_t
PageBulk::storeExt(
const big_rec_t* big_rec,
- ulint* offsets)
+ rec_offs* offsets)
{
- /* Note: not all fileds are initialized in btr_pcur. */
+ finish();
+
+ /* Note: not all fields are initialized in btr_pcur. */
btr_pcur_t btr_pcur;
btr_pcur.pos_state = BTR_PCUR_IS_POSITIONED;
btr_pcur.latch_mode = BTR_MODIFY_LEAF;
@@ -635,7 +671,7 @@ Note: log_free_check requires holding no lock/latch in current thread. */
void
PageBulk::release()
{
- ut_ad(!dict_index_is_spatial(m_index));
+ finish();
/* We fix the block because we will re-pin it soon. */
buf_block_buf_fix_inc(m_block, __FILE__, __LINE__);
@@ -693,12 +729,11 @@ BtrBulk::pageSplit(
{
ut_ad(page_bulk->getPageZip() != NULL);
- /* 1. Check if we have only one user record on the page. */
if (page_bulk->getRecNo() <= 1) {
return(DB_TOO_BIG_RECORD);
}
- /* 2. create a new page. */
+ /* Initialize a new page */
PageBulk new_page_bulk(m_index, m_trx->id, FIL_NULL,
page_bulk->getLevel(), m_flush_observer);
dberr_t err = new_page_bulk.init();
@@ -706,19 +741,18 @@ BtrBulk::pageSplit(
return(err);
}
- /* 3. copy the upper half to new page. */
+ /* Copy the upper half to the new page. */
rec_t* split_rec = page_bulk->getSplitRec();
new_page_bulk.copyIn(split_rec);
page_bulk->copyOut(split_rec);
- /* 4. commit the splitted page. */
+ /* Commit the pages after split. */
err = pageCommit(page_bulk, &new_page_bulk, true);
if (err != DB_SUCCESS) {
pageAbort(&new_page_bulk);
return(err);
}
- /* 5. commit the new page. */
err = pageCommit(&new_page_bulk, next_page_bulk, true);
if (err != DB_SUCCESS) {
pageAbort(&new_page_bulk);
@@ -864,7 +898,7 @@ BtrBulk::insert(
ulint rec_size = rec_get_converted_size(m_index, tuple, n_ext);
big_rec_t* big_rec = NULL;
rec_t* rec = NULL;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
if (page_bulk->needExt(tuple, rec_size)) {
/* The record is so big that we have to store some fields
@@ -944,11 +978,9 @@ BtrBulk::insert(
ut_ad(page_bulk->getLevel() == 0);
ut_ad(page_bulk == m_page_bulks.at(0));
- /* Release all latched but leaf node. */
+ /* Release all pages above the leaf level */
for (ulint level = 1; level <= m_root_level; level++) {
- PageBulk* page_bulk = m_page_bulks.at(level);
-
- page_bulk->release();
+ m_page_bulks.at(level)->release();
}
err = page_bulk->storeExt(big_rec, offsets);
@@ -1037,6 +1069,7 @@ BtrBulk::finish(dberr_t err)
return(err);
}
root_page_bulk.copyIn(first_rec);
+ root_page_bulk.finish();
/* Remove last page. */
btr_page_free(m_index, last_block, &mtr);
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 51552dcc513..770c6d73585 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -1,9 +1,9 @@
/*****************************************************************************
-Copyright (c) 1994, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -162,7 +162,7 @@ btr_cur_unmark_extern_fields(
part will be updated, or NULL */
rec_t* rec, /*!< in/out: record in a clustered index */
dict_index_t* index, /*!< in: index of the page */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
mtr_t* mtr); /*!< in: mtr, or NULL if not logged */
/*******************************************************************//**
Adds path information to the cursor for the current page, for which
@@ -187,7 +187,7 @@ btr_rec_free_updated_extern_fields(
rec_t* rec, /*!< in: record */
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
const upd_t* update, /*!< in: update vector */
bool rollback,/*!< in: performing rollback? */
mtr_t* mtr); /*!< in: mini-transaction handle which contains
@@ -201,7 +201,7 @@ btr_rec_free_externally_stored_fields(
dict_index_t* index, /*!< in: index of the data, the index
tree MUST be X-latched */
rec_t* rec, /*!< in: record */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
bool rollback,/*!< in: performing rollback? */
@@ -415,6 +415,7 @@ btr_cur_optimistic_latch_leaves(
{
ulint mode;
ulint left_page_no;
+ ulint curr_page_no;
switch (*latch_mode) {
case BTR_SEARCH_LEAF:
@@ -441,6 +442,8 @@ btr_cur_optimistic_latch_leaves(
goto unpin_failed;
}
+
+ curr_page_no = block->page.id.page_no();
left_page_no = btr_page_get_prev(
buf_block_get_frame(block));
rw_lock_s_unlock(&block->lock);
@@ -449,11 +452,26 @@ btr_cur_optimistic_latch_leaves(
const page_id_t page_id(
dict_index_get_space(cursor->index),
left_page_no);
+ dberr_t err = DB_SUCCESS;
- cursor->left_block = btr_block_get(
+ cursor->left_block = buf_page_get_gen(
page_id,
dict_table_page_size(cursor->index->table),
- mode, cursor->index, mtr);
+ mode, NULL, BUF_GET_POSSIBLY_FREED,
+ __FILE__, __LINE__, mtr, &err);
+
+ if (err == DB_DECRYPTION_FAILED) {
+ cursor->index->table->file_unreadable = true;
+ }
+
+ if (btr_page_get_next(buf_block_get_frame(
+ cursor->left_block))
+ != curr_page_no) {
+ /* release the left block */
+ btr_leaf_page_release(
+ cursor->left_block, mode, mtr);
+ goto unpin_failed;
+ }
} else {
cursor->left_block = NULL;
}
@@ -583,46 +601,66 @@ btr_cur_will_modify_tree(
const ulint n_recs = page_get_n_recs(page);
if (lock_intention <= BTR_INTENTION_BOTH) {
- ulint margin;
+ compile_time_assert(BTR_INTENTION_DELETE < BTR_INTENTION_BOTH);
+ compile_time_assert(BTR_INTENTION_BOTH < BTR_INTENTION_INSERT);
- /* check delete will cause. (BTR_INTENTION_BOTH
- or BTR_INTENTION_DELETE) */
- /* first, 2nd, 2nd-last and last records are 4 records */
- if (n_recs < 5) {
- return(true);
+ if (!page_has_siblings(page)) {
+ return true;
}
- /* is first, 2nd or last record */
- if (page_rec_is_first(rec, page)
- || (page_has_next(page)
- && (page_rec_is_last(rec, page)
- || page_rec_is_second_last(rec, page)))
- || (page_has_prev(page)
- && page_rec_is_second(rec, page))) {
- return(true);
- }
+ ulint margin = rec_size;
if (lock_intention == BTR_INTENTION_BOTH) {
+ ulint level = btr_page_get_level(page, mtr);
+
+ /* This value is the worst expectation for the node_ptr
+ records to be deleted from this page. It is used to
+ expect whether the cursor position can be the left_most
+ record in this page or not. */
+ ulint max_nodes_deleted = 0;
+
+ /* By modifying tree operations from the under of this
+ level, logically (2 ^ (level - 1)) opportunities to
+ deleting records in maximum even unreally rare case. */
+ if (level > 7) {
+ /* TODO: adjust this practical limit. */
+ max_nodes_deleted = 64;
+ } else if (level > 0) {
+ max_nodes_deleted = (ulint)1 << (level - 1);
+ }
+ /* check delete will cause. (BTR_INTENTION_BOTH
+ or BTR_INTENTION_DELETE) */
+ if (n_recs <= max_nodes_deleted * 2
+ || page_rec_is_first(rec, page)) {
+ /* The cursor record can be the left most record
+ in this page. */
+ return true;
+ }
+
+ if (page_has_prev(page)
+ && page_rec_distance_is_at_most(
+ page_get_infimum_rec(page), rec,
+ max_nodes_deleted)) {
+ return true;
+ }
+
+ if (page_has_next(page)
+ && page_rec_distance_is_at_most(
+ rec, page_get_supremum_rec(page),
+ max_nodes_deleted)) {
+ return true;
+ }
+
/* Delete at leftmost record in a page causes delete
& insert at its parent page. After that, the delete
might cause btr_compress() and delete record at its
- parent page. Thus we should consider max 2 deletes. */
-
- margin = rec_size * 2;
- } else {
- ut_ad(lock_intention == BTR_INTENTION_DELETE);
-
- margin = rec_size;
+ parent page. Thus we should consider max deletes. */
+ margin *= max_nodes_deleted;
}
- /* NOTE: call mach_read_from_4() directly to avoid assertion
- failure. It is safe because we already have SX latch of the
- index tree */
+
+ /* Safe because we already have SX latch of the index tree */
if (page_get_data_size(page)
- < margin + BTR_CUR_PAGE_COMPRESS_LIMIT(index)
- || (mach_read_from_4(page + FIL_PAGE_NEXT)
- == FIL_NULL
- && mach_read_from_4(page + FIL_PAGE_PREV)
- == FIL_NULL)) {
+ < margin + BTR_CUR_PAGE_COMPRESS_LIMIT(index)) {
return(true);
}
}
@@ -844,8 +882,7 @@ search tuple should be performed in the B-tree. InnoDB does an insert
immediately after the cursor. Thus, the cursor may end up on a user record,
or on a page infimum record. */
dberr_t
-btr_cur_search_to_nth_level(
-/*========================*/
+btr_cur_search_to_nth_level_func(
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: the tree level of search */
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
@@ -867,10 +904,12 @@ btr_cur_search_to_nth_level(
to protect the record! */
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
+#ifdef BTR_CUR_HASH_ADAPT
ulint has_search_latch,
/*!< in: info on the latch mode the
caller currently has on search system:
RW_S_LATCH, or 0 */
+#endif /* BTR_CUR_HASH_ADAPT */
const char* file, /*!< in: file name */
unsigned line, /*!< in: line where called */
mtr_t* mtr, /*!< in: mtr */
@@ -923,10 +962,10 @@ btr_cur_search_to_nth_level(
btr_search_t* info;
#endif /* BTR_CUR_ADAPT */
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
- ulint offsets2_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets2 = offsets2_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
+ rec_offs offsets2_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets2 = offsets2_;
rec_offs_init(offsets_);
rec_offs_init(offsets2_);
/* Currently, PAGE_CUR_LE is the only search mode used for searches
@@ -940,10 +979,12 @@ btr_cur_search_to_nth_level(
ut_ad(!(index->type & DICT_FTS));
ut_ad(index->page != FIL_NULL);
- UNIV_MEM_INVALID(&cursor->up_match, sizeof cursor->up_match);
- UNIV_MEM_INVALID(&cursor->up_bytes, sizeof cursor->up_bytes);
- UNIV_MEM_INVALID(&cursor->low_match, sizeof cursor->low_match);
- UNIV_MEM_INVALID(&cursor->low_bytes, sizeof cursor->low_bytes);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&cursor->up_match, sizeof cursor->up_match);
+ MEM_UNDEFINED(&cursor->up_bytes, sizeof cursor->up_bytes);
+ MEM_UNDEFINED(&cursor->low_match, sizeof cursor->low_match);
+ MEM_UNDEFINED(&cursor->low_bytes, sizeof cursor->low_bytes);
+#endif /* HAVE_valgrind_or_MSAN */
#ifdef UNIV_DEBUG
cursor->up_match = ULINT_UNDEFINED;
cursor->low_match = ULINT_UNDEFINED;
@@ -1033,6 +1074,7 @@ btr_cur_search_to_nth_level(
}
#ifdef BTR_CUR_HASH_ADAPT
+ rw_lock_t* const search_latch = btr_get_search_latch(index);
# ifdef UNIV_SEARCH_PERF_STAT
info->n_searches++;
@@ -1053,8 +1095,7 @@ btr_cur_search_to_nth_level(
will have to check it again. */
&& btr_search_enabled
&& !modify_external
- && rw_lock_get_writer(btr_get_search_latch(index))
- == RW_LOCK_NOT_LOCKED
+ && rw_lock_get_writer(search_latch) == RW_LOCK_NOT_LOCKED
&& btr_search_guess_on_hash(index, info, tuple, mode,
latch_mode, cursor,
has_search_latch, mtr)) {
@@ -1078,10 +1119,12 @@ btr_cur_search_to_nth_level(
/* If the hash search did not succeed, do binary search down the
tree */
+#ifdef BTR_CUR_HASH_ADAPT
if (has_search_latch) {
/* Release possible search latch to obey latching order */
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(search_latch);
}
+#endif /* BTR_CUR_HASH_ADAPT */
/* Store the position of the tree latch we push to mtr so that we
know how to release it when we have latched leaf node(s) */
@@ -1455,10 +1498,9 @@ retry_page_get:
node_seq_t root_seq_no;
root_seq_no = page_get_ssn_id(page);
-
- mutex_enter(&(index->rtr_ssn.mutex));
- index->rtr_ssn.seq_no = root_seq_no + 1;
- mutex_exit(&(index->rtr_ssn.mutex));
+ my_atomic_store32_explicit(
+ &index->rtr_ssn, root_seq_no + 1,
+ MY_MEMORY_ORDER_RELAXED);
}
/* Save the MBR */
@@ -1806,9 +1848,9 @@ need_opposite_intention:
offsets2 = rec_get_offsets(
first_rec, index, offsets2,
false, ULINT_UNDEFINED, &heap);
- cmp_rec_rec_with_match(node_ptr, first_rec,
- offsets, offsets2, index, FALSE,
- &matched_fields);
+ cmp_rec_rec(node_ptr, first_rec,
+ offsets, offsets2, index, false,
+ &matched_fields);
if (matched_fields
>= rec_offs_n_fields(offsets) - 1) {
@@ -1824,10 +1866,10 @@ need_opposite_intention:
offsets2 = rec_get_offsets(
last_rec, index, offsets2,
false, ULINT_UNDEFINED, &heap);
- cmp_rec_rec_with_match(
+ cmp_rec_rec(
node_ptr, last_rec,
offsets, offsets2, index,
- FALSE, &matched_fields);
+ false, &matched_fields);
if (matched_fields
>= rec_offs_n_fields(offsets) - 1) {
detected_same_key_root = true;
@@ -2136,9 +2178,11 @@ func_exit:
ut_free(prev_tree_savepoints);
}
+#ifdef BTR_CUR_HASH_ADAPT
if (has_search_latch) {
- btr_search_s_lock(index);
+ rw_lock_s_lock(search_latch);
}
+#endif /* BTR_CUR_HASH_ADAPT */
if (mbr_adj) {
/* remember that we will need to adjust parent MBR */
@@ -2178,8 +2222,8 @@ btr_cur_open_at_index_side_func(
ulint n_blocks = 0;
ulint n_releases = 0;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
dberr_t err = DB_SUCCESS;
rec_offs_init(offsets_);
@@ -2548,8 +2592,8 @@ btr_cur_open_at_rnd_pos_func(
ulint n_blocks = 0;
ulint n_releases = 0;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(!dict_index_is_spatial(index));
@@ -2839,7 +2883,7 @@ btr_cur_insert_if_possible(
cursor stays valid */
const dtuple_t* tuple, /*!< in: tuple to insert; the size info need not
have been stored to tuple */
- ulint** offsets,/*!< out: offsets on *rec */
+ rec_offs** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in/out: mini-transaction */
@@ -3005,7 +3049,7 @@ btr_cur_optimistic_insert(
specified */
btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
- ulint** offsets,/*!< out: offsets on *rec */
+ rec_offs** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
@@ -3031,7 +3075,7 @@ btr_cur_optimistic_insert(
page_t* page;
rec_t* dummy;
ibool leaf;
- ibool reorg;
+ ibool reorg __attribute__((unused));
ibool inherit = TRUE;
ulint rec_size;
dberr_t err;
@@ -3051,12 +3095,12 @@ btr_cur_optimistic_insert(
const page_size_t& page_size = block->page.size;
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
if (page_size.is_compressed()) {
- UNIV_MEM_ASSERT_RW(page, page_size.logical());
- UNIV_MEM_ASSERT_RW(block->page.zip.data, page_size.physical());
+ MEM_CHECK_DEFINED(page, page_size.logical());
+ MEM_CHECK_DEFINED(block->page.zip.data, page_size.physical());
}
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
leaf = page_is_leaf(page);
@@ -3101,7 +3145,7 @@ fail:
/* prefetch siblings of the leaf for the pessimistic
operation, if the page is leaf. */
- if (page_is_leaf(page)) {
+ if (page_is_leaf(page) && !index->is_ibuf()) {
btr_cur_prefetch_siblings(block);
}
fail_err:
@@ -3114,17 +3158,23 @@ fail_err:
}
ulint max_size = page_get_max_insert_size_after_reorganize(page, 1);
+ if (max_size < rec_size) {
+ goto fail;
+ }
+
+ const ulint n_recs = page_get_n_recs(page);
+ if (UNIV_UNLIKELY(n_recs >= 8189)) {
+ ut_ad(srv_page_size == 65536);
+ goto fail;
+ }
if (page_has_garbage(page)) {
- if ((max_size < rec_size
- || max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT)
- && page_get_n_recs(page) > 1
+ if (max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT
+ && n_recs > 1
&& page_get_max_insert_size(page, 1) < rec_size) {
goto fail;
}
- } else if (max_size < rec_size) {
- goto fail;
}
/* If there have been many consecutive inserts to the
@@ -3294,7 +3344,7 @@ btr_cur_pessimistic_insert(
insertion will certainly succeed */
btr_cur_t* cursor, /*!< in: cursor after which to insert;
cursor stays valid */
- ulint** offsets,/*!< out: offsets on *rec */
+ rec_offs** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap
that can be emptied */
dtuple_t* entry, /*!< in/out: entry to insert */
@@ -3460,7 +3510,7 @@ btr_cur_upd_lock_and_undo(
/*======================*/
ulint flags, /*!< in: undo logging and locking flags */
btr_cur_t* cursor, /*!< in: cursor on record to update */
- const ulint* offsets,/*!< in: rec_get_offsets() on cursor */
+ const rec_offs* offsets,/*!< in: rec_get_offsets() on cursor */
const upd_t* update, /*!< in: update vector */
ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
@@ -3591,7 +3641,7 @@ btr_cur_parse_update_in_place(
roll_ptr_t roll_ptr;
ulint rec_offset;
mem_heap_t* heap;
- ulint* offsets;
+ rec_offs* offsets;
if (end_ptr < ptr + 1) {
@@ -3676,7 +3726,7 @@ btr_cur_update_alloc_zip_func(
page_cur_t* cursor, /*!< in/out: B-tree page cursor */
dict_index_t* index, /*!< in: the index corresponding to cursor */
#ifdef UNIV_DEBUG
- ulint* offsets,/*!< in/out: offsets of the cursor record */
+ rec_offs* offsets,/*!< in/out: offsets of the cursor record */
#endif /* UNIV_DEBUG */
ulint length, /*!< in: size needed */
bool create, /*!< in: true=delete-and-insert,
@@ -3757,7 +3807,7 @@ btr_cur_update_in_place(
btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- ulint* offsets,/*!< in/out: offsets on cursor->page_cur.rec */
+ rec_offs* offsets,/*!< in/out: offsets on cursor->page_cur.rec */
const upd_t* update, /*!< in: update vector */
ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
@@ -3922,7 +3972,7 @@ btr_cur_optimistic_update(
btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
+ rec_offs** offsets,/*!< out: offsets on cursor->page_cur.rec */
mem_heap_t** heap, /*!< in/out: pointer to NULL or memory heap */
const upd_t* update, /*!< in: update vector; this must also
contain trx id and roll ptr fields */
@@ -3949,7 +3999,6 @@ btr_cur_optimistic_update(
dtuple_t* new_entry;
roll_ptr_t roll_ptr;
ulint i;
- ulint n_ext;
block = btr_cur_get_block(cursor);
page = buf_block_get_frame(block);
@@ -3975,7 +4024,7 @@ btr_cur_optimistic_update(
ULINT_UNDEFINED, heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(rec, *offsets)
- || trx_is_recv(thr_get_trx(thr)));
+ || thr_get_trx(thr) == trx_roll_crash_recv_trx);
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
if (!row_upd_changes_field_size_or_external(index, *offsets, update)) {
@@ -3992,6 +4041,7 @@ btr_cur_optimistic_update(
if (rec_offs_any_extern(*offsets)) {
any_extern:
+ ut_ad(!index->is_ibuf());
/* Externally stored fields are treated in pessimistic
update */
@@ -4022,10 +4072,8 @@ any_extern:
+ DTUPLE_EST_ALLOC(rec_offs_n_fields(*offsets)));
}
- new_entry = row_rec_to_index_entry(rec, index, *offsets,
- &n_ext, *heap);
- /* We checked above that there are no externally stored fields. */
- ut_a(!n_ext);
+ new_entry = row_rec_to_index_entry(rec, index, *offsets, *heap);
+ ut_ad(!dtuple_get_n_ext(new_entry));
/* The page containing the clustered index record
corresponding to new_entry is latched in mtr.
@@ -4173,7 +4221,7 @@ func_exit:
}
}
- if (err != DB_SUCCESS) {
+ if (err != DB_SUCCESS && !index->is_ibuf()) {
/* prefetch siblings of the leaf for the pessimistic
operation. */
btr_cur_prefetch_siblings(block);
@@ -4240,7 +4288,7 @@ btr_cur_pessimistic_update(
btr_cur_t* cursor, /*!< in/out: cursor on the record to update;
cursor may become invalid if *big_rec == NULL
|| !(flags & BTR_KEEP_POS_FLAG) */
- ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
+ rec_offs** offsets,/*!< out: offsets on cursor->page_cur.rec */
mem_heap_t** offsets_heap,
/*!< in/out: pointer to memory heap
that can be emptied */
@@ -4273,7 +4321,6 @@ btr_cur_pessimistic_update(
roll_ptr_t roll_ptr;
ibool was_first;
ulint n_reserved = 0;
- ulint n_ext;
ulint max_ins_size = 0;
*offsets = NULL;
@@ -4338,7 +4385,7 @@ btr_cur_pessimistic_update(
ut_ad(rec_offs_validate(rec, index, *offsets));
dtuple_t* new_entry = row_rec_to_index_entry(
- rec, index, *offsets, &n_ext, entry_heap);
+ rec, index, *offsets, entry_heap);
/* The page containing the clustered index record
corresponding to new_entry is latched in mtr. If the
@@ -4354,7 +4401,6 @@ btr_cur_pessimistic_update(
ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec));
ut_ad(rec_offs_validate(rec, index, *offsets));
- n_ext += btr_push_update_extern_fields(new_entry, update, entry_heap);
if ((flags & BTR_NO_UNDO_LOG_FLAG)
&& rec_offs_any_extern(*offsets)) {
@@ -4375,6 +4421,8 @@ btr_cur_pessimistic_update(
index, rec, page_zip, *offsets, update, true, mtr);
}
+ ulint n_ext = dtuple_get_n_ext(new_entry);
+
if (page_zip_rec_needs_ext(
rec_get_converted_size(index, new_entry, n_ext),
page_is_comp(page),
@@ -4762,7 +4810,7 @@ btr_cur_parse_del_mark_set_clust_rec(
clustered index fields. */
ut_ad(pos <= MAX_REF_PARTS);
- ulint offsets[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
+ rec_offs offsets[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
rec_offs_init(offsets);
mem_heap_t* heap = NULL;
@@ -4805,7 +4853,7 @@ btr_cur_del_mark_set_clust_rec(
buf_block_t* block, /*!< in/out: buffer block of the record */
rec_t* rec, /*!< in/out: record */
dict_index_t* index, /*!< in: clustered index of the record */
- const ulint* offsets,/*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec) */
que_thr_t* thr, /*!< in: query thread */
const dtuple_t* entry, /*!< in: dtuple for the deleting record, also
contains the virtual cols if there are any */
@@ -5092,8 +5140,8 @@ btr_cur_optimistic_delete_func(
buf_block_t* block;
rec_t* rec;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
ibool no_compress_needed;
rec_offs_init(offsets_);
@@ -5213,7 +5261,7 @@ btr_cur_pessimistic_delete(
bool success;
ibool ret = FALSE;
mem_heap_t* heap;
- ulint* offsets;
+ rec_offs* offsets;
#ifdef UNIV_DEBUG
bool parent_latched = false;
#endif /* UNIV_DEBUG */
@@ -5312,7 +5360,7 @@ btr_cur_pessimistic_delete(
rtr_mbr_t father_mbr;
rec_t* father_rec;
btr_cur_t father_cursor;
- ulint* offsets;
+ rec_offs* offsets;
bool upd_ret;
ulint len;
@@ -5730,7 +5778,7 @@ btr_estimate_n_rows_in_range_low(
btr_cur_search_to_nth_level(index, 0, tuple1, mode1,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
&cursor, 0,
- __FILE__, __LINE__, &mtr);
+ __FILE__, __LINE__, &mtr, 0);
ut_ad(!page_rec_is_infimum(btr_cur_get_rec(&cursor)));
@@ -5784,7 +5832,7 @@ btr_estimate_n_rows_in_range_low(
btr_cur_search_to_nth_level(index, 0, tuple2, mode2,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
&cursor, 0,
- __FILE__, __LINE__, &mtr);
+ __FILE__, __LINE__, &mtr, 0);
const rec_t* rec = btr_cur_get_rec(&cursor);
@@ -6073,7 +6121,7 @@ btr_record_not_null_field_in_rec(
ulint n_unique, /*!< in: dict_index_get_n_unique(index),
number of columns uniquely determine
an index entry */
- const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec, index),
its size could be for all fields or
that of "n_unique" */
ib_uint64_t* n_not_null) /*!< in/out: array to record number of
@@ -6127,8 +6175,8 @@ btr_estimate_number_of_different_key_vals(
uintmax_t add_on;
mtr_t mtr;
mem_heap_t* heap = NULL;
- ulint* offsets_rec = NULL;
- ulint* offsets_next_rec = NULL;
+ rec_offs* offsets_rec = NULL;
+ rec_offs* offsets_next_rec = NULL;
/* For spatial index, there is no such stats can be
fetched. */
@@ -6290,10 +6338,10 @@ btr_estimate_number_of_different_key_vals(
ULINT_UNDEFINED,
&heap);
- cmp_rec_rec_with_match(rec, next_rec,
- offsets_rec, offsets_next_rec,
- index, stats_null_not_equal,
- &matched_fields);
+ cmp_rec_rec(rec, next_rec,
+ offsets_rec, offsets_next_rec,
+ index, stats_null_not_equal,
+ &matched_fields);
for (j = matched_fields; j < n_cols; j++) {
/* We add one if this index record has
@@ -6316,7 +6364,7 @@ btr_estimate_number_of_different_key_vals(
and assign the old offsets_rec buffer to
offsets_next_rec. */
{
- ulint* offsets_tmp = offsets_rec;
+ rec_offs* offsets_tmp = offsets_rec;
offsets_rec = offsets_next_rec;
offsets_next_rec = offsets_tmp;
}
@@ -6401,7 +6449,7 @@ static
ulint
btr_rec_get_field_ref_offs(
/*=======================*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: index of the external field */
{
ulint field_ref_offs;
@@ -6430,7 +6478,7 @@ btr_rec_get_field_ref_offs(
ulint
btr_rec_get_externally_stored_len(
const rec_t* rec,
- const ulint* offsets)
+ const rec_offs* offsets)
{
ulint n_fields;
ulint total_extern_len = 0;
@@ -6469,7 +6517,7 @@ btr_cur_set_ownership_of_extern_field(
part will be updated, or NULL */
rec_t* rec, /*!< in/out: clustered index record */
dict_index_t* index, /*!< in: index of the page */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint i, /*!< in: field number */
ibool val, /*!< in: value to set */
mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
@@ -6519,7 +6567,7 @@ btr_cur_disown_inherited_fields(
part will be updated, or NULL */
rec_t* rec, /*!< in/out: record in a clustered index */
dict_index_t* index, /*!< in: index of the page */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
@@ -6550,7 +6598,7 @@ btr_cur_unmark_extern_fields(
part will be updated, or NULL */
rec_t* rec, /*!< in/out: record in a clustered index */
dict_index_t* index, /*!< in: index of the page */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
{
ulint n;
@@ -6574,84 +6622,6 @@ btr_cur_unmark_extern_fields(
}
/*******************************************************************//**
-Flags the data tuple fields that are marked as extern storage in the
-update vector. We use this function to remember which fields we must
-mark as extern storage in a record inserted for an update.
-@return number of flagged external columns */
-ulint
-btr_push_update_extern_fields(
-/*==========================*/
- dtuple_t* tuple, /*!< in/out: data tuple */
- const upd_t* update, /*!< in: update vector */
- mem_heap_t* heap) /*!< in: memory heap */
-{
- ulint n_pushed = 0;
- ulint n;
- const upd_field_t* uf;
-
- uf = update->fields;
- n = upd_get_n_fields(update);
-
- for (; n--; uf++) {
- if (dfield_is_ext(&uf->new_val)) {
- dfield_t* field
- = dtuple_get_nth_field(tuple, uf->field_no);
-
- if (!dfield_is_ext(field)) {
- dfield_set_ext(field);
- n_pushed++;
- }
-
- switch (uf->orig_len) {
- byte* data;
- ulint len;
- byte* buf;
- case 0:
- break;
- case BTR_EXTERN_FIELD_REF_SIZE:
- /* Restore the original locally stored
- part of the column. In the undo log,
- InnoDB writes a longer prefix of externally
- stored columns, so that column prefixes
- in secondary indexes can be reconstructed. */
- dfield_set_data(field,
- (byte*) dfield_get_data(field)
- + dfield_get_len(field)
- - BTR_EXTERN_FIELD_REF_SIZE,
- BTR_EXTERN_FIELD_REF_SIZE);
- dfield_set_ext(field);
- break;
- default:
- /* Reconstruct the original locally
- stored part of the column. The data
- will have to be copied. */
- ut_a(uf->orig_len > BTR_EXTERN_FIELD_REF_SIZE);
-
- data = (byte*) dfield_get_data(field);
- len = dfield_get_len(field);
-
- buf = (byte*) mem_heap_alloc(heap,
- uf->orig_len);
- /* Copy the locally stored prefix. */
- memcpy(buf, data,
- uf->orig_len
- - BTR_EXTERN_FIELD_REF_SIZE);
- /* Copy the BLOB pointer. */
- memcpy(buf + uf->orig_len
- - BTR_EXTERN_FIELD_REF_SIZE,
- data + len - BTR_EXTERN_FIELD_REF_SIZE,
- BTR_EXTERN_FIELD_REF_SIZE);
-
- dfield_set_data(field, buf, uf->orig_len);
- dfield_set_ext(field);
- }
- }
- }
-
- return(n_pushed);
-}
-
-/*******************************************************************//**
Returns the length of a BLOB part stored on the header page.
@return part length */
static
@@ -6688,29 +6658,19 @@ btr_blob_free(
mtr_t* mtr) /*!< in: mini-transaction to commit */
{
buf_pool_t* buf_pool = buf_pool_from_block(block);
- ulint space = block->page.id.space();
- ulint page_no = block->page.id.page_no();
-
+ const page_id_t page_id = block->page.id;
ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table));
-
mtr_commit(mtr);
buf_pool_mutex_enter(buf_pool);
- /* Only free the block if it is still allocated to
- the same file page. */
-
- if (buf_block_get_state(block)
- == BUF_BLOCK_FILE_PAGE
- && block->page.id.space() == space
- && block->page.id.page_no() == page_no) {
-
- if (!buf_LRU_free_page(&block->page, all)
- && all && block->page.zip.data) {
+ if (buf_page_t* bpage = buf_page_hash_get(buf_pool, page_id)) {
+ if (!buf_LRU_free_page(bpage, all)
+ && all && bpage->zip.data) {
/* Attempt to deallocate the uncompressed page
if the whole block cannot be deallocted. */
- buf_LRU_free_page(&block->page, false);
+ buf_LRU_free_page(bpage, false);
}
}
@@ -6724,7 +6684,7 @@ struct btr_blob_log_check_t {
/** Mini transaction holding the latches for m_pcur */
mtr_t* m_mtr;
/** rec_get_offsets(rec, index); offset of clust_rec */
- const ulint* m_offsets;
+ const rec_offs* m_offsets;
/** The block containing clustered record */
buf_block_t** m_block;
/** The clustered record pointer */
@@ -6744,7 +6704,7 @@ struct btr_blob_log_check_t {
btr_blob_log_check_t(
btr_pcur_t* pcur,
mtr_t* mtr,
- const ulint* offsets,
+ const rec_offs* offsets,
buf_block_t** block,
rec_t** rec,
enum blob_op op)
@@ -6818,7 +6778,7 @@ struct btr_blob_log_check_t {
*m_rec = btr_pcur_get_rec(m_pcur);
ut_d(rec_offs_make_valid(
- *m_rec, index, const_cast<ulint*>(m_offsets)));
+ *m_rec, index, const_cast<rec_offs*>(m_offsets)));
ut_ad(m_mtr->memo_contains_page_flagged(
*m_rec,
@@ -6849,7 +6809,7 @@ btr_store_big_rec_extern_fields(
btr_pcur_t* pcur, /*!< in/out: a persistent cursor. if
btr_mtr is restarted, then this can
be repositioned. */
- ulint* offsets, /*!< in/out: rec_get_offsets() on
+ rec_offs* offsets, /*!< in/out: rec_get_offsets() on
pcur. the "external storage" flags
in offsets will correctly correspond
to rec when this function returns */
@@ -6959,9 +6919,7 @@ btr_store_big_rec_extern_fields(
BTR_EXTERN_FIELD_REF_SIZE));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
extern_len = big_rec_vec->fields[i].len;
- UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
- extern_len);
-
+ MEM_CHECK_DEFINED(big_rec_vec->fields[i].data, extern_len);
ut_a(extern_len > 0);
prev_page_no = FIL_NULL;
@@ -7109,33 +7067,6 @@ btr_store_big_rec_extern_fields(
/* Initialize the unused "prev page" pointer */
mlog_write_ulint(page + FIL_PAGE_PREV,
FIL_NULL, MLOG_4BYTES, &mtr);
- /* Write a back pointer to the record
- into the otherwise unused area. This
- information could be useful in
- debugging. Later, we might want to
- implement the possibility to relocate
- BLOB pages. Then, we would need to be
- able to adjust the BLOB pointer in the
- record. We do not store the heap
- number of the record, because it can
- change in page_zip_reorganize() or
- btr_page_reorganize(). However, also
- the page number of the record may
- change when B-tree nodes are split or
- merged.
- NOTE: FIL_PAGE_FILE_FLUSH_LSN space is
- used by R-tree index for a Split Sequence
- Number */
- ut_ad(!dict_index_is_spatial(index));
-
- mlog_write_ulint(page
- + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
- space_id,
- MLOG_4BYTES, &mtr);
- mlog_write_ulint(page
- + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4,
- rec_page_no,
- MLOG_4BYTES, &mtr);
/* Zero out the unused part of the page. */
memset(page + page_zip_get_size(page_zip)
@@ -7361,7 +7292,7 @@ btr_free_externally_stored_field(
byte* field_ref, /*!< in/out: field reference */
const rec_t* rec, /*!< in: record containing field_ref, for
page_zip_write_blob_ptr(), or NULL */
- const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec, index),
or NULL */
page_zip_des_t* page_zip, /*!< in: compressed page corresponding
to rec, or NULL if rec == NULL */
@@ -7534,7 +7465,7 @@ btr_rec_free_externally_stored_fields(
dict_index_t* index, /*!< in: index of the data, the index
tree MUST be X-latched */
rec_t* rec, /*!< in/out: record */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
bool rollback,/*!< in: performing rollback? */
@@ -7575,7 +7506,7 @@ btr_rec_free_updated_extern_fields(
rec_t* rec, /*!< in/out: record */
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
const upd_t* update, /*!< in: update vector */
bool rollback,/*!< in: performing rollback? */
mtr_t* mtr) /*!< in: mini-transaction handle which contains
@@ -7655,7 +7586,7 @@ btr_copy_blob_prefix(
mtr_commit(&mtr);
if (page_no == FIL_NULL || copy_len != part_len) {
- UNIV_MEM_ASSERT_RW(buf, copied_len);
+ MEM_CHECK_DEFINED(buf, copied_len);
return(copied_len);
}
@@ -7811,7 +7742,7 @@ end_of_blob:
func_exit:
inflateEnd(&d_stream);
mem_heap_free(heap);
- UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
+ MEM_CHECK_DEFINED(buf, d_stream.total_out);
return(d_stream.total_out);
}
@@ -7973,7 +7904,7 @@ protected by a lock or a page latch
byte*
btr_rec_copy_externally_stored_field(
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
const page_size_t& page_size,
ulint no,
ulint* len,
diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc
index 4646b3252a7..645334cbf4d 100644
--- a/storage/innobase/btr/btr0defragment.cc
+++ b/storage/innobase/btr/btr0defragment.cc
@@ -39,6 +39,9 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com
#include <list>
+using std::list;
+using std::min;
+
/* When there's no work, either because defragment is disabled, or because no
query is submitted, thread checks state every BTR_DEFRAGMENT_SLEEP_IN_USECS.*/
#define BTR_DEFRAGMENT_SLEEP_IN_USECS 1000000
@@ -154,8 +157,6 @@ synchronized defragmentation. */
os_event_t
btr_defragment_add_index(
dict_index_t* index, /*!< index to be added */
- bool async, /*!< whether this is an async
- defragmentation */
dberr_t* err) /*!< out: error code */
{
mtr_t mtr;
@@ -188,10 +189,7 @@ btr_defragment_add_index(
return NULL;
}
btr_pcur_t* pcur = btr_pcur_create_for_mysql();
- os_event_t event = NULL;
- if (!async) {
- event = os_event_create(0);
- }
+ os_event_t event = os_event_create(0);
btr_pcur_open_at_index_side(true, index, BTR_SEARCH_LEAF, pcur,
true, 0, &mtr);
btr_pcur_move_to_next(pcur, &mtr);
@@ -338,8 +336,8 @@ btr_defragment_calc_n_recs_for_size(
{
page_t* page = buf_block_get_frame(block);
ulint n_recs = 0;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
mem_heap_t* heap = NULL;
ulint size = 0;
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index cb5e18457f2..4340c2f32b0 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -293,16 +293,21 @@ btr_pcur_restore_position_func(
if (cursor->rel_pos == BTR_PCUR_ON) {
#ifdef UNIV_DEBUG
const rec_t* rec;
- const ulint* offsets1;
- const ulint* offsets2;
+ rec_offs offsets1_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets2_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets1 = offsets1_;
+ rec_offs* offsets2 = offsets2_;
rec = btr_pcur_get_rec(cursor);
+ rec_offs_init(offsets1_);
+ rec_offs_init(offsets2_);
+
heap = mem_heap_create(256);
offsets1 = rec_get_offsets(
- cursor->old_rec, index, NULL, true,
+ cursor->old_rec, index, offsets1, true,
cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets(
- rec, index, NULL, true,
+ rec, index, offsets2, true,
cursor->old_n_fields, &heap);
ut_ad(!cmp_rec_rec(cursor->old_rec,
@@ -348,8 +353,11 @@ btr_pcur_restore_position_func(
mode = PAGE_CUR_UNSUPP;
}
- btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
- cursor, 0, file, line, mtr);
+ btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode, cursor,
+#ifdef BTR_CUR_HASH_ADAPT
+ 0,
+#endif /* BTR_CUR_HASH_ADAPT */
+ file, line, mtr);
/* Restore the old search mode */
cursor->search_mode = old_mode;
@@ -357,11 +365,13 @@ btr_pcur_restore_position_func(
ut_ad(cursor->rel_pos == BTR_PCUR_ON
|| cursor->rel_pos == BTR_PCUR_BEFORE
|| cursor->rel_pos == BTR_PCUR_AFTER);
+ rec_offs offsets[REC_OFFS_NORMAL_SIZE];
+ rec_offs_init(offsets);
if (cursor->rel_pos == BTR_PCUR_ON
&& btr_pcur_is_on_user_rec(cursor)
&& !cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor),
- index, NULL, true,
+ index, offsets, true,
ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock,
diff --git a/storage/innobase/btr/btr0scrub.cc b/storage/innobase/btr/btr0scrub.cc
index 955a5bc0800..60d9c90c310 100644
--- a/storage/innobase/btr/btr0scrub.cc
+++ b/storage/innobase/btr/btr0scrub.cc
@@ -481,7 +481,7 @@ btr_pessimistic_scrub(
/* arguments to btr_page_split_and_insert */
mem_heap_t* heap = NULL;
dtuple_t* entry = NULL;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
ulint n_ext = 0;
ulint flags = BTR_MODIFY_TREE;
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 725190e7fee..79e6326ac1c 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -141,34 +141,32 @@ static
void
btr_search_check_free_space_in_heap(dict_index_t* index)
{
+ /* Note that we peek the value of heap->free_block without reserving
+ the latch: this is ok, because we will not guarantee that there will
+ be enough free space in the hash table. */
+
+ buf_block_t* block = buf_block_alloc(NULL);
+ rw_lock_t* latch = btr_get_search_latch(index);
hash_table_t* table;
mem_heap_t* heap;
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
+ rw_lock_x_lock(latch);
- table = btr_get_search_table(index);
+ if (!btr_search_enabled) {
+ goto func_exit;
+ }
+ table = btr_get_search_table(index);
heap = table->heap;
- /* Note that we peek the value of heap->free_block without reserving
- the latch: this is ok, because we will not guarantee that there will
- be enough free space in the hash table. */
-
if (heap->free_block == NULL) {
- buf_block_t* block = buf_block_alloc(NULL);
-
- btr_search_x_lock(index);
-
- if (btr_search_enabled
- && heap->free_block == NULL) {
- heap->free_block = block;
- } else {
- buf_block_free(block);
- }
-
- btr_search_x_unlock(index);
+ heap->free_block = block;
+ } else {
+func_exit:
+ buf_block_free(block);
}
+
+ rw_lock_x_unlock(latch);
}
/** Creates and initializes the adaptive search system at a database start.
@@ -197,87 +195,41 @@ btr_search_sys_create(ulint hash_size)
btr_search_sys = reinterpret_cast<btr_search_sys_t*>(
ut_malloc(sizeof(btr_search_sys_t), mem_key_ahi));
- btr_search_sys->hash_tables = reinterpret_cast<hash_table_t**>(
- ut_malloc(sizeof(hash_table_t*) * btr_ahi_parts, mem_key_ahi));
-
- for (ulint i = 0; i < btr_ahi_parts; ++i) {
-
- btr_search_sys->hash_tables[i] =
- ib_create((hash_size / btr_ahi_parts),
- LATCH_ID_HASH_TABLE_MUTEX,
- 0, MEM_HEAP_FOR_BTR_SEARCH);
-
-#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- btr_search_sys->hash_tables[i]->adaptive = TRUE;
-#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- }
-}
-
-/** Resize hash index hash table.
-@param[in] hash_size hash index hash table size */
-void
-btr_search_sys_resize(ulint hash_size)
-{
- /* Step-1: Lock all search latches in exclusive mode. */
- btr_search_x_lock_all();
+ btr_search_sys->hash_tables = NULL;
if (btr_search_enabled) {
-
- btr_search_x_unlock_all();
-
- ib::error() << "btr_search_sys_resize failed because"
- " hash index hash table is not empty.";
- ut_ad(0);
- return;
- }
-
- /* Step-2: Recreate hash tables with new size. */
- for (ulint i = 0; i < btr_ahi_parts; ++i) {
-
- mem_heap_free(btr_search_sys->hash_tables[i]->heap);
- hash_table_free(btr_search_sys->hash_tables[i]);
-
- btr_search_sys->hash_tables[i] =
- ib_create((hash_size / btr_ahi_parts),
- LATCH_ID_HASH_TABLE_MUTEX,
- 0, MEM_HEAP_FOR_BTR_SEARCH);
-
-#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- btr_search_sys->hash_tables[i]->adaptive = TRUE;
-#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+ btr_search_enable();
}
-
- /* Step-3: Unlock all search latches from exclusive mode. */
- btr_search_x_unlock_all();
}
/** Frees the adaptive search system at a database shutdown. */
-void
-btr_search_sys_free()
+void btr_search_sys_free()
{
- ut_ad(btr_search_sys != NULL && btr_search_latches != NULL);
-
- /* Step-1: Release the hash tables. */
- for (ulint i = 0; i < btr_ahi_parts; ++i) {
-
- mem_heap_free(btr_search_sys->hash_tables[i]->heap);
- hash_table_free(btr_search_sys->hash_tables[i]);
-
- }
-
- ut_free(btr_search_sys->hash_tables);
- ut_free(btr_search_sys);
- btr_search_sys = NULL;
-
- /* Step-2: Release all allocates latches. */
- for (ulint i = 0; i < btr_ahi_parts; ++i) {
-
- rw_lock_free(btr_search_latches[i]);
- ut_free(btr_search_latches[i]);
- }
-
- ut_free(btr_search_latches);
- btr_search_latches = NULL;
+ ut_ad(btr_search_sys);
+ ut_ad(btr_search_latches);
+
+ if (btr_search_sys->hash_tables)
+ {
+ for (ulint i= 0; i < btr_ahi_parts; ++i)
+ {
+ mem_heap_free(btr_search_sys->hash_tables[i]->heap);
+ hash_table_free(btr_search_sys->hash_tables[i]);
+ }
+ ut_free(btr_search_sys->hash_tables);
+ }
+
+ ut_free(btr_search_sys);
+ btr_search_sys= NULL;
+
+ /* Free all latches. */
+ for (ulint i= 0; i < btr_ahi_parts; ++i)
+ {
+ rw_lock_free(btr_search_latches[i]);
+ ut_free(btr_search_latches[i]);
+ }
+
+ ut_free(btr_search_latches);
+ btr_search_latches= NULL;
}
/** Set index->ref_count = 0 on all indexes of a table.
@@ -289,38 +241,99 @@ btr_search_disable_ref_count(
{
dict_index_t* index;
- ut_ad(mutex_own(&dict_sys->mutex));
-
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
-
- ut_ad(rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
-
index->search_info->ref_count = 0;
}
}
-/** Disable the adaptive hash search system and empty the index.
-@param[in] need_mutex need to acquire dict_sys->mutex */
-void
-btr_search_disable(
- bool need_mutex)
+/** Lazily free detached metadata when removing the last reference. */
+ATTRIBUTE_COLD static void btr_search_lazy_free(dict_index_t *index)
+{
+ ut_ad(index->freed());
+ dict_table_t *table= index->table;
+ /* Perform the skipped steps of dict_index_remove_from_cache_low(). */
+ UT_LIST_REMOVE(table->freed_indexes, index);
+ rw_lock_free(&index->lock);
+ dict_mem_index_free(index);
+
+ if (!UT_LIST_GET_LEN(table->freed_indexes) &&
+ !UT_LIST_GET_LEN(table->indexes))
+ {
+ ut_ad(table->id == 0);
+ dict_mem_table_free(table);
+ }
+}
+
+/** Clear the adaptive hash index on all pages in the buffer pool. */
+static void buf_pool_clear_hash_index()
+{
+ ut_ad(btr_search_own_all(RW_LOCK_X));
+ ut_ad(!btr_search_enabled);
+
+ std::set<dict_index_t*> garbage;
+
+ for (ulong p = 0; p < srv_buf_pool_instances; p++)
+ {
+ buf_pool_t *buf_pool= buf_pool_from_array(p);
+ buf_chunk_t *chunks= buf_pool->chunks;
+ buf_chunk_t *chunk= chunks + buf_pool->n_chunks;
+
+ while (--chunk >= chunks)
+ {
+ buf_block_t *block= chunk->blocks;
+ for (ulint i= chunk->size; i--; block++)
+ {
+ dict_index_t *index= block->index;
+ assert_block_ahi_valid(block);
+
+ /* We can clear block->index and block->n_pointers when
+ btr_search_own_all(RW_LOCK_X); see the comments in buf0buf.h */
+
+ if (!index)
+ {
+# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ ut_a(!block->n_pointers);
+# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+ continue;
+ }
+
+ ut_d(buf_page_state state= buf_block_get_state(block));
+ /* Another thread may have set the state to
+ BUF_BLOCK_REMOVE_HASH in buf_LRU_block_remove_hashed().
+
+ The state change in buf_page_realloc() is not observable here,
+ because in that case we would have !block->index.
+
+ In the end, the entire adaptive hash index will be removed. */
+ ut_ad(state == BUF_BLOCK_FILE_PAGE || state == BUF_BLOCK_REMOVE_HASH);
+# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ block->n_pointers= 0;
+# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+ if (index->freed())
+ garbage.insert(index);
+ block->index= NULL;
+ }
+ }
+ }
+
+ for (std::set<dict_index_t*>::iterator i= garbage.begin();
+ i != garbage.end(); i++)
+ btr_search_lazy_free(*i);
+}
+
+/** Disable the adaptive hash search system and empty the index. */
+void btr_search_disable()
{
dict_table_t* table;
- if (need_mutex) {
- mutex_enter(&dict_sys->mutex);
- }
+ mutex_enter(&dict_sys->mutex);
- ut_ad(mutex_own(&dict_sys->mutex));
btr_search_x_lock_all();
if (!btr_search_enabled) {
- if (need_mutex) {
- mutex_exit(&dict_sys->mutex);
- }
-
+ mutex_exit(&dict_sys->mutex);
btr_search_x_unlock_all();
return;
}
@@ -341,63 +354,59 @@ btr_search_disable(
btr_search_disable_ref_count(table);
}
- if (need_mutex) {
- mutex_exit(&dict_sys->mutex);
- }
+ mutex_exit(&dict_sys->mutex);
/* Set all block->index = NULL. */
buf_pool_clear_hash_index();
/* Clear the adaptive hash index. */
for (ulint i = 0; i < btr_ahi_parts; ++i) {
- hash_table_clear(btr_search_sys->hash_tables[i]);
- mem_heap_empty(btr_search_sys->hash_tables[i]->heap);
+ mem_heap_free(btr_search_sys->hash_tables[i]->heap);
+ hash_table_free(btr_search_sys->hash_tables[i]);
}
+ ut_free(btr_search_sys->hash_tables);
+ btr_search_sys->hash_tables = NULL;
btr_search_x_unlock_all();
}
-/** Enable the adaptive hash search system. */
+/** Enable the adaptive hash search system.
+@param[in] resize Flag to indicate call during buf_pool_resize() */
void
-btr_search_enable()
+btr_search_enable(bool resize)
{
- buf_pool_mutex_enter_all();
- if (srv_buf_pool_old_size != srv_buf_pool_size) {
+ if (!resize) {
+ buf_pool_mutex_enter_all();
+ if (srv_buf_pool_old_size != srv_buf_pool_size) {
+ buf_pool_mutex_exit_all();
+ return;
+ }
buf_pool_mutex_exit_all();
- return;
}
- buf_pool_mutex_exit_all();
+ ulint hash_size = buf_pool_get_curr_size() / sizeof(void *) / 64;
btr_search_x_lock_all();
- btr_search_enabled = true;
- btr_search_x_unlock_all();
-}
-
-/** Returns the value of ref_count. The value is protected by latch.
-@param[in] info search info
-@param[in] index index identifier
-@return ref_count value. */
-ulint
-btr_search_info_get_ref_count(
- btr_search_t* info,
- dict_index_t* index)
-{
- ulint ret = 0;
- if (!btr_search_enabled) {
- return(ret);
+ if (btr_search_sys->hash_tables) {
+ ut_ad(btr_search_enabled);
+ btr_search_x_unlock_all();
+ return;
}
- ut_ad(info);
-
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
-
- btr_search_s_lock(index);
- ret = info->ref_count;
- btr_search_s_unlock(index);
+ btr_search_sys->hash_tables = reinterpret_cast<hash_table_t**>(
+ ut_malloc(sizeof(hash_table_t*) * btr_ahi_parts, mem_key_ahi));
+ for (ulint i = 0; i < btr_ahi_parts; ++i) {
+ btr_search_sys->hash_tables[i] =
+ ib_create((hash_size / btr_ahi_parts),
+ LATCH_ID_HASH_TABLE_MUTEX,
+ 0, MEM_HEAP_FOR_BTR_SEARCH);
+#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ btr_search_sys->hash_tables[i]->adaptive = TRUE;
+#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+ }
- return(ret);
+ btr_search_enabled = true;
+ btr_search_x_unlock_all();
}
/** Updates the search info of an index about hash successes. NOTE that info
@@ -415,8 +424,8 @@ btr_search_info_update_hash(
ulint n_unique;
int cmp;
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
+ ut_ad(!rw_lock_own_flagged(btr_get_search_latch(index),
+ RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
if (dict_index_is_ibuf(index)) {
/* So many deletes are performed on an insert buffer tree
@@ -601,59 +610,60 @@ btr_search_update_hash_ref(
buf_block_t* block,
const btr_cur_t* cursor)
{
- dict_index_t* index;
- ulint fold;
- rec_t* rec;
-
ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
- ut_ad(rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
+
ut_ad(rw_lock_own_flagged(&block->lock,
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
ut_ad(page_align(btr_cur_get_rec(cursor)) == block->frame);
ut_ad(page_is_leaf(block->frame));
assert_block_ahi_valid(block);
- index = block->index;
-
- if (!index) {
+ dict_index_t* index = block->index;
+ if (!index || !info->n_hash_potential) {
return;
}
ut_ad(block->page.id.space() == index->space);
ut_a(index == cursor->index);
- ut_a(!dict_index_is_ibuf(index));
+ ut_ad(!dict_index_is_ibuf(index));
+ rw_lock_t* const latch = btr_get_search_latch(index);
+ rw_lock_x_lock(latch);
+ ut_ad(!block->index || block->index == index);
- if ((info->n_hash_potential > 0)
+ if (block->index
&& (block->curr_n_fields == info->n_fields)
&& (block->curr_n_bytes == info->n_bytes)
- && (block->curr_left_side == info->left_side)) {
+ && (block->curr_left_side == info->left_side)
+ && btr_search_enabled) {
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
- rec = btr_cur_get_rec(cursor);
+ const rec_t* rec = btr_cur_get_rec(cursor);
if (!page_rec_is_user_rec(rec)) {
-
- return;
+ goto func_exit;
}
- fold = rec_fold(rec,
- rec_get_offsets(rec, index, offsets_, true,
- ULINT_UNDEFINED, &heap),
- block->curr_n_fields,
- block->curr_n_bytes, index->id);
+ ulint fold = rec_fold(
+ rec,
+ rec_get_offsets(rec, index, offsets_, true,
+ ULINT_UNDEFINED, &heap),
+ block->curr_n_fields,
+ block->curr_n_bytes, index->id);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
- ut_ad(rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
ha_insert_for_fold(btr_get_search_table(index), fold,
block, rec);
MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_ADDED);
}
+
+func_exit:
+ rw_lock_x_unlock(latch);
}
/** Updates the search info.
@@ -692,12 +702,7 @@ btr_search_info_update_slow(
#ifdef UNIV_SEARCH_PERF_STAT
btr_search_n_hash_fail++;
#endif /* UNIV_SEARCH_PERF_STAT */
-
- btr_search_x_lock(cursor->index);
-
btr_search_update_hash_ref(info, block, cursor);
-
- btr_search_x_unlock(cursor->index);
}
if (build_index) {
@@ -740,8 +745,8 @@ btr_search_check_guess(
ulint match;
int cmp;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
ibool success = FALSE;
rec_offs_init(offsets_);
@@ -898,7 +903,6 @@ btr_search_guess_on_hash(
ulint has_search_latch,
mtr_t* mtr)
{
- const rec_t* rec;
ulint fold;
index_id_t index_id;
#ifdef notdefined
@@ -944,33 +948,28 @@ btr_search_guess_on_hash(
cursor->fold = fold;
cursor->flag = BTR_CUR_HASH;
+ rw_lock_t* const latch = btr_get_search_latch(index);
+
if (!has_search_latch) {
- btr_search_s_lock(index);
+ rw_lock_s_lock(latch);
if (!btr_search_enabled) {
- btr_search_s_unlock(index);
-
+fail:
+ if (!has_search_latch) {
+ rw_lock_s_unlock(latch);
+ }
btr_search_failure(info, cursor);
-
return(FALSE);
}
}
- ut_ad(rw_lock_get_writer(btr_get_search_latch(index)) != RW_LOCK_X);
- ut_ad(rw_lock_get_reader_count(btr_get_search_latch(index)) > 0);
-
- rec = (rec_t*) ha_search_and_get_data(
- btr_get_search_table(index), fold);
-
- if (rec == NULL) {
-
- if (!has_search_latch) {
- btr_search_s_unlock(index);
- }
+ ut_ad(rw_lock_own(latch, RW_LOCK_S));
- btr_search_failure(info, cursor);
+ const rec_t* rec = static_cast<const rec_t*>(
+ ha_search_and_get_data(btr_get_search_table(index), fold));
- return(FALSE);
+ if (!rec) {
+ goto fail;
}
buf_block_t* block = buf_block_from_ahi(rec);
@@ -980,32 +979,33 @@ btr_search_guess_on_hash(
if (!buf_page_get_known_nowait(
latch_mode, block, BUF_MAKE_YOUNG,
__FILE__, __LINE__, mtr)) {
-
- if (!has_search_latch) {
- btr_search_s_unlock(index);
- }
-
- btr_search_failure(info, cursor);
-
- return(FALSE);
+ goto fail;
}
- btr_search_s_unlock(index);
+ const bool fail = index != block->index
+ && index_id == block->index->id;
+ ut_a(!fail || block->index->freed());
+ rw_lock_s_unlock(latch);
buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
+ if (UNIV_UNLIKELY(fail)) {
+ goto fail_and_release_page;
+ }
+ } else if (UNIV_UNLIKELY(index != block->index
+ && index_id == block->index->id)) {
+ ut_a(block->index->freed());
+ goto fail_and_release_page;
}
if (buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
ut_ad(buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH);
-
+fail_and_release_page:
if (!has_search_latch) {
-
btr_leaf_page_release(block, latch_mode, mtr);
}
btr_search_failure(info, cursor);
-
return(FALSE);
}
@@ -1024,14 +1024,7 @@ btr_search_guess_on_hash(
|| !btr_search_check_guess(cursor,
has_search_latch,
tuple, mode, mtr)) {
-
- if (!has_search_latch) {
- btr_leaf_page_release(block, latch_mode, mtr);
- }
-
- btr_search_failure(info, cursor);
-
- return(FALSE);
+ goto fail_and_release_page;
}
if (info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5) {
@@ -1115,30 +1108,26 @@ btr_search_drop_page_hash_index(buf_block_t* block)
ulint* folds;
ulint i;
mem_heap_t* heap;
- const dict_index_t* index;
- ulint* offsets;
+ rec_offs* offsets;
rw_lock_t* latch;
- btr_search_t* info;
retry:
- /* Do a dirty check on block->index, return if the block is
- not in the adaptive hash index. */
- index = block->index;
/* This debug check uses a dirty read that could theoretically cause
false positives while buf_pool_clear_hash_index() is executing. */
assert_block_ahi_valid(block);
- if (index == NULL) {
+ if (!block->index) {
return;
}
ut_ad(block->page.buf_fix_count == 0
|| buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH
|| rw_lock_own_flagged(&block->lock,
- RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
+ RW_LOCK_FLAG_X | RW_LOCK_FLAG_S
+ | RW_LOCK_FLAG_SX));
ut_ad(page_is_leaf(block->frame));
- /* We must not dereference index here, because it could be freed
+ /* We must not dereference block->index here, because it could be freed
if (index->table->n_ref_count == 0 && !mutex_own(&dict_sys->mutex)).
Determine the ahi_slot based on the block contents. */
@@ -1156,18 +1145,12 @@ retry:
rw_lock_s_lock(latch);
assert_block_ahi_valid(block);
- if (block->index == NULL) {
+ if (!block->index || !btr_search_enabled) {
rw_lock_s_unlock(latch);
return;
}
- /* The index associated with a block must remain the
- same, because we are holding block->lock or the block is
- not accessible by other threads (BUF_BLOCK_REMOVE_HASH),
- or the index is not accessible to other threads
- (buf_fix_count == 0 when DROP TABLE or similar is executing
- buf_LRU_drop_page_hash_for_tablespace()). */
- ut_a(index == block->index);
+ dict_index_t* index = block->index;
#ifdef MYSQL_INDEX_DISABLE_AHI
ut_ad(!index->disable_ahi);
#endif
@@ -1176,27 +1159,7 @@ retry:
ut_ad(index->space == FIL_NULL
|| block->page.id.space() == index->space);
ut_a(index_id == index->id);
- ut_a(!dict_index_is_ibuf(index));
-#ifdef UNIV_DEBUG
- switch (dict_index_get_online_status(index)) {
- case ONLINE_INDEX_CREATION:
- /* The index is being created (bulk loaded). */
- case ONLINE_INDEX_COMPLETE:
- /* The index has been published. */
- case ONLINE_INDEX_ABORTED:
- /* Either the index creation was aborted due to an
- error observed by InnoDB (in which case there should
- not be any adaptive hash index entries), or it was
- completed and then flagged aborted in
- rollback_inplace_alter_table(). */
- break;
- case ONLINE_INDEX_ABORTED_DROPPED:
- /* The index should have been dropped from the tablespace
- already, and the adaptive hash index entries should have
- been dropped as well. */
- ut_error;
- }
-#endif /* UNIV_DEBUG */
+ ut_ad(!dict_index_is_ibuf(index));
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
@@ -1281,9 +1244,14 @@ next_rec:
folds[i], page);
}
- info = btr_search_get_info(block->index);
- ut_a(info->ref_count > 0);
- info->ref_count--;
+ switch (index->search_info->ref_count--) {
+ case 0:
+ ut_error;
+ case 1:
+ if (index->freed()) {
+ btr_search_lazy_free(index);
+ }
+ }
block->index = NULL;
@@ -1370,8 +1338,8 @@ btr_search_build_page_hash_index(
rec_t** recs;
ulint i;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
#ifdef MYSQL_INDEX_DISABLE_AHI
if (index->disable_ahi) return;
@@ -1383,27 +1351,32 @@ btr_search_build_page_hash_index(
rec_offs_init(offsets_);
ut_ad(index);
ut_ad(block->page.id.space() == index->space);
- ut_a(!dict_index_is_ibuf(index));
+ ut_ad(!dict_index_is_ibuf(index));
ut_ad(page_is_leaf(block->frame));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
ut_ad(rw_lock_own_flagged(&block->lock,
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
+ ut_ad(block->page.id.page_no() >= 3);
+
+ rw_lock_t* const latch = btr_get_search_latch(index);
+ rw_lock_s_lock(latch);
- btr_search_s_lock(index);
+ if (!btr_search_enabled) {
+ rw_lock_s_unlock(latch);
+ return;
+ }
table = btr_get_search_table(index);
page = buf_block_get_frame(block);
- if (block->index && ((block->curr_n_fields != n_fields)
- || (block->curr_n_bytes != n_bytes)
- || (block->curr_left_side != left_side))) {
-
- btr_search_s_unlock(index);
+ const bool must_drop = block->index
+ && ((block->curr_n_fields != n_fields)
+ || (block->curr_n_bytes != n_bytes)
+ || (block->curr_left_side != left_side));
+ rw_lock_s_unlock(latch);
+ if (must_drop) {
btr_search_drop_page_hash_index(block);
- } else {
- btr_search_s_unlock(index);
}
/* Check that the values for hash index build are sensible */
@@ -1495,12 +1468,13 @@ btr_search_build_page_hash_index(
btr_search_check_free_space_in_heap(index);
- btr_search_x_lock(index);
+ rw_lock_x_lock(latch);
if (!btr_search_enabled) {
goto exit_func;
}
+ table = btr_get_search_table(index);
if (block->index && ((block->curr_n_fields != n_fields)
|| (block->curr_n_bytes != n_bytes)
|| (block->curr_left_side != left_side))) {
@@ -1533,7 +1507,7 @@ btr_search_build_page_hash_index(
MONITOR_INC_VALUE(MONITOR_ADAPTIVE_HASH_ROW_ADDED, n_cached);
exit_func:
assert_block_ahi_valid(block);
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(latch);
ut_free(folds);
ut_free(recs);
@@ -1566,21 +1540,19 @@ btr_search_move_or_delete_hash_entries(
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_X));
ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_X));
- btr_search_s_lock(index);
+ rw_lock_t* const latch = btr_get_search_latch(index);
+ rw_lock_s_lock(latch);
ut_a(!new_block->index || new_block->index == index);
ut_a(!block->index || block->index == index);
- ut_a(!(new_block->index || block->index)
- || !dict_index_is_ibuf(index));
+ ut_ad(!(new_block->index || block->index)
+ || !dict_index_is_ibuf(index));
assert_block_ahi_valid(block);
assert_block_ahi_valid(new_block);
if (new_block->index) {
-
- btr_search_s_unlock(index);
-
+ rw_lock_s_unlock(latch);
btr_search_drop_page_hash_index(block);
-
return;
}
@@ -1593,7 +1565,7 @@ btr_search_move_or_delete_hash_entries(
new_block->n_bytes = block->curr_n_bytes;
new_block->left_side = left_side;
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(latch);
ut_a(n_fields > 0 || n_bytes > 0);
@@ -1605,7 +1577,7 @@ btr_search_move_or_delete_hash_entries(
return;
}
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(latch);
}
/** Updates the page hash index when a single record is deleted from a page.
@@ -1619,7 +1591,7 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
const rec_t* rec;
ulint fold;
dict_index_t* index;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
mem_heap_t* heap = NULL;
rec_offs_init(offsets_);
@@ -1647,9 +1619,7 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
ut_ad(block->page.id.space() == index->space);
ut_a(index == cursor->index);
ut_a(block->curr_n_fields > 0 || block->curr_n_bytes > 0);
- ut_a(!dict_index_is_ibuf(index));
-
- table = btr_get_search_table(index);
+ ut_ad(!dict_index_is_ibuf(index));
rec = btr_cur_get_rec(cursor);
@@ -1660,9 +1630,16 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
mem_heap_free(heap);
}
- btr_search_x_lock(index);
+ rw_lock_t* const latch = btr_get_search_latch(index);
+ rw_lock_x_lock(latch);
assert_block_ahi_valid(block);
+ if (!btr_search_enabled) {
+ rw_lock_x_unlock(latch);
+ return;
+ }
+
+ table = btr_get_search_table(index);
if (block->index) {
ut_a(block->index == index);
@@ -1676,7 +1653,7 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
assert_block_ahi_valid(block);
}
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(latch);
}
/** Updates the page hash index when a single record is inserted on a page.
@@ -1712,11 +1689,12 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
}
ut_a(cursor->index == index);
- ut_a(!dict_index_is_ibuf(index));
+ ut_ad(!dict_index_is_ibuf(index));
- btr_search_x_lock(index);
+ rw_lock_t* const latch = btr_get_search_latch(index);
+ rw_lock_x_lock(latch);
- if (!block->index) {
+ if (!block->index || !btr_search_enabled) {
goto func_exit;
}
@@ -1738,10 +1716,9 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
func_exit:
assert_block_ahi_valid(block);
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(latch);
} else {
- btr_search_x_unlock(index);
-
+ rw_lock_x_unlock(latch);
btr_search_update_hash_on_insert(cursor);
}
}
@@ -1754,7 +1731,6 @@ func_exit:
void
btr_search_update_hash_on_insert(btr_cur_t* cursor)
{
- hash_table_t* table;
buf_block_t* block;
dict_index_t* index;
const rec_t* rec;
@@ -1765,11 +1741,9 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
ulint next_fold = 0; /* remove warning (??? bug ???) */
ulint n_fields;
ulint n_bytes;
- ibool left_side;
- ibool locked = FALSE;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
@@ -1795,19 +1769,17 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
ut_ad(block->page.id.space() == index->space);
btr_search_check_free_space_in_heap(index);
- table = btr_get_search_table(index);
-
rec = btr_cur_get_rec(cursor);
#ifdef MYSQL_INDEX_DISABLE_AHI
ut_a(!index->disable_ahi);
#endif
ut_a(index == cursor->index);
- ut_a(!dict_index_is_ibuf(index));
+ ut_ad(!dict_index_is_ibuf(index));
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
- left_side = block->curr_left_side;
+ const bool left_side = block->curr_left_side;
ins_rec = page_rec_get_next_const(rec);
next_rec = page_rec_get_next_const(ins_rec);
@@ -1824,22 +1796,26 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
n_bytes, index->id);
}
+ rw_lock_t* const latch = btr_get_search_latch(index);
+ /* We must not look up "table" before acquiring the latch. */
+ hash_table_t* table = NULL;
+ bool locked = false;
+
if (!page_rec_is_infimum(rec)) {
offsets = rec_get_offsets(
rec, index, offsets, true,
btr_search_get_n_fields(n_fields, n_bytes), &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
} else {
- if (left_side) {
+ locked = left_side;
+ if (locked) {
+ rw_lock_x_lock(latch);
- btr_search_x_lock(index);
-
- locked = TRUE;
-
- if (!btr_search_enabled) {
+ if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+ table = btr_get_search_table(index);
ha_insert_for_fold(table, ins_fold, block, ins_rec);
}
@@ -1849,14 +1825,14 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
if (fold != ins_fold) {
if (!locked) {
+ locked = true;
+ rw_lock_x_lock(latch);
- btr_search_x_lock(index);
-
- locked = TRUE;
-
- if (!btr_search_enabled) {
+ if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
+ table = btr_get_search_table(index);
}
if (!left_side) {
@@ -1870,15 +1846,15 @@ check_next_rec:
if (page_rec_is_supremum(next_rec)) {
if (!left_side) {
-
if (!locked) {
- btr_search_x_lock(index);
+ locked = true;
+ rw_lock_x_lock(latch);
- locked = TRUE;
-
- if (!btr_search_enabled) {
+ if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
+ table = btr_get_search_table(index);
}
ha_insert_for_fold(table, ins_fold, block, ins_rec);
@@ -1888,16 +1864,15 @@ check_next_rec:
}
if (ins_fold != next_fold) {
-
if (!locked) {
+ locked = true;
+ rw_lock_x_lock(latch);
- btr_search_x_lock(index);
-
- locked = TRUE;
-
- if (!btr_search_enabled) {
+ if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
+ table = btr_get_search_table(index);
}
if (!left_side) {
@@ -1912,7 +1887,7 @@ function_exit:
mem_heap_free(heap);
}
if (locked) {
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(latch);
}
}
@@ -1930,10 +1905,12 @@ btr_search_hash_table_validate(ulint hash_table_id)
ulint i;
ulint cell_count;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
+ btr_search_x_lock_all();
if (!btr_search_enabled) {
+ btr_search_x_unlock_all();
return(TRUE);
}
@@ -1943,7 +1920,6 @@ btr_search_hash_table_validate(ulint hash_table_id)
rec_offs_init(offsets_);
- btr_search_x_lock_all();
buf_pool_mutex_enter_all();
cell_count = hash_get_n_cells(
@@ -1960,6 +1936,12 @@ btr_search_hash_table_validate(ulint hash_table_id)
os_thread_yield();
btr_search_x_lock_all();
+
+ if (!btr_search_enabled) {
+ ok = true;
+ goto func_exit;
+ }
+
buf_pool_mutex_enter_all();
ulint curr_cell_count = hash_get_n_cells(
@@ -2019,7 +2001,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
== BUF_BLOCK_REMOVE_HASH);
}
- ut_a(!dict_index_is_ibuf(block->index));
+ ut_ad(!dict_index_is_ibuf(block->index));
ut_ad(block->page.id.space() == block->index->space);
page_index_id = btr_page_get_index_id(block->frame);
@@ -2077,6 +2059,12 @@ btr_search_hash_table_validate(ulint hash_table_id)
os_thread_yield();
btr_search_x_lock_all();
+
+ if (!btr_search_enabled) {
+ ok = true;
+ goto func_exit;
+ }
+
buf_pool_mutex_enter_all();
ulint curr_cell_count = hash_get_n_cells(
@@ -2101,6 +2089,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
}
buf_pool_mutex_exit_all();
+func_exit:
btr_search_x_unlock_all();
if (UNIV_LIKELY_NULL(heap)) {
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index 0863facad52..80d82b9e78c 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2019, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -85,7 +85,6 @@ enum buf_buddy_state_t {
are in use */
};
-#ifdef UNIV_DEBUG_VALGRIND
/**********************************************************************//**
Invalidate memory area that we won't access while page is free */
UNIV_INLINE
@@ -95,15 +94,11 @@ buf_buddy_mem_invalid(
buf_buddy_free_t* buf, /*!< in: block to check */
ulint i) /*!< in: index of zip_free[] */
{
- const size_t size = BUF_BUDDY_LOW << i;
- ut_ad(i <= BUF_BUDDY_SIZES);
+ ut_ad(i <= BUF_BUDDY_SIZES);
- UNIV_MEM_ASSERT_W(buf, size);
- UNIV_MEM_INVALID(buf, size);
+ MEM_CHECK_ADDRESSABLE(buf, BUF_BUDDY_LOW << i);
+ MEM_UNDEFINED(buf, BUF_BUDDY_LOW << i);
}
-#else /* UNIV_DEBUG_VALGRIND */
-# define buf_buddy_mem_invalid(buf, i) ut_ad((i) <= BUF_BUDDY_SIZES)
-#endif /* UNIV_DEBUG_VALGRIND */
/**********************************************************************//**
Check if a buddy is stamped free.
@@ -351,7 +346,7 @@ buf_buddy_alloc_zip(
if (buf) {
buf_buddy_free_t* buddy =
reinterpret_cast<buf_buddy_free_t*>(
- buf->stamp.bytes
+ reinterpret_cast<byte*>(buf)
+ (BUF_BUDDY_LOW << i));
ut_ad(!buf_pool_contains_zip(buf_pool, buddy));
@@ -361,11 +356,10 @@ buf_buddy_alloc_zip(
if (buf) {
/* Trash the page other than the BUF_BUDDY_STAMP_NONFREE. */
- UNIV_MEM_TRASH((void*) buf, ~i, BUF_BUDDY_STAMP_OFFSET);
- UNIV_MEM_TRASH(BUF_BUDDY_STAMP_OFFSET + 4
- + buf->stamp.bytes, ~i,
- (BUF_BUDDY_LOW << i)
- - (BUF_BUDDY_STAMP_OFFSET + 4));
+ MEM_UNDEFINED(buf, BUF_BUDDY_STAMP_OFFSET);
+ MEM_UNDEFINED(BUF_BUDDY_STAMP_OFFSET + 4 + buf->stamp.bytes,
+ (BUF_BUDDY_LOW << i)
+ - (BUF_BUDDY_STAMP_OFFSET + 4));
ut_ad(mach_read_from_4(buf->stamp.bytes
+ BUF_BUDDY_STAMP_OFFSET)
== BUF_BUDDY_STAMP_NONFREE);
@@ -402,8 +396,10 @@ buf_buddy_block_free(
ut_d(bpage->in_zip_hash = FALSE);
HASH_DELETE(buf_page_t, hash, buf_pool->zip_hash, fold, bpage);
- ut_d(memset(buf, 0, UNIV_PAGE_SIZE));
- UNIV_MEM_INVALID(buf, UNIV_PAGE_SIZE);
+ ut_d(memset(buf, 0, srv_page_size));
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(buf, srv_page_size);
+#endif /* HAVE_valgrind_or_MSAN */
block = (buf_block_t*) bpage;
buf_page_mutex_enter(block);
@@ -559,17 +555,16 @@ buf_buddy_relocate(
ut_ad(!ut_align_offset(src, size));
ut_ad(!ut_align_offset(dst, size));
ut_ad(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
- UNIV_MEM_ASSERT_W(dst, size);
+ MEM_CHECK_ADDRESSABLE(dst, size);
space = mach_read_from_4((const byte*) src
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
offset = mach_read_from_4((const byte*) src
+ FIL_PAGE_OFFSET);
- /* Suppress Valgrind warnings about conditional jump
- on uninitialized value. */
- UNIV_MEM_VALID(&space, sizeof space);
- UNIV_MEM_VALID(&offset, sizeof offset);
+ /* Suppress Valgrind or MSAN warnings. */
+ MEM_MAKE_DEFINED(&space, sizeof space);
+ MEM_MAKE_DEFINED(&offset, sizeof offset);
ut_ad(space != BUF_BUDDY_STAMP_FREE);
@@ -631,7 +626,7 @@ buf_buddy_relocate(
/* The block must have been allocated, but it may
contain uninitialized data. */
- UNIV_MEM_ASSERT_W(src, size);
+ MEM_CHECK_ADDRESSABLE(src, size);
BPageMutex* block_mutex = buf_page_get_mutex(bpage);
@@ -686,7 +681,7 @@ buf_buddy_free_low(
buf_pool->buddy_stat[i].used--;
recombine:
- UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i);
+ MEM_UNDEFINED(buf, BUF_BUDDY_LOW << i);
if (i == BUF_BUDDY_SIZES) {
buf_buddy_block_free(buf_pool, buf);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index b5ca51c81dc..cfc79868482 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -83,6 +83,8 @@ Created 11/5/1995 Heikki Tuuri
#include "lzo/lzo1x.h"
#endif
+using st_::span;
+
#ifdef HAVE_LIBNUMA
#include <numa.h>
#include <numaif.h>
@@ -103,6 +105,7 @@ struct set_numa_interleave_t
" policy to MPOL_INTERLEAVE: "
<< strerror(errno);
}
+ numa_bitmask_free(numa_mems_allowed);
}
}
@@ -130,29 +133,6 @@ struct set_numa_interleave_t
#include "snappy-c.h"
#endif
-inline void* aligned_malloc(size_t size, size_t align) {
- void *result;
-#ifdef _MSC_VER
- result = _aligned_malloc(size, align);
-#elif defined (HAVE_POSIX_MEMALIGN)
- if(posix_memalign(&result, align, size)) {
- result = 0;
- }
-#else
- /* Use unaligned malloc as fallback */
- result = malloc(size);
-#endif
- return result;
-}
-
-inline void aligned_free(void *ptr) {
-#ifdef _MSC_VER
- _aligned_free(ptr);
-#else
- free(ptr);
-#endif
-}
-
/*
IMPLEMENTATION OF THE BUFFER POOL
=================================
@@ -483,7 +463,7 @@ buf_pool_register_chunk(
@return true if temporary tablespace decrypted, false if not */
static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame)
{
- if (buf_page_is_zeroes(src_frame, srv_page_size)) {
+ if (buf_is_zeroes(span<const byte>(src_frame, srv_page_size))) {
return true;
}
@@ -567,13 +547,13 @@ decompress:
decompress_with_slot:
ut_d(fil_page_type_validate(dst_frame));
- bpage->write_size = fil_page_decompress(slot->crypt_buf,
- dst_frame);
+ ulint write_size = fil_page_decompress(slot->crypt_buf,
+ dst_frame);
slot->release();
- ut_ad(!bpage->write_size || fil_page_type_validate(dst_frame));
+ ut_ad(!write_size || fil_page_type_validate(dst_frame));
ut_ad(space->n_pending_ios > 0);
- return bpage->write_size != 0;
+ return write_size != 0;
}
if (space->crypt_data
@@ -972,20 +952,14 @@ static uint32_t buf_page_check_crc32(const byte* page, uint32_t checksum)
# define buf_page_check_crc32(page, checksum) buf_calc_page_crc32(page)
#endif /* INNODB_BUG_ENDIAN_CRC32 */
-/** Check if a page is all zeroes.
-@param[in] read_buf database page
-@param[in] page_size page frame size
-@return whether the page is all zeroes */
-bool buf_page_is_zeroes(const void* read_buf, size_t page_size)
+
+/** Check if a buffer is all zeroes.
+@param[in] buf data to check
+@return whether the buffer is all zeroes */
+bool buf_is_zeroes(span<const byte> buf)
{
- const ulint* b = reinterpret_cast<const ulint*>(read_buf);
- const ulint* const e = b + page_size / sizeof *b;
- do {
- if (*b++) {
- return false;
- }
- } while (b != e);
- return true;
+ ut_ad(buf.size() <= sizeof field_ref_zero);
+ return memcmp(buf.data(), field_ref_zero, buf.size()) == 0;
}
/** Check if a page is corrupt.
@@ -1103,7 +1077,7 @@ buf_page_is_corrupted(
/* A page filled with NUL bytes is considered not corrupted.
The FIL_PAGE_FILE_FLUSH_LSN field may be written nonzero for
- the first page of each file of the system tablespace.
+ the first page of the system tablespace.
Ignore it for the system tablespace. */
if (!checksum_field1 && !checksum_field2) {
/* Checksum fields can have valid value as zero.
@@ -1513,8 +1487,6 @@ buf_block_init(
buf_block_t* block, /*!< in: pointer to control block */
byte* frame) /*!< in: pointer to buffer frame */
{
- UNIV_MEM_DESC(frame, UNIV_PAGE_SIZE);
-
/* This function should only be executed at database startup or by
buf_pool_resize(). Either way, adaptive hash index must not exist. */
assert_block_ahi_empty_on_init(block);
@@ -1528,7 +1500,6 @@ buf_block_init(
block->page.io_fix = BUF_IO_NONE;
block->page.flush_observer = NULL;
block->page.real_size = 0;
- block->page.write_size = 0;
block->modify_clock = 0;
block->page.slot = NULL;
@@ -1537,8 +1508,6 @@ buf_block_init(
#ifdef BTR_CUR_HASH_ADAPT
block->index = NULL;
#endif /* BTR_CUR_HASH_ADAPT */
- block->skip_flush_check = false;
-
ut_d(block->page.in_page_hash = FALSE);
ut_d(block->page.in_zip_hash = FALSE);
ut_d(block->page.in_flush_list = FALSE);
@@ -1623,6 +1592,7 @@ buf_chunk_init(
" buffer pool page frames to MPOL_INTERLEAVE"
" (error: " << strerror(errno) << ").";
}
+ numa_bitmask_free(numa_mems_allowed);
}
#endif /* HAVE_LIBNUMA */
@@ -1661,7 +1631,7 @@ buf_chunk_init(
for (i = chunk->size; i--; ) {
buf_block_init(buf_pool, block, frame);
- UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE);
+ MEM_UNDEFINED(block->frame, srv_page_size);
/* Add the block to the free list */
UT_LIST_ADD_LAST(buf_pool->free, &block->page);
@@ -2206,8 +2176,6 @@ buf_page_realloc(
if (block->page.zip.data != NULL) {
ut_ad(block->in_unzip_LRU_list);
ut_d(new_block->in_unzip_LRU_list = TRUE);
- UNIV_MEM_DESC(&new_block->page.zip.data,
- page_zip_get_size(&new_block->page.zip));
buf_block_t* prev_block = UT_LIST_GET_PREV(unzip_LRU, block);
UT_LIST_REMOVE(buf_pool->unzip_LRU, block);
@@ -2233,15 +2201,15 @@ buf_page_realloc(
ut_d(block->page.in_page_hash = FALSE);
ulint fold = block->page.id.fold();
ut_ad(fold == new_block->page.id.fold());
- HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, (&block->page));
- HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold, (&new_block->page));
+ HASH_REPLACE(buf_page_t, hash, buf_pool->page_hash, fold,
+ &block->page, &new_block->page);
ut_ad(new_block->page.in_page_hash);
buf_block_modify_clock_inc(block);
memset(block->frame + FIL_PAGE_OFFSET, 0xff, 4);
memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
- UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE);
+ MEM_UNDEFINED(block->frame, srv_page_size);
buf_block_set_state(block, BUF_BLOCK_REMOVE_HASH);
block->page.id
= page_id_t(ULINT32_UNDEFINED, ULINT32_UNDEFINED);
@@ -2669,23 +2637,6 @@ buf_pool_resize_hash(
buf_pool->zip_hash = new_hash_table;
}
-#ifndef DBUG_OFF
-/** This is a debug routine to inject an memory allocation failure error. */
-static
-void
-buf_pool_resize_chunk_make_null(buf_chunk_t** new_chunks)
-{
- static int count = 0;
-
- if (count == 1) {
- ut_free(*new_chunks);
- *new_chunks = NULL;
- }
-
- count++;
-}
-#endif // DBUG_OFF
-
/** Resize the buffer pool based on srv_buf_pool_size from
srv_buf_pool_old_size. */
static
@@ -2741,7 +2692,7 @@ buf_pool_resize()
btr_search_s_unlock_all();
}
- btr_search_disable(true);
+ btr_search_disable();
if (btr_search_disabled) {
ib::info() << "disabled adaptive hash index.";
@@ -2952,7 +2903,8 @@ withdraw_retry:
ut_zalloc_nokey_nofatal(new_chunks_size));
DBUG_EXECUTE_IF("buf_pool_resize_chunk_null",
- buf_pool_resize_chunk_make_null(&new_chunks););
+ ut_free(new_chunks);
+ new_chunks = NULL;);
if (new_chunks == NULL) {
ib::error() << "buffer pool " << i
@@ -3114,10 +3066,6 @@ calc_buf_pool_size:
srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
lock_sys_resize(srv_lock_table_size);
- /* normalize btr_search_sys */
- btr_search_sys_resize(
- buf_pool_get_curr_size() / sizeof(void*) / 64);
-
/* normalize dict_sys */
dict_resize();
@@ -3142,7 +3090,7 @@ calc_buf_pool_size:
#ifdef BTR_CUR_HASH_ADAPT
/* enable AHI if needed */
if (btr_search_disabled) {
- btr_search_enable();
+ btr_search_enable(true);
ib::info() << "Re-enabled adaptive hash index.";
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -3207,66 +3155,6 @@ DECLARE_THREAD(buf_resize_thread)(void*)
OS_THREAD_DUMMY_RETURN;
}
-#ifdef BTR_CUR_HASH_ADAPT
-/** Clear the adaptive hash index on all pages in the buffer pool. */
-void
-buf_pool_clear_hash_index()
-{
- ulint p;
-
- ut_ad(btr_search_own_all(RW_LOCK_X));
- ut_ad(!buf_pool_resizing);
- ut_ad(!btr_search_enabled);
-
- for (p = 0; p < srv_buf_pool_instances; p++) {
- buf_pool_t* buf_pool = buf_pool_from_array(p);
- buf_chunk_t* chunks = buf_pool->chunks;
- buf_chunk_t* chunk = chunks + buf_pool->n_chunks;
-
- while (--chunk >= chunks) {
- buf_block_t* block = chunk->blocks;
- ulint i = chunk->size;
-
- for (; i--; block++) {
- dict_index_t* index = block->index;
- assert_block_ahi_valid(block);
-
- /* We can set block->index = NULL
- and block->n_pointers = 0
- when btr_search_own_all(RW_LOCK_X);
- see the comments in buf0buf.h */
-
- if (!index) {
-# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- ut_a(!block->n_pointers);
-# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- continue;
- }
-
- ut_d(buf_page_state state
- = buf_block_get_state(block));
- /* Another thread may have set the
- state to BUF_BLOCK_REMOVE_HASH in
- buf_LRU_block_remove_hashed().
-
- The state change in buf_page_realloc()
- is not observable here, because in
- that case we would have !block->index.
-
- In the end, the entire adaptive hash
- index will be removed. */
- ut_ad(state == BUF_BLOCK_FILE_PAGE
- || state == BUF_BLOCK_REMOVE_HASH);
-# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- block->n_pointers = 0;
-# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- block->index = NULL;
- }
- }
- }
-}
-#endif /* BTR_CUR_HASH_ADAPT */
-
/********************************************************************//**
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list.
@@ -3350,8 +3238,8 @@ buf_relocate(
/* relocate buf_pool->page_hash */
ulint fold = bpage->id.fold();
ut_ad(fold == dpage->id.fold());
- HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, bpage);
- HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold, dpage);
+ HASH_REPLACE(buf_page_t, hash, buf_pool->page_hash, fold, bpage,
+ dpage);
}
/** Hazard Pointer implementation. */
@@ -3831,9 +3719,9 @@ lookup:
ut_ad(!hash_lock);
dberr_t err = buf_read_page(page_id, page_size);
- if (err != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::error() << "Reading compressed page " << page_id
- << " failed with error: " << ut_strerr(err);
+ << " failed with error: " << err;
goto err_exit;
}
@@ -3932,7 +3820,6 @@ buf_block_init_low(
/*===============*/
buf_block_t* block) /*!< in: block to init */
{
- block->skip_flush_check = false;
#ifdef BTR_CUR_HASH_ADAPT
/* No adaptive hash index entries may point to a previously
unused (and now freshly allocated) block. */
@@ -3991,7 +3878,8 @@ buf_zip_decompress(
frame, size, SRV_CHECKSUM_ALGORITHM_INNODB)
<< ", none: "
<< page_zip_calc_checksum(
- frame, size, SRV_CHECKSUM_ALGORITHM_NONE);
+ frame, size, SRV_CHECKSUM_ALGORITHM_NONE)
+ << " (algorithm: " << srv_checksum_algorithm << ")";
goto err_exit;
}
@@ -4230,7 +4118,94 @@ buf_wait_for_read(
}
}
-/** This is the general function used to get access to a database page.
+#ifdef BTR_CUR_HASH_ADAPT
+/** If a stale adaptive hash index exists on the block, drop it.
+Multiple executions of btr_search_drop_page_hash_index() on the
+same block must be prevented by exclusive page latch. */
+ATTRIBUTE_COLD
+static void buf_defer_drop_ahi(buf_block_t *block, mtr_memo_type_t fix_type)
+{
+ switch (fix_type) {
+ case MTR_MEMO_BUF_FIX:
+ /* We do not drop the adaptive hash index, because safely doing
+ so would require acquiring block->lock, and that is not safe
+ to acquire in some RW_NO_LATCH access paths. Those code paths
+ should have no business accessing the adaptive hash index anyway. */
+ break;
+ case MTR_MEMO_PAGE_S_FIX:
+ /* Temporarily release our S-latch. */
+ rw_lock_s_unlock(&block->lock);
+ rw_lock_x_lock(&block->lock);
+ if (dict_index_t *index= block->index)
+ if (index->freed())
+ btr_search_drop_page_hash_index(block);
+ rw_lock_x_unlock(&block->lock);
+ rw_lock_s_lock(&block->lock);
+ break;
+ case MTR_MEMO_PAGE_SX_FIX:
+ rw_lock_sx_unlock(&block->lock);
+ rw_lock_x_lock(&block->lock);
+ if (dict_index_t *index= block->index)
+ if (index->freed())
+ btr_search_drop_page_hash_index(block);
+ rw_lock_x_unlock(&block->lock);
+ rw_lock_sx_lock(&block->lock);
+ break;
+ default:
+ ut_ad(fix_type == MTR_MEMO_PAGE_X_FIX);
+ btr_search_drop_page_hash_index(block);
+ }
+}
+#endif /* BTR_CUR_HASH_ADAPT */
+
+/** Lock the page with the given latch type.
+@param[in,out] block block to be locked
+@param[in] rw_latch RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH
+@param[in] mtr mini-transaction
+@param[in] file file name
+@param[in] line line where called
+@return pointer to locked block */
+static buf_block_t* buf_page_mtr_lock(buf_block_t *block,
+ ulint rw_latch,
+ mtr_t* mtr,
+ const char *file,
+ unsigned line)
+{
+ mtr_memo_type_t fix_type;
+ switch (rw_latch)
+ {
+ case RW_NO_LATCH:
+ fix_type= MTR_MEMO_BUF_FIX;
+ goto done;
+ case RW_S_LATCH:
+ rw_lock_s_lock_inline(&block->lock, 0, file, line);
+ fix_type= MTR_MEMO_PAGE_S_FIX;
+ break;
+ case RW_SX_LATCH:
+ rw_lock_sx_lock_inline(&block->lock, 0, file, line);
+ fix_type= MTR_MEMO_PAGE_SX_FIX;
+ break;
+ default:
+ ut_ad(rw_latch == RW_X_LATCH);
+ rw_lock_x_lock_inline(&block->lock, 0, file, line);
+ fix_type= MTR_MEMO_PAGE_X_FIX;
+ break;
+ }
+
+#ifdef BTR_CUR_HASH_ADAPT
+ {
+ dict_index_t *index= block->index;
+ if (index && index->freed())
+ buf_defer_drop_ahi(block, fix_type);
+ }
+#endif /* BTR_CUR_HASH_ADAPT */
+
+done:
+ mtr_memo_push(mtr, block, fix_type);
+ return block;
+}
+
+/** This is the low level function used to get access to a database page.
@param[in] page_id page id
@param[in] rw_latch RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH
@param[in] guess guessed block or NULL
@@ -4241,7 +4216,7 @@ BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or BUF_GET_IF_IN_POOL_OR_WATCH
@param[in] mtr mini-transaction
@return pointer to the block or NULL */
buf_block_t*
-buf_page_get_gen(
+buf_page_get_low(
const page_id_t page_id,
const page_size_t& page_size,
ulint rw_latch,
@@ -4543,6 +4518,7 @@ evict_from_pool:
buf_pool_mutex_exit(buf_pool);
return(NULL);
}
+
break;
case BUF_BLOCK_ZIP_PAGE:
@@ -4637,9 +4613,6 @@ evict_from_pool:
block->lock_hash_val = lock_rec_hash(page_id.space(),
page_id.page_no());
- UNIV_MEM_DESC(&block->page.zip.data,
- page_zip_get_size(&block->page.zip));
-
if (buf_page_get_state(&block->page) == BUF_BLOCK_ZIP_PAGE) {
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
UT_LIST_REMOVE(buf_pool->zip_clean, &block->page);
@@ -4661,7 +4634,7 @@ evict_from_pool:
buf_block_set_io_fix(block, BUF_IO_READ);
rw_lock_x_lock_inline(&block->lock, 0, file, line);
- UNIV_MEM_INVALID(bpage, sizeof *bpage);
+ MEM_UNDEFINED(bpage, sizeof *bpage);
rw_lock_x_unlock(hash_lock);
buf_pool->n_pend_unzip++;
@@ -4678,7 +4651,7 @@ evict_from_pool:
buf_pool->mutex or block->mutex. */
{
- bool success = buf_zip_decompress(block, TRUE);
+ bool success = buf_zip_decompress(block, false);
if (!success) {
buf_pool_mutex_enter(buf_pool);
@@ -4884,35 +4857,7 @@ evict_from_pool:
return NULL;
}
- mtr_memo_type_t fix_type;
-
- switch (rw_latch) {
- case RW_NO_LATCH:
-
- fix_type = MTR_MEMO_BUF_FIX;
- break;
-
- case RW_S_LATCH:
- rw_lock_s_lock_inline(&fix_block->lock, 0, file, line);
-
- fix_type = MTR_MEMO_PAGE_S_FIX;
- break;
-
- case RW_SX_LATCH:
- rw_lock_sx_lock_inline(&fix_block->lock, 0, file, line);
-
- fix_type = MTR_MEMO_PAGE_SX_FIX;
- break;
-
- default:
- ut_ad(rw_latch == RW_X_LATCH);
- rw_lock_x_lock_inline(&fix_block->lock, 0, file, line);
-
- fix_type = MTR_MEMO_PAGE_X_FIX;
- break;
- }
-
- mtr_memo_push(mtr, fix_block, fix_type);
+ fix_block = buf_page_mtr_lock(fix_block, rw_latch, mtr, file, line);
if (mode != BUF_PEEK_IF_IN_POOL && !access_time) {
/* In the case of a first access, try to apply linear
@@ -4927,6 +4872,42 @@ evict_from_pool:
return(fix_block);
}
+/** This is the general function used to get access to a database page.
+It does page initialization and applies the buffered redo logs.
+@param[in] page_id page id
+@param[in] rw_latch RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH
+@param[in] guess guessed block or NULL
+@param[in] mode BUF_GET, BUF_GET_IF_IN_POOL,
+BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or BUF_GET_IF_IN_POOL_OR_WATCH
+@param[in] file file name
+@param[in] line line where called
+@param[in] mtr mini-transaction
+@param[out] err DB_SUCCESS or error code
+@return pointer to the block or NULL */
+buf_block_t*
+buf_page_get_gen(
+ const page_id_t page_id,
+ const page_size_t& page_size,
+ ulint rw_latch,
+ buf_block_t* guess,
+ ulint mode,
+ const char* file,
+ unsigned line,
+ mtr_t* mtr,
+ dberr_t* err)
+{
+ if (buf_block_t *block = recv_recovery_create_page(page_id))
+ {
+ buf_block_fix(block);
+ ut_ad(rw_lock_s_lock_nowait(&block->debug_latch, file, line));
+ block= buf_page_mtr_lock(block, rw_latch, mtr, file, line);
+ return block;
+ }
+
+ return buf_page_get_low(page_id, page_size, rw_latch,
+ guess, mode, file, line, mtr, err);
+}
+
/********************************************************************//**
This is the general function used to get optimistic access to a database
page.
@@ -5082,9 +5063,11 @@ buf_page_get_known_nowait(
buf_pool = buf_pool_from_block(block);
+#ifdef BTR_CUR_HASH_ADAPT
if (mode == BUF_MAKE_YOUNG) {
buf_page_make_young_if_needed(&block->page);
}
+#endif /* BTR_CUR_HASH_ADAPT */
ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
@@ -5127,9 +5110,12 @@ buf_page_get_known_nowait(
deleting a record from SYS_INDEXES. This check will be
skipped in recv_recover_page() as well. */
- buf_page_mutex_enter(block);
- ut_a(!block->page.file_page_was_freed);
- buf_page_mutex_exit(block);
+# ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!block->page.file_page_was_freed
+ || (block->index && block->index->freed()));
+# else /* BTR_CUR_HASH_ADAPT */
+ ut_ad(!block->page.file_page_was_freed);
+# endif /* BTR_CUR_HASH_ADAPT */
}
#endif /* UNIV_DEBUG */
@@ -5238,7 +5224,6 @@ buf_page_init_low(
bpage->access_time = 0;
bpage->newest_modification = 0;
bpage->oldest_modification = 0;
- bpage->write_size = 0;
bpage->real_size = 0;
bpage->slot = NULL;
@@ -5273,15 +5258,6 @@ buf_page_init(
/* Set the state of the block */
buf_block_set_file_page(block, page_id);
-#ifdef UNIV_DEBUG_VALGRIND
- if (is_system_tablespace(page_id.space())) {
- /* Silence valid Valgrind warnings about uninitialized
- data being written to data files. There are some unused
- bytes on some pages that InnoDB does not initialize. */
- UNIV_MEM_VALID(block->frame, UNIV_PAGE_SIZE);
- }
-#endif /* UNIV_DEBUG_VALGRIND */
-
buf_block_init_low(block);
block->lock_hash_val = lock_rec_hash(page_id.space(),
@@ -5295,7 +5271,8 @@ buf_page_init(
if (hash_page == NULL) {
/* Block not found in hash table */
- } else if (buf_pool_watch_is_sentinel(buf_pool, hash_page)) {
+ } else if (UNIV_LIKELY(buf_pool_watch_is_sentinel(buf_pool,
+ hash_page))) {
/* Preserve the reference count. */
ib_uint32_t buf_fix_count = hash_page->buf_fix_count;
@@ -5305,18 +5282,8 @@ buf_page_init(
buf_pool_watch_remove(buf_pool, hash_page);
} else {
-
- ib::error() << "Page " << page_id
- << " already found in the hash table: "
- << hash_page << ", " << block;
-
- ut_d(buf_page_mutex_exit(block));
- ut_d(buf_pool_mutex_exit(buf_pool));
- ut_d(buf_print());
- ut_d(buf_LRU_print());
- ut_d(buf_validate());
- ut_d(buf_LRU_validate());
- ut_error;
+ ib::fatal() << "Page already foudn in the hash table: "
+ << page_id;
}
ut_ad(!block->page.in_zip_hash);
@@ -5517,7 +5484,6 @@ buf_page_init_for_read(
bpage->size.copy_from(page_size);
mutex_enter(&buf_pool->zip_mutex);
- UNIV_MEM_DESC(bpage->zip.data, bpage->size.physical());
buf_page_init_low(bpage);
@@ -5598,14 +5564,13 @@ buf_page_create(
buf_frame_t* frame;
buf_block_t* block;
buf_block_t* free_block = NULL;
- buf_pool_t* buf_pool = buf_pool_get(page_id);
+ buf_pool_t* buf_pool= buf_pool_get(page_id);
rw_lock_t* hash_lock;
ut_ad(mtr->is_active());
ut_ad(page_id.space() != 0 || !page_size.is_compressed());
-
+loop:
free_block = buf_LRU_get_free_block(buf_pool);
-
buf_pool_mutex_enter(buf_pool);
hash_lock = buf_page_hash_lock_get(buf_pool, page_id);
@@ -5617,21 +5582,107 @@ buf_page_create(
&& buf_page_in_file(&block->page)
&& !buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
ut_d(block->page.file_page_was_freed = FALSE);
+ buf_page_state page_state = buf_block_get_state(block);
+#ifdef BTR_CUR_HASH_ADAPT
+ const dict_index_t *drop_hash_entry= NULL;
+#endif
+ switch (page_state) {
+ default:
+ ut_ad(0);
+ break;
+ case BUF_BLOCK_ZIP_PAGE:
+ case BUF_BLOCK_ZIP_DIRTY:
+ buf_block_init_low(free_block);
+ mutex_enter(&buf_pool->zip_mutex);
+ buf_page_mutex_enter(free_block);
+ if (buf_page_get_io_fix(&block->page) != BUF_IO_NONE) {
+ mutex_exit(&buf_pool->zip_mutex);
+ rw_lock_x_unlock(hash_lock);
+ buf_LRU_block_free_non_file_page(free_block);
+ buf_pool_mutex_exit(buf_pool);
+ buf_page_mutex_exit(free_block);
+
+ goto loop;
+ }
+
+ rw_lock_x_lock(&free_block->lock);
+
+ buf_relocate(&block->page, &free_block->page);
+ if (page_state == BUF_BLOCK_ZIP_DIRTY) {
+ ut_ad(block->page.in_flush_list);
+ ut_ad(block->page.oldest_modification > 0);
+ buf_flush_relocate_on_flush_list(
+ &block->page, &free_block->page);
+ } else {
+ ut_ad(block->page.oldest_modification == 0);
+ ut_ad(!block->page.in_flush_list);
+#ifdef UNIV_DEBUG
+ UT_LIST_REMOVE(
+ buf_pool->zip_clean, &block->page);
+#endif
+ }
+
+ free_block->page.state = BUF_BLOCK_FILE_PAGE;
+ mutex_exit(&buf_pool->zip_mutex);
+ free_block->lock_hash_val = lock_rec_hash(
+ page_id.space(), page_id.page_no());
+ buf_unzip_LRU_add_block(free_block, false);
+ buf_page_free_descriptor(&block->page);
+ block = free_block;
+ buf_block_fix(block);
+ buf_page_mutex_exit(free_block);
+ free_block = NULL;
+ break;
+ case BUF_BLOCK_FILE_PAGE:
+ buf_block_fix(block);
+ const int32_t num_fix_count =
+ mtr->get_fix_count(block) + 1;
+ buf_page_mutex_enter(block);
+ while (buf_block_get_io_fix(block) != BUF_IO_NONE
+ || (num_fix_count
+ != block->page.buf_fix_count)) {
+ buf_page_mutex_exit(block);
+ buf_pool_mutex_exit(buf_pool);
+ rw_lock_x_unlock(hash_lock);
+
+ os_thread_yield();
+
+ buf_pool_mutex_enter(buf_pool);
+ rw_lock_x_lock(hash_lock);
+ buf_page_mutex_enter(block);
+ }
+
+ rw_lock_x_lock(&block->lock);
+ buf_page_mutex_exit(block);
+#ifdef BTR_CUR_HASH_ADAPT
+ drop_hash_entry = block->index;
+#endif
+ break;
+ }
/* Page can be found in buf_pool */
buf_pool_mutex_exit(buf_pool);
rw_lock_x_unlock(hash_lock);
- buf_block_free(free_block);
+ if (free_block) {
+ buf_block_free(free_block);
+ }
+#ifdef BTR_CUR_HASH_ADAPT
+ if (drop_hash_entry) {
+ btr_search_drop_page_hash_index(block);
+ }
+#endif /* BTR_CUR_HASH_ADAPT */
- if (!recv_recovery_is_on()) {
- return buf_page_get_with_no_latch(page_id, page_size,
- mtr);
+#ifdef UNIV_DEBUG
+ if (!fsp_is_system_temporary(page_id.space())) {
+ rw_lock_s_lock_nowait(
+ &block->debug_latch,
+ __FILE__, __LINE__);
}
+#endif /* UNIV_DEBUG */
+
+ mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);
- mutex_exit(&recv_sys->mutex);
- block = buf_page_get_with_no_latch(page_id, page_size, mtr);
- mutex_enter(&recv_sys->mutex);
return block;
}
@@ -5646,6 +5697,8 @@ buf_page_create(
buf_page_init(buf_pool, page_id, page_size, block);
+ rw_lock_x_lock(&block->lock);
+
rw_lock_x_unlock(hash_lock);
/* The block must be put to the LRU list */
@@ -5663,7 +5716,6 @@ buf_page_create(
by IO-fixing and X-latching the block. */
buf_page_set_io_fix(&block->page, BUF_IO_READ);
- rw_lock_x_lock(&block->lock);
buf_page_mutex_exit(block);
/* buf_pool->mutex may be released and reacquired by
@@ -5685,12 +5737,11 @@ buf_page_create(
buf_unzip_LRU_add_block(block, FALSE);
buf_page_set_io_fix(&block->page, BUF_IO_NONE);
- rw_lock_x_unlock(&block->lock);
}
buf_pool_mutex_exit(buf_pool);
- mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
+ mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);
buf_page_set_accessed(&block->page);
@@ -6058,9 +6109,8 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict)
err = buf_page_check_corrupt(bpage, space);
-database_corrupted:
-
if (err != DB_SUCCESS) {
+database_corrupted:
/* Not a real corruption if it was triggered by
error injection */
DBUG_EXECUTE_IF(
@@ -6077,6 +6127,11 @@ database_corrupted:
goto page_not_corrupt;
);
+ if (uncompressed && bpage->zip.data) {
+ memset(reinterpret_cast<buf_block_t*>(bpage)
+ ->frame, 0, srv_page_size);
+ }
+
if (err == DB_PAGE_CORRUPTED) {
ib::error()
<< "Database page corruption on disk"
@@ -7288,6 +7343,7 @@ operator<<(
return(out);
}
+#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/** Print the given buf_pool_t object.
@param[in,out] out the output stream
@param[in] buf_pool the buf_pool_t object to be printed
@@ -7315,6 +7371,7 @@ operator<<(
<< ", written=" << buf_pool.stat.n_pages_written << "]";
return(out);
}
+#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
/** Encrypt a buffer of temporary tablespace
@param[in] offset Page offset
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index 93201c3793f..30f24d57391 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -34,6 +34,8 @@ Created 2011/12/19
#include "fil0crypt.h"
#include "fil0pagecompress.h"
+using st_::span;
+
/** The doublewrite buffer */
buf_dblwr_t* buf_dblwr = NULL;
@@ -168,6 +170,7 @@ buf_dblwr_create()
{
buf_block_t* block2;
buf_block_t* new_block;
+ buf_block_t* trx_sys_block;
byte* doublewrite;
byte* fseg_header;
ulint page_no;
@@ -207,9 +210,14 @@ start_again:
}
}
- block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
+ trx_sys_block = buf_page_get(
+ page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
+ page_size_t(srv_page_size, srv_page_size, 0), RW_X_LATCH,
+ &mtr);
+
+ block2 = fseg_create(TRX_SYS_SPACE,
TRX_SYS_DOUBLEWRITE
- + TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
+ + TRX_SYS_DOUBLEWRITE_FSEG, &mtr, trx_sys_block);
if (block2 == NULL) {
too_small:
@@ -530,30 +538,54 @@ buf_dblwr_init_or_load_pages(
void
buf_dblwr_process()
{
+ ut_ad(recv_sys->parse_start_lsn);
+
ulint page_no_dblwr = 0;
byte* read_buf;
- byte* unaligned_read_buf;
recv_dblwr_t& recv_dblwr = recv_sys->dblwr;
if (!buf_dblwr) {
return;
}
- unaligned_read_buf = static_cast<byte*>(
- ut_malloc_nokey(3 * UNIV_PAGE_SIZE));
-
read_buf = static_cast<byte*>(
- ut_align(unaligned_read_buf, UNIV_PAGE_SIZE));
- byte* const buf = read_buf + UNIV_PAGE_SIZE;
+ aligned_malloc(3 * srv_page_size, srv_page_size));
+ byte* const buf = read_buf + srv_page_size;
for (recv_dblwr_t::list::iterator i = recv_dblwr.pages.begin();
i != recv_dblwr.pages.end();
++i, ++page_no_dblwr) {
- byte* page = *i;
- ulint space_id = page_get_space_id(page);
- fil_space_t* space = fil_space_get(space_id);
+ byte* page = *i;
+ const ulint page_no = page_get_page_no(page);
+
+ if (!page_no) {
+ /* page 0 should have been recovered
+ already via Datafile::restore_from_doublewrite() */
+ continue;
+ }
- if (space == NULL) {
+ const ulint space_id = page_get_space_id(page);
+ const lsn_t lsn = mach_read_from_8(page + FIL_PAGE_LSN);
+
+ if (recv_sys->parse_start_lsn > lsn) {
+ /* Pages written before the checkpoint are
+ not useful for recovery. */
+ continue;
+ }
+
+ const page_id_t page_id(space_id, page_no);
+
+ if (recv_sys->scanned_lsn < lsn) {
+ ib::warn() << "Ignoring a doublewrite copy of page "
+ << page_id
+ << " with future log sequence number "
+ << lsn;
+ continue;
+ }
+
+ fil_space_t* space = fil_space_acquire_for_io(space_id);
+
+ if (!space) {
/* Maybe we have dropped the tablespace
and this page once belonged to it: do nothing */
continue;
@@ -561,10 +593,7 @@ buf_dblwr_process()
fil_space_open_if_needed(space);
- const ulint page_no = page_get_page_no(page);
- const page_id_t page_id(space_id, page_no);
-
- if (page_no >= space->size) {
+ if (UNIV_UNLIKELY(page_no >= space->size)) {
/* Do not report the warning if the tablespace
is scheduled for truncation or was truncated
@@ -572,16 +601,21 @@ buf_dblwr_process()
if (!srv_is_tablespace_truncated(space_id)
&& !srv_was_tablespace_truncated(space)
&& !srv_is_undo_tablespace(space_id)) {
- ib::warn() << "A copy of page " << page_id
+ ib::warn() << "A copy of page " << page_no
<< " in the doublewrite buffer slot "
<< page_no_dblwr
- << " is not within space bounds";
+ << " is beyond the end of tablespace "
+ << space->name
+ << " (" << space->size << " pages)";
}
+next_page:
+ fil_space_release_for_io(space);
continue;
}
const page_size_t page_size(space->flags);
- ut_ad(!buf_page_is_zeroes(page, page_size.physical()));
+ ut_ad(!buf_is_zeroes(span<const byte>(page,
+ page_size.physical())));
/* We want to ensure that for partial reads the
unread portion of the page is NUL. */
@@ -597,83 +631,34 @@ buf_dblwr_process()
page_id, page_size,
0, page_size.physical(), read_buf, NULL);
- if (err != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::warn()
<< "Double write buffer recovery: "
<< page_id << " read failed with "
- << "error: " << ut_strerr(err);
+ << "error: " << err;
}
- const bool is_all_zero = buf_page_is_zeroes(
- read_buf, page_size.physical());
- const bool expect_encrypted = space->crypt_data
- && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED;
-
- if (is_all_zero) {
+ if (buf_is_zeroes(span<const byte>(read_buf,
+ page_size.physical()))) {
/* We will check if the copy in the
doublewrite buffer is valid. If not, we will
ignore this page (there should be redo log
records to initialize it). */
+ } else if (recv_dblwr.validate_page(
+ page_id, read_buf, space, buf)) {
+ goto next_page;
} else {
- /* Decompress the page before
- validating the checksum. */
- ulint decomp = fil_page_decompress(buf, read_buf);
- if (!decomp || (decomp != srv_page_size
- && page_size.is_compressed())) {
- goto bad;
- }
-
- if (expect_encrypted && mach_read_from_4(
- read_buf
- + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
- ? fil_space_verify_crypt_checksum(read_buf,
- page_size)
- : !buf_page_is_corrupted(true, read_buf,
- page_size, space)) {
- /* The page is good; there is no need
- to consult the doublewrite buffer. */
- continue;
- }
-
-bad:
/* We intentionally skip this message for
- is_all_zero pages. */
+ all-zero pages. */
ib::info()
<< "Trying to recover page " << page_id
<< " from the doublewrite buffer.";
}
- ulint decomp = fil_page_decompress(buf, page);
- if (!decomp || (decomp != srv_page_size
- && page_size.is_compressed())) {
- continue;
- }
-
- if (expect_encrypted && mach_read_from_4(
- page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
- ? !fil_space_verify_crypt_checksum(page, page_size)
- : buf_page_is_corrupted(true, page, page_size, space)) {
- /* Theoretically we could have another good
- copy for this page in the doublewrite
- buffer. If not, we will report a fatal error
- for a corrupted page somewhere else if that
- page was truly needed. */
- continue;
- }
+ page = recv_dblwr.find_page(page_id, space, buf);
- if (page_no == 0) {
- /* Check the FSP_SPACE_FLAGS. */
- ulint flags = fsp_header_get_flags(page);
- if (!fsp_flags_is_valid(flags, space_id)
- && fsp_flags_convert_from_101(flags)
- == ULINT_UNDEFINED) {
- ib::warn() << "Ignoring a doublewrite copy"
- " of page " << page_id
- << " due to invalid flags "
- << ib::hex(flags);
- continue;
- }
- /* The flags on the page should be converted later. */
+ if (!page) {
+ goto next_page;
}
/* Write the good page from the doublewrite buffer to
@@ -682,17 +667,18 @@ bad:
IORequest write_request(IORequest::WRITE);
fil_io(write_request, true, page_id, page_size,
- 0, page_size.physical(),
- const_cast<byte*>(page), NULL);
+ 0, page_size.physical(), page, NULL);
ib::info() << "Recovered page " << page_id
<< " from the doublewrite buffer.";
+
+ goto next_page;
}
recv_dblwr.pages.clear();
fil_flush_file_spaces(FIL_TYPE_TABLESPACE);
- ut_free(unaligned_read_buf);
+ aligned_free(read_buf);
}
/****************************************************************//**
@@ -849,10 +835,6 @@ buf_dblwr_check_block(
{
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
- if (block->skip_flush_check) {
- return;
- }
-
switch (fil_page_get_type(block->frame)) {
case FIL_PAGE_INDEX:
case FIL_PAGE_RTREE:
@@ -992,6 +974,7 @@ try_again:
int64_t sig_count = os_event_reset(buf_dblwr->b_event);
mutex_exit(&buf_dblwr->mutex);
+ os_aio_simulated_wake_handler_threads();
os_event_wait_low(buf_dblwr->b_event, sig_count);
goto try_again;
}
@@ -1121,6 +1104,7 @@ try_again:
checkpoint. */
int64_t sig_count = os_event_reset(buf_dblwr->b_event);
mutex_exit(&buf_dblwr->mutex);
+ os_aio_simulated_wake_handler_threads();
os_event_wait_low(buf_dblwr->b_event, sig_count);
goto try_again;
@@ -1142,7 +1126,7 @@ try_again:
void * frame = buf_page_get_frame(bpage);
if (bpage->size.is_compressed()) {
- UNIV_MEM_ASSERT_RW(bpage->zip.data, bpage->size.physical());
+ MEM_CHECK_DEFINED(bpage->zip.data, bpage->size.physical());
/* Copy the compressed page and clear the rest. */
memcpy(p, frame, bpage->size.physical());
@@ -1151,10 +1135,7 @@ try_again:
univ_page_size.physical() - bpage->size.physical());
} else {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
-
- UNIV_MEM_ASSERT_RW(frame,
- bpage->size.logical());
-
+ MEM_CHECK_DEFINED(frame, bpage->size.logical());
memcpy(p, frame, bpage->size.logical());
}
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index 3e01b66eb76..b3ef58ecb55 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,6 +25,7 @@ Created April 08, 2011 Vasil Dimov
*******************************************************/
#include "my_global.h"
+#include "mysqld.h"
#include "my_sys.h"
#include "mysql/psi/mysql_stage.h"
@@ -185,7 +186,7 @@ get_buf_dump_dir()
/* The dump file should be created in the default data directory if
innodb_data_home_dir is set as an empty string. */
- if (strcmp(srv_data_home, "") == 0) {
+ if (!*srv_data_home) {
dump_dir = fil_path_to_mysql_datadir;
} else {
dump_dir = srv_data_home;
@@ -197,16 +198,14 @@ get_buf_dump_dir()
/** Generate the path to the buffer pool dump/load file.
@param[out] path generated path
@param[in] path_size size of 'path', used as in snprintf(3). */
-static
-void
-buf_dump_generate_path(
- char* path,
- size_t path_size)
+static void buf_dump_generate_path(char *path, size_t path_size)
{
char buf[FN_REFLEN];
+ mysql_mutex_lock(&LOCK_global_system_variables);
snprintf(buf, sizeof(buf), "%s%c%s", get_buf_dump_dir(),
OS_PATH_SEPARATOR, srv_buf_dump_filename);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
os_file_type_t type;
bool exists = false;
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 3c3cc99de72..26610337d0d 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Copyright (c) 2013, 2014, Fusion-io
This program is free software; you can redistribute it and/or modify it under
@@ -449,18 +449,9 @@ buf_flush_insert_into_flush_list(
incr_flush_list_size_in_bytes(block, buf_pool);
-#ifdef UNIV_DEBUG_VALGRIND
- void* p;
-
- if (block->page.size.is_compressed()) {
- p = block->page.zip.data;
- } else {
- p = block->frame;
- }
-
- UNIV_MEM_ASSERT_RW(p, block->page.size.physical());
-#endif /* UNIV_DEBUG_VALGRIND */
-
+ MEM_CHECK_DEFINED(block->page.size.is_compressed()
+ ? block->page.zip.data : block->frame,
+ block->page.size.physical());
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(buf_flush_validate_skip(buf_pool));
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
@@ -510,17 +501,9 @@ buf_flush_insert_sorted_into_flush_list(
ut_d(block->page.in_flush_list = TRUE);
block->page.oldest_modification = lsn;
-#ifdef UNIV_DEBUG_VALGRIND
- void* p;
-
- if (block->page.size.is_compressed()) {
- p = block->page.zip.data;
- } else {
- p = block->frame;
- }
-
- UNIV_MEM_ASSERT_RW(p, block->page.size.physical());
-#endif /* UNIV_DEBUG_VALGRIND */
+ MEM_CHECK_DEFINED(block->page.size.is_compressed()
+ ? block->page.zip.data : block->frame,
+ block->page.size.physical());
prev_b = NULL;
@@ -578,18 +561,11 @@ buf_flush_ready_for_replace(
#endif /* UNIV_DEBUG */
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_ad(bpage->in_LRU_list);
+ ut_a(buf_page_in_file(bpage));
- if (buf_page_in_file(bpage)) {
-
- return(bpage->oldest_modification == 0
- && bpage->buf_fix_count == 0
- && buf_page_get_io_fix(bpage) == BUF_IO_NONE);
- }
-
- ib::fatal() << "Buffer block " << bpage << " state " << bpage->state
- << " in the LRU list!";
-
- return(FALSE);
+ return bpage->oldest_modification == 0
+ && bpage->buf_fix_count == 0
+ && buf_page_get_io_fix(bpage) == BUF_IO_NONE;
}
/********************************************************************//**
@@ -1069,10 +1045,8 @@ buf_flush_write_block_low(
case BUF_BLOCK_ZIP_DIRTY:
frame = bpage->zip.data;
- mach_write_to_8(frame + FIL_PAGE_LSN,
- bpage->newest_modification);
-
- ut_a(page_zip_verify_checksum(frame, bpage->size.physical()));
+ buf_flush_update_zip_checksum(frame, bpage->size.physical(),
+ bpage->newest_modification);
break;
case BUF_BLOCK_FILE_PAGE:
frame = bpage->zip.data;
@@ -1417,9 +1391,11 @@ buf_flush_try_neighbors(
}
}
- const ulint space_size = fil_space_get_size(page_id.space());
- if (high > space_size) {
- high = space_size;
+ if (fil_space_t *s = fil_space_acquire_for_io(page_id.space())) {
+ high = s->max_page_number_for_io(high);
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
}
DBUG_PRINT("ib_buf", ("flush %u:%u..%u",
@@ -3159,7 +3135,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
ulint last_activity = srv_get_activity_count();
ulint last_pages = 0;
- while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
+ while (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
ulint curr_time = ut_time_ms();
/* The page_cleaner skips sleep if the server is
@@ -3177,7 +3153,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
ret_sleep = 0;
}
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
break;
}
@@ -3344,7 +3320,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
ut_d(buf_flush_page_cleaner_disabled_loop());
}
- ut_ad(srv_shutdown_state > 0);
+ ut_ad(srv_shutdown_state > SRV_SHUTDOWN_INITIATED);
if (srv_fast_shutdown == 2
|| srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
/* In very fast shutdown or when innodb failed to start, we
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 8673c8d9d72..290bb1a737e 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -62,6 +62,7 @@ static const ulint BUF_LRU_OLD_TOLERANCE = 20;
# error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN"
#endif
+#ifdef BTR_CUR_HASH_ADAPT
/** When dropping the search hash index entries before deleting an ibd
file, we build a local array of pages belonging to that tablespace
in the buffer pool. Following is the size of that array.
@@ -70,6 +71,7 @@ flush_list when dropping a table. This is to ensure that other threads
are not blocked for extended period of time when using very large
buffer pools. */
static const ulint BUF_LRU_DROP_SEARCH_SIZE = 1024;
+#endif /* BTR_CUR_HASH_ADAPT */
/** We scan these many blocks when looking for a clean page to evict
during LRU eviction. */
@@ -220,167 +222,6 @@ buf_LRU_evict_from_unzip_LRU(
}
#ifdef BTR_CUR_HASH_ADAPT
-/** Attempts to drop page hash index on a batch of pages belonging to a
-particular space id.
-@param[in] space_id space id
-@param[in] arr array of page_no
-@param[in] count number of entries in array */
-static
-void
-buf_LRU_drop_page_hash_batch(ulint space_id, const ulint* arr, ulint count)
-{
- ut_ad(count <= BUF_LRU_DROP_SEARCH_SIZE);
-
- for (const ulint* const end = arr + count; arr != end; ) {
- /* While our only caller
- buf_LRU_drop_page_hash_for_tablespace()
- is being executed for DROP TABLE or similar,
- the table cannot be evicted from the buffer pool. */
- btr_search_drop_page_hash_when_freed(
- page_id_t(space_id, *arr++));
- }
-}
-
-/******************************************************************//**
-When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page
-hash index entries belonging to that table. This function tries to
-do that in batch. Note that this is a 'best effort' attempt and does
-not guarantee that ALL hash entries will be removed. */
-static
-void
-buf_LRU_drop_page_hash_for_tablespace(
-/*==================================*/
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
- ulint id) /*!< in: space id */
-{
- ulint* page_arr = static_cast<ulint*>(ut_malloc_nokey(
- sizeof(ulint) * BUF_LRU_DROP_SEARCH_SIZE));
-
- ulint num_entries = 0;
-
- buf_pool_mutex_enter(buf_pool);
-
-scan_again:
- for (buf_page_t* bpage = UT_LIST_GET_LAST(buf_pool->LRU);
- bpage != NULL;
- /* No op */) {
-
- buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
-
- ut_a(buf_page_in_file(bpage));
-
- if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
- || bpage->id.space() != id
- || bpage->io_fix != BUF_IO_NONE) {
- /* Compressed pages are never hashed.
- Skip blocks of other tablespaces.
- Skip I/O-fixed blocks (to be dealt with later). */
-next_page:
- bpage = prev_bpage;
- continue;
- }
-
- buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
-
- mutex_enter(&block->mutex);
-
- /* This debug check uses a dirty read that could
- theoretically cause false positives while
- buf_pool_clear_hash_index() is executing.
- (Other conflicting access paths to the adaptive hash
- index should not be possible, because when a
- tablespace is being discarded or dropped, there must
- be no concurrect access to the contained tables.) */
- assert_block_ahi_valid(block);
-
- bool skip = bpage->buf_fix_count > 0 || !block->index;
-
- mutex_exit(&block->mutex);
-
- if (skip) {
- /* Skip this block, because there are
- no adaptive hash index entries
- pointing to it, or because we cannot
- drop them due to the buffer-fix. */
- goto next_page;
- }
-
- /* Store the page number so that we can drop the hash
- index in a batch later. */
- page_arr[num_entries] = bpage->id.page_no();
- ut_a(num_entries < BUF_LRU_DROP_SEARCH_SIZE);
- ++num_entries;
-
- if (num_entries < BUF_LRU_DROP_SEARCH_SIZE) {
- goto next_page;
- }
-
- /* Array full. We release the buf_pool->mutex to obey
- the latching order. */
- buf_pool_mutex_exit(buf_pool);
-
- buf_LRU_drop_page_hash_batch(id, page_arr, num_entries);
-
- num_entries = 0;
-
- buf_pool_mutex_enter(buf_pool);
-
- /* Note that we released the buf_pool mutex above
- after reading the prev_bpage during processing of a
- page_hash_batch (i.e.: when the array was full).
- Because prev_bpage could belong to a compressed-only
- block, it may have been relocated, and thus the
- pointer cannot be trusted. Because bpage is of type
- buf_block_t, it is safe to dereference.
-
- bpage can change in the LRU list. This is OK because
- this function is a 'best effort' to drop as many
- search hash entries as possible and it does not
- guarantee that ALL such entries will be dropped. */
-
- /* If, however, bpage has been removed from LRU list
- to the free list then we should restart the scan.
- bpage->state is protected by buf_pool mutex. */
- if (bpage != NULL
- && buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
-
- goto scan_again;
- }
- }
-
- buf_pool_mutex_exit(buf_pool);
-
- /* Drop any remaining batch of search hashed pages. */
- buf_LRU_drop_page_hash_batch(id, page_arr, num_entries);
- ut_free(page_arr);
-}
-
-/** Try to drop the adaptive hash index for a tablespace.
-@param[in,out] table table
-@return whether anything was dropped */
-bool buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table)
-{
- for (dict_index_t* index = dict_table_get_first_index(table);
- index != NULL;
- index = dict_table_get_next_index(index)) {
- if (btr_search_info_get_ref_count(btr_search_get_info(index),
- index)) {
- goto drop_ahi;
- }
- }
-
- return false;
-drop_ahi:
- ulint id = table->space;
- for (ulint i = 0; i < srv_buf_pool_instances; i++) {
- buf_LRU_drop_page_hash_for_tablespace(buf_pool_from_array(i),
- id);
- }
-
- return true;
-}
-#endif /* BTR_CUR_HASH_ADAPT */
-
/******************************************************************//**
While flushing (or removing dirty) pages from a tablespace we don't
want to hog the CPU and resources. Release the buffer pool and block
@@ -468,6 +309,7 @@ buf_flush_try_yield(
return(false);
}
+#endif /* BTR_CUR_HASH_ADAPT */
/******************************************************************//**
Removes a single page from a given tablespace inside a specific
@@ -643,6 +485,7 @@ rescan:
goto rescan;
}
+#ifdef BTR_CUR_HASH_ADAPT
++processed;
/* Yield if we have hogged the CPU and mutexes for too long. */
@@ -652,6 +495,7 @@ rescan:
processed = 0;
}
+#endif /* BTR_CUR_HASH_ADAPT */
/* The check for trx is interrupted is expensive, we want
to check every N iterations. */
@@ -965,7 +809,7 @@ buf_LRU_get_free_only(
assert_block_ahi_empty(block);
buf_block_set_state(block, BUF_BLOCK_READY_FOR_USE);
- UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE);
+ MEM_UNDEFINED(block->frame, srv_page_size);
ut_ad(buf_pool_from_block(block) == buf_pool);
@@ -1020,7 +864,7 @@ buf_LRU_check_size_of_non_data_objects(
+ UT_LIST_GET_LEN(buf_pool->LRU))
< buf_pool->curr_size / 3) {
- if (!buf_lru_switched_on_innodb_mon) {
+ if (!buf_lru_switched_on_innodb_mon && srv_monitor_event) {
/* Over 67 % of the buffer pool is occupied by lock
heaps or the adaptive hash index. This may be a memory
@@ -1110,7 +954,6 @@ loop:
ut_ad(buf_pool_from_block(block) == buf_pool);
memset(&block->page.zip, 0, sizeof block->page.zip);
- block->skip_flush_check = false;
block->page.flush_observer = NULL;
return(block);
}
@@ -1660,8 +1503,6 @@ func_exit:
ut_ad(b->size.is_compressed());
- UNIV_MEM_DESC(b->zip.data, b->size.physical());
-
/* The fields in_page_hash and in_LRU_list of
the to-be-freed block descriptor should have
been cleared in
@@ -1765,38 +1606,20 @@ func_exit:
The page was declared uninitialized by
buf_LRU_block_remove_hashed(). We need to flag
the contents of the page valid (which it still is) in
- order to avoid bogus Valgrind warnings.*/
-
- UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
- UNIV_PAGE_SIZE);
- btr_search_drop_page_hash_index((buf_block_t*) bpage);
- UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
- UNIV_PAGE_SIZE);
-
- if (b != NULL) {
-
- /* Compute and stamp the compressed page
- checksum while not holding any mutex. The
- block is already half-freed
- (BUF_BLOCK_REMOVE_HASH) and removed from
- buf_pool->page_hash, thus inaccessible by any
- other thread. */
+ order to avoid bogus Valgrind or MSAN warnings.*/
+ buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
- ut_ad(b->size.is_compressed());
-
- const uint32_t checksum = page_zip_calc_checksum(
- b->zip.data,
- b->size.physical(),
- static_cast<srv_checksum_algorithm_t>(
- srv_checksum_algorithm));
-
- mach_write_to_4(b->zip.data + FIL_PAGE_SPACE_OR_CHKSUM,
- checksum);
- }
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_MAKE_DEFINED(block->frame, srv_page_size);
+#endif /* HAVE_valgrind_or_MSAN */
+ btr_search_drop_page_hash_index(block);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(block->frame, srv_page_size);
+#endif /* HAVE_valgrind_or_MSAN */
buf_pool_mutex_enter(buf_pool);
- if (b != NULL) {
+ if (b) {
mutex_enter(block_mutex);
buf_page_unset_sticky(b);
@@ -1804,7 +1627,7 @@ func_exit:
mutex_exit(block_mutex);
}
- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
+ buf_LRU_block_free_hashed_page(block);
return(true);
}
@@ -1837,15 +1660,10 @@ buf_LRU_block_free_non_file_page(
buf_block_set_state(block, BUF_BLOCK_NOT_USED);
- UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE);
-#ifdef UNIV_DEBUG
- /* Wipe contents of page to reveal possible stale pointers to it */
- memset(block->frame, '\0', UNIV_PAGE_SIZE);
-#else
+ MEM_UNDEFINED(block->frame, srv_page_size);
/* Wipe page_no and space_id */
memset(block->frame + FIL_PAGE_OFFSET, 0xfe, 4);
memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xfe, 4);
-#endif /* UNIV_DEBUG */
data = block->page.zip.data;
if (data != NULL) {
@@ -1881,7 +1699,7 @@ buf_LRU_block_free_non_file_page(
ut_d(block->page.in_free_list = TRUE);
}
- UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
+ MEM_NOACCESS(block->frame, srv_page_size);
}
/******************************************************************//**
@@ -1928,9 +1746,9 @@ buf_LRU_block_remove_hashed(
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_FILE_PAGE:
- UNIV_MEM_ASSERT_W(bpage, sizeof(buf_block_t));
- UNIV_MEM_ASSERT_W(((buf_block_t*) bpage)->frame,
- UNIV_PAGE_SIZE);
+ MEM_CHECK_ADDRESSABLE(bpage, sizeof(buf_block_t));
+ MEM_CHECK_ADDRESSABLE(((buf_block_t*) bpage)->frame,
+ srv_page_size);
buf_block_modify_clock_inc((buf_block_t*) bpage);
if (bpage->zip.data) {
const page_t* page = ((buf_block_t*) bpage)->frame;
@@ -1986,8 +1804,8 @@ buf_LRU_block_remove_hashed(
case BUF_BLOCK_ZIP_PAGE:
ut_a(bpage->oldest_modification == 0);
if (bpage->size.is_compressed()) {
- UNIV_MEM_ASSERT_W(bpage->zip.data,
- bpage->size.physical());
+ MEM_CHECK_ADDRESSABLE(bpage->zip.data,
+ bpage->size.physical());
}
break;
case BUF_BLOCK_POOL_WATCH:
@@ -2001,46 +1819,9 @@ buf_LRU_block_remove_hashed(
}
hashed_bpage = buf_page_hash_get_low(buf_pool, bpage->id);
- if (bpage != hashed_bpage) {
- ib::error() << "Page " << bpage->id
- << " not found in the hash table";
-
-#ifdef UNIV_DEBUG
-
-
- ib::error()
- << "in_page_hash:" << bpage->in_page_hash
- << " in_zip_hash:" << bpage->in_zip_hash
- // << " in_free_list:"<< bpage->in_fee_list
- << " in_flush_list:" << bpage->in_flush_list
- << " in_LRU_list:" << bpage->in_LRU_list
- << " zip.data:" << bpage->zip.data
- << " zip_size:" << bpage->size.logical()
- << " page_state:" << buf_page_get_state(bpage);
-#else
- ib::error()
- << " zip.data:" << bpage->zip.data
- << " zip_size:" << bpage->size.logical()
- << " page_state:" << buf_page_get_state(bpage);
-#endif
-
- if (hashed_bpage) {
-
- ib::error() << "In hash table we find block "
- << hashed_bpage << " of " << hashed_bpage->id
- << " which is not " << bpage;
- }
-
-#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- mutex_exit(buf_page_get_mutex(bpage));
- rw_lock_x_unlock(hash_lock);
- buf_pool_mutex_exit(buf_pool);
- buf_print();
- buf_LRU_print();
- buf_validate();
- buf_LRU_validate();
-#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
- ut_error;
+ if (UNIV_UNLIKELY(bpage != hashed_bpage)) {
+ ib::fatal() << "Page not found in the hash table: "
+ << bpage->id;
}
ut_ad(!bpage->in_zip_hash);
@@ -2078,8 +1859,7 @@ buf_LRU_block_remove_hashed(
+ FIL_PAGE_OFFSET, 0xff, 4);
memset(((buf_block_t*) bpage)->frame
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
- UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
- UNIV_PAGE_SIZE);
+ MEM_UNDEFINED(((buf_block_t*) bpage)->frame, srv_page_size);
buf_page_set_state(bpage, BUF_BLOCK_REMOVE_HASH);
/* Question: If we release bpage and hash mutex here
diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index e25c0e853e4..ad583e577c4 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -279,31 +279,8 @@ buf_read_ahead_random(
high = (page_id.page_no() / buf_read_ahead_random_area + 1)
* buf_read_ahead_random_area;
- /* Remember the tablespace version before we ask the tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
if (fil_space_t* space = fil_space_acquire(page_id.space())) {
-
-#ifdef UNIV_DEBUG
- if (srv_file_per_table) {
- ulint size = 0;
-
- for (const fil_node_t* node =
- UT_LIST_GET_FIRST(space->chain);
- node != NULL;
- node = UT_LIST_GET_NEXT(chain, node)) {
-
- size += ulint(os_file_get_size(node->handle)
- / page_size.physical());
- }
-
- ut_ad(size == space->size);
- }
-#endif /* UNIV_DEBUG */
-
- if (high > space->size) {
- high = space->size;
- }
+ high = space->max_page_number_for_io(high);
fil_space_release(space);
} else {
return(0);
@@ -580,13 +557,10 @@ buf_read_ahead_linear(
return(0);
}
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
ulint space_size;
if (fil_space_t* space = fil_space_acquire(page_id.space())) {
- space_size = space->size;
+ space_size = space->committed_size;
fil_space_release(space);
if (high > space_size) {
@@ -925,8 +899,12 @@ buf_read_recv_pages(
ulint count = 0;
buf_pool = buf_pool_get(cur_page_id);
- while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) {
+ ulint limit = 0;
+ for (ulint j = 0; j < buf_pool->n_chunks; j++) {
+ limit += buf_pool->chunks[j].size / 2;
+ }
+ while (buf_pool->n_pend_reads >= limit) {
os_aio_simulated_wake_handler_threads();
os_thread_sleep(10000);
diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc
index 17126e38e42..fba06e78987 100644
--- a/storage/innobase/data/data0data.cc
+++ b/storage/innobase/data/data0data.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -194,41 +194,20 @@ dtuple_validate(
/*============*/
const dtuple_t* tuple) /*!< in: tuple */
{
- const dfield_t* field;
- ulint n_fields;
- ulint len;
- ulint i;
-
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
+#ifdef HAVE_valgrind_or_MSAN
+ const ulint n_fields = dtuple_get_n_fields(tuple);
- n_fields = dtuple_get_n_fields(tuple);
-
- /* We dereference all the data of each field to test
- for memory traps */
-
- for (i = 0; i < n_fields; i++) {
-
- field = dtuple_get_nth_field(tuple, i);
- len = dfield_get_len(field);
+ for (ulint i = 0; i < n_fields; i++) {
+ const dfield_t* field = dtuple_get_nth_field(tuple, i);
if (!dfield_is_null(field)) {
-
- const byte* data;
-
- data = static_cast<const byte*>(dfield_get_data(field));
-#ifndef UNIV_DEBUG_VALGRIND
- ulint j;
-
- for (j = 0; j < len; j++) {
- data++;
- }
-#endif /* !UNIV_DEBUG_VALGRIND */
-
- UNIV_MEM_ASSERT_RW(data, len);
+ MEM_CHECK_DEFINED(dfield_get_data(field),
+ dfield_get_len(field));
}
}
-
- ut_a(dtuple_check_typed(tuple));
+#endif /* HAVE_valgrind_or_MSAN */
+ ut_ad(dtuple_check_typed(tuple));
return(TRUE);
}
@@ -683,14 +662,6 @@ skip_field:
memcpy(data, dfield_get_data(dfield), local_prefix_len);
/* Clear the extern field reference (BLOB pointer). */
memset(data + local_prefix_len, 0, BTR_EXTERN_FIELD_REF_SIZE);
-#if 0
- /* The following would fail the Valgrind checks in
- page_cur_insert_rec_low() and page_cur_insert_rec_zip().
- The BLOB pointers in the record will be initialized after
- the record and the BLOBs have been written. */
- UNIV_MEM_ALLOC(data + local_prefix_len,
- BTR_EXTERN_FIELD_REF_SIZE);
-#endif
dfield_set_data(dfield, data, local_len);
dfield_set_ext(dfield);
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index 9294cf6263c..8e4732f8214 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -179,7 +179,7 @@ dict_hdr_create(
/* Create the dictionary header file block in a new, allocated file
segment in the system tablespace */
- block = fseg_create(DICT_HDR_SPACE, 0,
+ block = fseg_create(DICT_HDR_SPACE,
DICT_HDR + DICT_HDR_FSEG_HEADER, mtr);
ut_a(DICT_HDR_PAGE_NO == block->page.id.page_no());
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 4ef87dae22d..2976581c19f 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -26,7 +26,9 @@ Created 1/8/1996 Heikki Tuuri
#include "dict0crea.h"
#include "btr0pcur.h"
-#include "btr0btr.h"
+#ifdef BTR_CUR_HASH_ADAPT
+# include "btr0sea.h"
+#endif /* BTR_CUR_HASH_ADAPT */
#include "page0page.h"
#include "mach0data.h"
#include "dict0boot.h"
@@ -1528,6 +1530,9 @@ dict_create_index_step(
&node->table->fts->cache->init_lock);
}
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!node->index->search_info->ref_count);
+#endif /* BTR_CUR_HASH_ADAPT */
dict_index_remove_from_cache(node->table, node->index);
node->index = NULL;
@@ -1714,10 +1719,9 @@ dict_create_or_check_foreign_constraint_tables(void)
"END;\n",
FALSE, trx);
- if (err != DB_SUCCESS) {
-
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::error() << "Creation of SYS_FOREIGN and SYS_FOREIGN_COLS"
- " failed: " << ut_strerr(err) << ". Tablespace is"
+ " failed: " << err << ". Tablespace is"
" full. Dropping incompletely created tables.";
ut_ad(err == DB_OUT_OF_FILE_SPACE
@@ -1816,10 +1820,9 @@ dict_create_or_check_sys_virtual()
"END;\n",
FALSE, trx);
- if (err != DB_SUCCESS) {
-
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::error() << "Creation of SYS_VIRTUAL"
- " failed: " << ut_strerr(err) << ". Tablespace is"
+ " failed: " << err << ". Tablespace is"
" full or too many transactions."
" Dropping incompletely created tables.";
@@ -1897,9 +1900,9 @@ dict_foreign_eval_sql(
return(error);
}
- if (error != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
ib::error() << "Foreign key constraint creation failed: "
- << ut_strerr(error);
+ << error;
mutex_enter(&dict_foreign_err_mutex);
ut_print_timestamp(ef);
@@ -2348,10 +2351,9 @@ dict_create_or_check_sys_tablespace(void)
"END;\n",
FALSE, trx);
- if (err != DB_SUCCESS) {
-
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::error() << "Creation of SYS_TABLESPACES and SYS_DATAFILES"
- " has failed with error " << ut_strerr(err)
+ " has failed with error " << err
<< ". Dropping incompletely created tables.";
ut_a(err == DB_OUT_OF_FILE_SPACE
@@ -2460,49 +2462,6 @@ dict_replace_tablespace_in_dictionary(
return(error);
}
-/** Delete records from SYS_TABLESPACES and SYS_DATAFILES associated
-with a particular tablespace ID.
-@param[in] space Tablespace ID
-@param[in,out] trx Current transaction
-@return DB_SUCCESS if OK, dberr_t if the operation failed */
-
-dberr_t
-dict_delete_tablespace_and_datafiles(
- ulint space,
- trx_t* trx)
-{
- dberr_t err = DB_SUCCESS;
-
- ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys->mutex));
- ut_ad(srv_sys_tablespaces_open);
-
- trx->op_info = "delete tablespace and datafiles from dictionary";
-
- pars_info_t* info = pars_info_create();
- ut_a(!is_system_tablespace(space));
- pars_info_add_int4_literal(info, "space", space);
-
- err = que_eval_sql(info,
- "PROCEDURE P () IS\n"
- "BEGIN\n"
- "DELETE FROM SYS_TABLESPACES\n"
- "WHERE SPACE = :space;\n"
- "DELETE FROM SYS_DATAFILES\n"
- "WHERE SPACE = :space;\n"
- "END;\n",
- FALSE, trx);
-
- if (err != DB_SUCCESS) {
- ib::warn() << "Could not delete space_id "
- << space << " from data dictionary";
- }
-
- trx->op_info = "";
-
- return(err);
-}
-
/** Assign a new table ID and put it into the table cache and the transaction.
@param[in,out] table Table that needs an ID
@param[in,out] trx Transaction */
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 4b1549c419d..37a8a4387d1 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -60,7 +60,6 @@ extern uint ibuf_debug;
#include "lock0lock.h"
#include "mach0data.h"
#include "mem0mem.h"
-#include "os0once.h"
#include "page0page.h"
#include "page0zip.h"
#include "pars0pars.h"
@@ -268,76 +267,6 @@ dict_mutex_exit_for_mysql(void)
mutex_exit(&dict_sys->mutex);
}
-/** Allocate and init a dict_table_t's stats latch.
-This function must not be called concurrently on the same table object.
-@param[in,out] table_void table whose stats latch to create */
-static
-void
-dict_table_stats_latch_alloc(
- void* table_void)
-{
- dict_table_t* table = static_cast<dict_table_t*>(table_void);
-
- /* Note: rw_lock_create() will call the constructor */
-
- table->stats_latch = static_cast<rw_lock_t*>(
- ut_malloc_nokey(sizeof(rw_lock_t)));
-
- ut_a(table->stats_latch != NULL);
-
- rw_lock_create(dict_table_stats_key, table->stats_latch,
- SYNC_INDEX_TREE);
-}
-
-/** Deinit and free a dict_table_t's stats latch.
-This function must not be called concurrently on the same table object.
-@param[in,out] table table whose stats latch to free */
-static
-void
-dict_table_stats_latch_free(
- dict_table_t* table)
-{
- rw_lock_free(table->stats_latch);
- ut_free(table->stats_latch);
-}
-
-/** Create a dict_table_t's stats latch or delay for lazy creation.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to create
-@param[in] enabled if false then the latch is disabled
-and dict_table_stats_lock()/unlock() become noop on this table. */
-void
-dict_table_stats_latch_create(
- dict_table_t* table,
- bool enabled)
-{
- if (!enabled) {
- table->stats_latch = NULL;
- table->stats_latch_created = os_once::DONE;
- return;
- }
-
- /* We create this lazily the first time it is used. */
- table->stats_latch = NULL;
- table->stats_latch_created = os_once::NEVER_DONE;
-}
-
-/** Destroy a dict_table_t's stats latch.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to destroy */
-void
-dict_table_stats_latch_destroy(
- dict_table_t* table)
-{
- if (table->stats_latch_created == os_once::DONE
- && table->stats_latch != NULL) {
-
- dict_table_stats_latch_free(table);
- }
-}
-
/** Lock the appropriate latch to protect a given table's statistics.
@param[in] table table whose stats to lock
@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
@@ -349,23 +278,12 @@ dict_table_stats_lock(
ut_ad(table != NULL);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
- os_once::do_or_wait_for_done(
- &table->stats_latch_created,
- dict_table_stats_latch_alloc, table);
-
- if (table->stats_latch == NULL) {
- /* This is a dummy table object that is private in the current
- thread and is not shared between multiple threads, thus we
- skip any locking. */
- return;
- }
-
switch (latch_mode) {
case RW_S_LATCH:
- rw_lock_s_lock(table->stats_latch);
+ rw_lock_s_lock(&table->stats_latch);
break;
case RW_X_LATCH:
- rw_lock_x_lock(table->stats_latch);
+ rw_lock_x_lock(&table->stats_latch);
break;
case RW_NO_LATCH:
/* fall through */
@@ -385,19 +303,12 @@ dict_table_stats_unlock(
ut_ad(table != NULL);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
- if (table->stats_latch == NULL) {
- /* This is a dummy table object that is private in the current
- thread and is not shared between multiple threads, thus we
- skip any locking. */
- return;
- }
-
switch (latch_mode) {
case RW_S_LATCH:
- rw_lock_s_unlock(table->stats_latch);
+ rw_lock_s_unlock(&table->stats_latch);
break;
case RW_X_LATCH:
- rw_lock_x_unlock(table->stats_latch);
+ rw_lock_x_unlock(&table->stats_latch);
break;
case RW_NO_LATCH:
/* fall through */
@@ -528,7 +439,10 @@ dict_table_close(
mutex_exit(&dict_sys->mutex);
- if (drop_aborted) {
+ /* dict_table_try_drop_aborted() can generate undo logs.
+ So it should be avoided after shutdown of background
+ threads */
+ if (drop_aborted && !srv_undo_sources) {
dict_table_try_drop_aborted(NULL, table_id, 0);
}
}
@@ -734,34 +648,6 @@ dict_table_get_nth_v_col_mysql(
return(dict_table_get_nth_v_col(table, i));
}
-/** Allocate and init the autoinc latch of a given table.
-This function must not be called concurrently on the same table object.
-@param[in,out] table_void table whose autoinc latch to create */
-static
-void
-dict_table_autoinc_alloc(
- void* table_void)
-{
- dict_table_t* table = static_cast<dict_table_t*>(table_void);
- table->autoinc_mutex = UT_NEW_NOKEY(ib_mutex_t());
- ut_a(table->autoinc_mutex != NULL);
- mutex_create(LATCH_ID_AUTOINC, table->autoinc_mutex);
-}
-
-/** Allocate and init the zip_pad_mutex of a given index.
-This function must not be called concurrently on the same index object.
-@param[in,out] index_void index whose zip_pad_mutex to create */
-static
-void
-dict_index_zip_pad_alloc(
- void* index_void)
-{
- dict_index_t* index = static_cast<dict_index_t*>(index_void);
- index->zip_pad.mutex = UT_NEW_NOKEY(SysMutex());
- ut_a(index->zip_pad.mutex != NULL);
- mutex_create(LATCH_ID_ZIP_PAD_MUTEX, index->zip_pad.mutex);
-}
-
/********************************************************************//**
Acquire the autoinc lock. */
void
@@ -769,11 +655,7 @@ dict_table_autoinc_lock(
/*====================*/
dict_table_t* table) /*!< in/out: table */
{
- os_once::do_or_wait_for_done(
- &table->autoinc_mutex_created,
- dict_table_autoinc_alloc, table);
-
- mutex_enter(table->autoinc_mutex);
+ mysql_mutex_lock(&table->autoinc_mutex);
}
/** Acquire the zip_pad_mutex latch.
@@ -783,11 +665,7 @@ void
dict_index_zip_pad_lock(
dict_index_t* index)
{
- os_once::do_or_wait_for_done(
- &index->zip_pad.mutex_created,
- dict_index_zip_pad_alloc, index);
-
- mutex_enter(index->zip_pad.mutex);
+ mysql_mutex_lock(&index->zip_pad.mutex);
}
/** Get all the FTS indexes on a table.
@@ -822,7 +700,7 @@ dict_table_autoinc_unlock(
/*======================*/
dict_table_t* table) /*!< in/out: table */
{
- mutex_exit(table->autoinc_mutex);
+ mysql_mutex_unlock(&table->autoinc_mutex);
}
/** Looks for column n in an index.
@@ -1273,6 +1151,8 @@ dict_table_add_to_cache(
dict_table_add_system_columns(table, heap);
+ mysql_mutex_init(0, &table->autoinc_mutex, NULL);
+
table->cached = TRUE;
fold = ut_fold_string(table->name.m_name);
@@ -1358,25 +1238,12 @@ dict_table_can_be_evicted(
}
#ifdef BTR_CUR_HASH_ADAPT
+ /* We cannot really evict the table if adaptive hash
+ index entries are pointing to any of its indexes. */
for (dict_index_t* index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
-
- btr_search_t* info = btr_search_get_info(index);
-
- /* We are not allowed to free the in-memory index
- struct dict_index_t until all entries in the adaptive
- hash index that point to any of the page belonging to
- his b-tree index are dropped. This is so because
- dropping of these entries require access to
- dict_index_t struct. To avoid such scenario we keep
- a count of number of such pages in the search_info and
- only free the dict_index_t struct when this count
- drops to zero.
-
- See also: dict_index_remove_from_cache_low() */
-
- if (btr_search_info_get_ref_count(info, index) > 0) {
+ if (index->n_ahi_pages()) {
return(FALSE);
}
}
@@ -1388,6 +1255,71 @@ dict_table_can_be_evicted(
return(FALSE);
}
+#ifdef BTR_CUR_HASH_ADAPT
+/** @return a clone of this */
+dict_index_t *dict_index_t::clone() const
+{
+ ut_ad(n_fields);
+ ut_ad(!(type & (DICT_IBUF | DICT_SPATIAL | DICT_FTS)));
+ ut_ad(online_status == ONLINE_INDEX_COMPLETE);
+ ut_ad(is_committed());
+ ut_ad(!is_dummy);
+ ut_ad(!parser);
+ ut_ad(!index_fts_syncing);
+ ut_ad(!online_log);
+ ut_ad(!rtr_track);
+
+ const size_t size= sizeof *this + n_fields * sizeof(*fields) +
+#ifdef BTR_CUR_ADAPT
+ sizeof *search_info +
+#endif
+ 1 + strlen(name) +
+ n_uniq * (sizeof *stat_n_diff_key_vals +
+ sizeof *stat_n_sample_sizes +
+ sizeof *stat_n_non_null_key_vals);
+
+ mem_heap_t* heap= mem_heap_create(size);
+ dict_index_t *index= static_cast<dict_index_t*>(mem_heap_dup(heap, this,
+ sizeof *this));
+ *index= *this;
+ rw_lock_create(index_tree_rw_lock_key, &index->lock, SYNC_INDEX_TREE);
+ index->heap= heap;
+ index->name= mem_heap_strdup(heap, name);
+ index->fields= static_cast<dict_field_t*>
+ (mem_heap_dup(heap, fields, n_fields * sizeof *fields));
+#ifdef BTR_CUR_ADAPT
+ index->search_info= btr_search_info_create(index->heap);
+#endif /* BTR_CUR_ADAPT */
+ index->stat_n_diff_key_vals= static_cast<ib_uint64_t*>
+ (mem_heap_zalloc(heap, n_uniq * sizeof *stat_n_diff_key_vals));
+ index->stat_n_sample_sizes= static_cast<ib_uint64_t*>
+ (mem_heap_zalloc(heap, n_uniq * sizeof *stat_n_sample_sizes));
+ index->stat_n_non_null_key_vals= static_cast<ib_uint64_t*>
+ (mem_heap_zalloc(heap, n_uniq * sizeof *stat_n_non_null_key_vals));
+ mysql_mutex_init(0, &index->zip_pad.mutex, NULL);
+ return index;
+}
+
+/** Clone this index for lazy dropping of the adaptive hash.
+@return this or a clone */
+dict_index_t *dict_index_t::clone_if_needed()
+{
+ if (!search_info->ref_count)
+ return this;
+ dict_index_t *prev= UT_LIST_GET_PREV(indexes, this);
+
+ UT_LIST_REMOVE(table->indexes, this);
+ UT_LIST_ADD_LAST(table->freed_indexes, this);
+ dict_index_t *index= clone();
+ set_freed();
+ if (prev)
+ UT_LIST_INSERT_AFTER(table->indexes, prev, index);
+ else
+ UT_LIST_ADD_FIRST(table->indexes, index);
+ return index;
+}
+#endif /* BTR_CUR_HASH_ADAPT */
+
/**********************************************************************//**
Make room in the table cache by evicting an unused table. The unused table
should not be part of FK relationship and currently not used in any user
@@ -1627,7 +1559,8 @@ dict_table_rename_in_cache(
return(DB_OUT_OF_MEMORY);
}
- fil_delete_tablespace(table->space);
+ fil_delete_tablespace(table->space,
+ dict_table_is_discarded(table));
/* Delete any temp file hanging around. */
if (os_file_status(filepath, &exists, &ftype)
@@ -2077,6 +2010,21 @@ dict_table_remove_from_cache_low(
UT_DELETE(table->vc_templ);
}
+ mysql_mutex_destroy(&table->autoinc_mutex);
+#ifdef BTR_CUR_HASH_ADAPT
+ if (UNIV_UNLIKELY(UT_LIST_GET_LEN(table->freed_indexes) != 0)) {
+ if (table->fts) {
+ fts_optimize_remove_table(table);
+ fts_free(table);
+ table->fts = NULL;
+ }
+
+ table->vc_templ = NULL;
+ table->id = 0;
+ return;
+ }
+#endif /* BTR_CUR_HASH_ADAPT */
+
dict_mem_table_free(table);
}
@@ -2136,7 +2084,7 @@ dict_index_remove_from_v_col_list(dict_index_t* index) {
for (ulint i = 0; i < dict_index_get_n_fields(index); i++) {
col = dict_index_get_nth_col(index, i);
- if (dict_col_is_virtual(col)) {
+ if (col && col->is_virtual()) {
vcol = reinterpret_cast<const dict_v_col_t*>(
col);
/* This could be NULL, when we do add
@@ -2306,6 +2254,10 @@ dict_index_remove_from_cache_low(
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&dict_sys->mutex));
+ ut_ad(table->id);
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!index->freed());
+#endif /* BTR_CUR_HASH_ADAPT */
/* No need to acquire the dict_index_t::lock here because
there can't be any active operations on this index (or table). */
@@ -2315,13 +2267,22 @@ dict_index_remove_from_cache_low(
row_log_free(index->online_log);
}
+ /* Remove the index from the list of indexes of the table */
+ UT_LIST_REMOVE(table->indexes, index);
+
+ /* The index is being dropped, remove any compression stats for it. */
+ if (!lru_evict && DICT_TF_GET_ZIP_SSIZE(index->table->flags)) {
+ mutex_enter(&page_zip_stat_per_index_mutex);
+ page_zip_stat_per_index.erase(index->id);
+ mutex_exit(&page_zip_stat_per_index_mutex);
+ }
+
+ /* Remove the index from affected virtual column index list */
+ index->detach_columns();
+
#ifdef BTR_CUR_HASH_ADAPT
/* We always create search info whether or not adaptive
hash index is enabled or not. */
- btr_search_t* info = btr_search_get_info(index);
- ulint retries = 0;
- ut_ad(info);
-
/* We are not allowed to free the in-memory index struct
dict_index_t until all entries in the adaptive hash index
that point to any of the page belonging to his b-tree index
@@ -2331,31 +2292,15 @@ dict_index_remove_from_cache_low(
only free the dict_index_t struct when this count drops to
zero. See also: dict_table_can_be_evicted() */
- do {
- if (!btr_search_info_get_ref_count(info, index)
- || !buf_LRU_drop_page_hash_for_tablespace(table)) {
- break;
- }
-
- ut_a(++retries < 10000);
- } while (srv_shutdown_state == SRV_SHUTDOWN_NONE || !lru_evict);
+ if (index->n_ahi_pages()) {
+ index->set_freed();
+ UT_LIST_ADD_LAST(table->freed_indexes, index);
+ return;
+ }
#endif /* BTR_CUR_HASH_ADAPT */
rw_lock_free(&index->lock);
- /* The index is being dropped, remove any compression stats for it. */
- if (!lru_evict && DICT_TF_GET_ZIP_SSIZE(index->table->flags)) {
- mutex_enter(&page_zip_stat_per_index_mutex);
- page_zip_stat_per_index.erase(index->id);
- mutex_exit(&page_zip_stat_per_index_mutex);
- }
-
- /* Remove the index from the list of indexes of the table */
- UT_LIST_REMOVE(table->indexes, index);
-
- /* Remove the index from affected virtual column index list */
- index->detach_columns();
-
dict_mem_index_free(index);
}
@@ -4955,7 +4900,7 @@ dict_create_foreign_constraints(
heap = mem_heap_create(10000);
err = dict_create_foreign_constraints_low(
- trx, heap, innobase_get_charset(trx->mysql_thd),
+ trx, heap, thd_charset(trx->mysql_thd),
str, name, reject_fks);
mem_heap_free(heap);
@@ -4990,7 +4935,7 @@ dict_foreign_parse_drop_constraints(
ut_a(trx->mysql_thd);
- cs = innobase_get_charset(trx->mysql_thd);
+ cs = thd_charset(trx->mysql_thd);
*n = 0;
@@ -5694,7 +5639,7 @@ dict_set_corrupted(
btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_LE,
BTR_MODIFY_LEAF,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, 0, __FILE__, __LINE__, &mtr, 0);
if (cursor.low_match == dtuple_get_n_fields(tuple)) {
/* UPDATE SYS_INDEXES SET TYPE=index->type
@@ -5743,6 +5688,7 @@ dict_set_corrupted_index_cache_only(
is corrupted */
if (dict_index_is_clust(index)) {
index->table->corrupted = TRUE;
+ index->table->file_unreadable = true;
}
index->type |= DICT_CORRUPT;
@@ -5796,7 +5742,7 @@ dict_index_set_merge_threshold(
btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, 0, __FILE__, __LINE__, &mtr, 0);
if (cursor.up_match == dtuple_get_n_fields(tuple)
&& rec_get_n_fields_old(btr_cur_get_rec(&cursor))
@@ -6547,7 +6493,11 @@ dict_foreign_qualify_index(
return(false);
}
- if (index->type & (DICT_SPATIAL | DICT_FTS)) {
+ if (index->type & (DICT_SPATIAL | DICT_FTS | DICT_CORRUPT)) {
+ return false;
+ }
+
+ if (index->online_status >= ONLINE_INDEX_ABORTED) {
return false;
}
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 8ed947f04cf..22fc70a4e42 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -805,7 +805,7 @@ err_len:
@param[in] space_id Tablespace ID
@return First filepath (caller must invoke ut_free() on it)
@retval NULL if no SYS_DATAFILES entry was found. */
-char*
+static char*
dict_get_first_path(
ulint space_id)
{
@@ -863,7 +863,7 @@ dict_get_first_path(
ut_ad(len > 0);
ut_ad(len < OS_FILE_MAX_PATH);
- if (len > 0 && len != UNIV_SQL_NULL) {
+ if (len > 0 && len < UNIV_SQL_NULL) {
filepath = mem_strdupl(
reinterpret_cast<const char*>(field),
len);
@@ -925,7 +925,7 @@ dict_update_filepath(
trx->dict_operation_lock_mode = 0;
trx_free_for_background(trx);
- if (err == DB_SUCCESS) {
+ if (UNIV_LIKELY(err == DB_SUCCESS)) {
/* We just updated SYS_DATAFILES due to the contents in
a link file. Make a note that we did this. */
ib::info() << "The InnoDB data dictionary table SYS_DATAFILES"
@@ -935,7 +935,7 @@ dict_update_filepath(
ib::warn() << "Error occurred while updating InnoDB data"
" dictionary table SYS_DATAFILES for tablespace ID "
<< space_id << " to file " << filepath << ": "
- << ut_strerr(err) << ".";
+ << err << ".";
}
return(err);
@@ -1388,6 +1388,7 @@ static ulint dict_check_sys_tables()
for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
rec != NULL;
+ mtr.commit(), mtr.start(),
rec = dict_getnext_system(&pcur, &mtr)) {
const byte* field;
ulint len;
@@ -1570,7 +1571,7 @@ dict_load_column_low(
ulint pos;
ulint num_base;
- ut_ad(table || column);
+ ut_ad(!table == !!column);
if (rec_get_deleted_flag(rec, 0)) {
return(dict_load_column_del);
@@ -1677,7 +1678,7 @@ err_len:
}
num_base = mach_read_from_4(field);
- if (column == NULL) {
+ if (table) {
if (prtype & DATA_VIRTUAL) {
#ifdef UNIV_DEBUG
dict_v_col_t* vcol =
@@ -2685,7 +2686,7 @@ static const char* dict_load_table_low(const table_name_t& name,
*table = dict_mem_table_create(
name.m_name, space_id, n_cols + n_v_col, n_v_col, flags, flags2);
(*table)->id = table_id;
- (*table)->file_unreadable = false;
+ (*table)->file_unreadable = !!(flags2 & DICT_TF2_DISCARDED);
return(NULL);
}
@@ -2738,7 +2739,8 @@ dict_get_and_save_data_dir_path(
{
ut_ad(!dict_table_is_temporary(table));
- if (!table->data_dir_path && table->space) {
+ if (!table->data_dir_path && table->space
+ && !dict_table_is_discarded(table)) {
char* path = fil_space_get_first_path(table->space);
if (!dict_mutex_own) {
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index fe01948b70d..11d362d32c6 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -96,20 +96,37 @@ operator<<(
return(s << ut_get_name(NULL, table_name.m_name));
}
-/**********************************************************************//**
-Creates a table memory object.
-@return own: table object */
+/** @return whether a table belongs to a system database */
+static bool dict_mem_table_is_system(char *name)
+{
+ /* table has the following format: database/table
+ and some system table are of the form SYS_* */
+ if (strchr(name, '/')) {
+ size_t table_len = strlen(name);
+ const char *system_db;
+ int i = 0;
+ while ((system_db = innobase_system_databases[i++])
+ && (system_db != NullS)) {
+ size_t len = strlen(system_db);
+ if (table_len > len && !strncmp(name, system_db, len)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return true;
+ }
+}
+
dict_table_t*
dict_mem_table_create(
-/*==================*/
- const char* name, /*!< in: table name */
- ulint space, /*!< in: space where the clustered index of
- the table is placed */
- ulint n_cols, /*!< in: total number of columns including
- virtual and non-virtual columns */
- ulint n_v_cols,/*!< in: number of virtual columns */
- ulint flags, /*!< in: table flags */
- ulint flags2) /*!< in: table flags2 */
+ const char* name,
+ ulint space,
+ ulint n_cols,
+ ulint n_v_cols,
+ ulint flags,
+ ulint flags2,
+ bool init_stats_latch)
{
dict_table_t* table;
mem_heap_t* heap;
@@ -126,6 +143,9 @@ dict_mem_table_create(
lock_table_lock_list_init(&table->locks);
UT_LIST_INIT(table->indexes, &dict_index_t::indexes);
+#ifdef BTR_CUR_HASH_ADAPT
+ UT_LIST_INIT(table->freed_indexes, &dict_index_t::indexes);
+#endif /* BTR_CUR_HASH_ADAPT */
table->heap = heap;
@@ -145,16 +165,9 @@ dict_mem_table_create(
table->v_cols = static_cast<dict_v_col_t*>(
mem_heap_alloc(heap, n_v_cols * sizeof(*table->v_cols)));
- /* true means that the stats latch will be enabled -
- dict_table_stats_lock() will not be noop. */
- dict_table_stats_latch_create(table, true);
-
table->autoinc_lock = static_cast<ib_lock_t*>(
mem_heap_alloc(heap, lock_get_size()));
- /* lazy creation of table autoinc latch */
- dict_table_autoinc_create_lazy(table);
-
/* If the table has an FTS index or we are in the process
of building one, create the table->fts */
if (dict_table_has_fts_index(table)
@@ -169,6 +182,12 @@ dict_mem_table_create(
new(&table->foreign_set) dict_foreign_set();
new(&table->referenced_set) dict_foreign_set();
+ if (init_stats_latch) {
+ rw_lock_create(dict_table_stats_key, &table->stats_latch,
+ SYNC_INDEX_TREE);
+ table->stats_latch_inited = true;
+ }
+
return(table);
}
@@ -181,6 +200,10 @@ dict_mem_table_free(
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+ ut_ad(UT_LIST_GET_LEN(table->indexes) == 0);
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(UT_LIST_GET_LEN(table->freed_indexes) == 0);
+#endif /* BTR_CUR_HASH_ADAPT */
ut_d(table->cached = FALSE);
if (dict_table_has_fts_index(table)
@@ -193,9 +216,7 @@ dict_mem_table_free(
}
}
- dict_table_autoinc_destroy(table);
dict_mem_table_free_foreign_vcol_set(table);
- dict_table_stats_latch_destroy(table);
table->foreign_set.~dict_foreign_set();
table->referenced_set.~dict_foreign_set();
@@ -216,6 +237,10 @@ dict_mem_table_free(
UT_DELETE(table->s_cols);
}
+ if (table->stats_latch_inited) {
+ rw_lock_free(&table->stats_latch);
+ }
+
mem_heap_free(table->heap);
}
@@ -559,15 +584,14 @@ dict_mem_table_col_rename_low(
}
}
- dict_index_t* new_index = dict_foreign_find_index(
+ /* New index can be null if InnoDB already dropped
+ the foreign index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->foreign_index = dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL);
- /* There must be an equivalent index in this case. */
- ut_ad(new_index != NULL);
-
- foreign->foreign_index = new_index;
} else {
@@ -590,7 +614,41 @@ dict_mem_table_col_rename_low(
foreign = *it;
- ut_ad(foreign->referenced_index != NULL);
+ if (!foreign->referenced_index) {
+ /* Referenced index could have been dropped
+ when foreign_key_checks is disabled. In that case,
+ rename the corresponding referenced_col_names and
+ find the equivalent referenced index also */
+ for (unsigned f = 0; f < foreign->n_fields; f++) {
+
+ const char*& rc =
+ foreign->referenced_col_names[f];
+ if (strcmp(rc, from)) {
+ continue;
+ }
+
+ if (to_len <= strlen(rc)) {
+ memcpy(const_cast<char*>(rc), to,
+ to_len + 1);
+ } else {
+ rc = static_cast<char*>(
+ mem_heap_dup(
+ foreign->heap,
+ to, to_len + 1));
+ }
+ }
+
+ /* New index can be null if InnoDB already dropped
+ the referenced index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->referenced_index = dict_foreign_find_index(
+ foreign->referenced_table, NULL,
+ foreign->referenced_col_names,
+ foreign->n_fields, NULL, true, false,
+ NULL, NULL, NULL);
+ return;
+ }
+
for (unsigned f = 0; f < foreign->n_fields; f++) {
/* foreign->referenced_col_names[] need to be
@@ -705,10 +763,9 @@ dict_mem_index_create(
dict_mem_fill_index_struct(index, heap, table_name, index_name,
space, type, n_fields);
- dict_index_zip_pad_mutex_create_lazy(index);
+ mysql_mutex_init(0, &index->zip_pad.mutex, NULL);
if (type & DICT_SPATIAL) {
- mutex_create(LATCH_ID_RTR_SSN_MUTEX, &index->rtr_ssn.mutex);
index->rtr_track = static_cast<rtr_info_track_t*>(
mem_heap_alloc(
heap,
@@ -1021,7 +1078,7 @@ dict_mem_index_free(
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- dict_index_zip_pad_mutex_destroy(index);
+ mysql_mutex_destroy(&index->zip_pad.mutex);
if (dict_index_is_spatial(index)) {
rtr_info_active::iterator it;
@@ -1034,7 +1091,6 @@ dict_mem_index_free(
rtr_info->index = NULL;
}
- mutex_destroy(&index->rtr_ssn.mutex);
mutex_destroy(&index->rtr_track->rtr_active_mutex);
UT_DELETE(index->rtr_track->rtr_active);
}
@@ -1157,31 +1213,20 @@ operator<< (std::ostream& out, const dict_foreign_set& fk_set)
return(out);
}
-/****************************************************************//**
-Determines if a table belongs to a system database
-@return */
-bool
-dict_mem_table_is_system(
-/*================*/
- char *name) /*!< in: table name */
+/** Check whether fulltext index gets affected by foreign
+key constraint. */
+bool dict_foreign_t::affects_fulltext() const
{
- ut_ad(name);
-
- /* table has the following format: database/table
- and some system table are of the form SYS_* */
- if (strchr(name, '/')) {
- size_t table_len = strlen(name);
- const char *system_db;
- int i = 0;
- while ((system_db = innobase_system_databases[i++])
- && (system_db != NullS)) {
- size_t len = strlen(system_db);
- if (table_len > len && !strncmp(name, system_db, len)) {
- return true;
- }
- }
- return false;
- } else {
- return true;
- }
+ if (foreign_table == referenced_table || !foreign_table->fts)
+ return false;
+
+ for (ulint i= 0; i < n_fields; i++)
+ {
+ const dict_col_t *col= dict_index_get_nth_col(foreign_index, i);
+ if (dict_table_is_fts_column(foreign_table->fts->indexes, col->ind,
+ col->is_virtual()) != ULINT_UNDEFINED)
+ return true;
+ }
+
+ return false;
}
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index f49fb87e4ea..5083fda48ee 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2009, 2019, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -33,6 +33,7 @@ Created Jan 06, 2010 Vasil Dimov
#include "pars0pars.h"
#include <mysql_com.h>
#include "btr0btr.h"
+#include "sync0sync.h"
#include <algorithm>
#include <map>
@@ -409,7 +410,7 @@ dict_stats_table_clone_create(
t = (dict_table_t*) mem_heap_alloc(heap, sizeof(*t));
- UNIV_MEM_ASSERT_RW_ABORT(&table->id, sizeof(table->id));
+ MEM_CHECK_DEFINED(&table->id, sizeof(table->id));
t->id = table->id;
t->heap = heap;
@@ -418,12 +419,10 @@ dict_stats_table_clone_create(
t->corrupted = table->corrupted;
- /* This private object "t" is not shared with other threads, so
- we do not need the stats_latch (thus we pass false below). The
- dict_table_stats_lock()/unlock() routines will do nothing. */
- dict_table_stats_latch_create(t, false);
-
UT_LIST_INIT(t->indexes, &dict_index_t::indexes);
+#ifdef BTR_CUR_HASH_ADAPT
+ UT_LIST_INIT(t->freed_indexes, &dict_index_t::indexes);
+#endif /* BTR_CUR_HASH_ADAPT */
for (index = dict_table_get_first_index(table);
index != NULL;
@@ -439,7 +438,7 @@ dict_stats_table_clone_create(
idx = (dict_index_t*) mem_heap_alloc(heap, sizeof(*idx));
- UNIV_MEM_ASSERT_RW_ABORT(&index->id, sizeof(index->id));
+ MEM_CHECK_DEFINED(&index->id, sizeof(index->id));
idx->id = index->id;
idx->name = mem_heap_strdup(heap, index->name);
@@ -487,6 +486,8 @@ dict_stats_table_clone_create(
ut_d(t->magic_n = DICT_TABLE_MAGIC_N);
+ rw_lock_create(dict_table_stats_key, &t->stats_latch, SYNC_INDEX_TREE);
+
return(t);
}
@@ -499,7 +500,7 @@ dict_stats_table_clone_free(
/*========================*/
dict_table_t* t) /*!< in: dummy table object to free */
{
- dict_table_stats_latch_destroy(t);
+ rw_lock_free(&t->stats_latch);
mem_heap_free(t->heap);
}
@@ -586,23 +587,23 @@ dict_stats_assert_initialized_index(
/*================================*/
const dict_index_t* index) /*!< in: index */
{
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
index->stat_n_diff_key_vals,
index->n_uniq * sizeof(index->stat_n_diff_key_vals[0]));
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
index->stat_n_sample_sizes,
index->n_uniq * sizeof(index->stat_n_sample_sizes[0]));
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
index->stat_n_non_null_key_vals,
index->n_uniq * sizeof(index->stat_n_non_null_key_vals[0]));
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
&index->stat_index_size,
sizeof(index->stat_index_size));
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
&index->stat_n_leaf_pages,
sizeof(index->stat_n_leaf_pages));
}
@@ -617,32 +618,32 @@ dict_stats_assert_initialized(
{
ut_a(table->stat_initialized);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stats_last_recalc,
- sizeof(table->stats_last_recalc));
+ MEM_CHECK_DEFINED(&table->stats_last_recalc,
+ sizeof table->stats_last_recalc);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_persistent,
- sizeof(table->stat_persistent));
+ MEM_CHECK_DEFINED(&table->stat_persistent,
+ sizeof table->stat_persistent);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stats_auto_recalc,
- sizeof(table->stats_auto_recalc));
+ MEM_CHECK_DEFINED(&table->stats_auto_recalc,
+ sizeof table->stats_auto_recalc);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stats_sample_pages,
- sizeof(table->stats_sample_pages));
+ MEM_CHECK_DEFINED(&table->stats_sample_pages,
+ sizeof table->stats_sample_pages);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_n_rows,
- sizeof(table->stat_n_rows));
+ MEM_CHECK_DEFINED(&table->stat_n_rows,
+ sizeof table->stat_n_rows);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_clustered_index_size,
- sizeof(table->stat_clustered_index_size));
+ MEM_CHECK_DEFINED(&table->stat_clustered_index_size,
+ sizeof table->stat_clustered_index_size);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_sum_of_other_index_sizes,
- sizeof(table->stat_sum_of_other_index_sizes));
+ MEM_CHECK_DEFINED(&table->stat_sum_of_other_index_sizes,
+ sizeof table->stat_sum_of_other_index_sizes);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_modified_counter,
- sizeof(table->stat_modified_counter));
+ MEM_CHECK_DEFINED(&table->stat_modified_counter,
+ sizeof table->stat_modified_counter);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stats_bg_flag,
- sizeof(table->stats_bg_flag));
+ MEM_CHECK_DEFINED(&table->stats_bg_flag,
+ sizeof table->stats_bg_flag);
for (dict_index_t* index = dict_table_get_first_index(table);
index != NULL;
@@ -1018,8 +1019,8 @@ dict_stats_analyze_index_level(
bool prev_rec_is_copied;
byte* prev_rec_buf = NULL;
ulint prev_rec_buf_size = 0;
- ulint* rec_offsets;
- ulint* prev_rec_offsets;
+ rec_offs* rec_offsets;
+ rec_offs* prev_rec_offsets;
ulint i;
DEBUG_PRINTF(" %s(table=%s, index=%s, level=" ULINTPF ")\n",
@@ -1040,9 +1041,9 @@ dict_stats_analyze_index_level(
i = (REC_OFFS_HEADER_SIZE + 1 + 1) + index->n_fields;
heap = mem_heap_create((2 * sizeof *rec_offsets) * i);
- rec_offsets = static_cast<ulint*>(
+ rec_offsets = static_cast<rec_offs*>(
mem_heap_alloc(heap, i * sizeof *rec_offsets));
- prev_rec_offsets = static_cast<ulint*>(
+ prev_rec_offsets = static_cast<rec_offs*>(
mem_heap_alloc(heap, i * sizeof *prev_rec_offsets));
rec_offs_set_n_alloc(rec_offsets, i);
rec_offs_set_n_alloc(prev_rec_offsets, i);
@@ -1166,13 +1167,9 @@ dict_stats_analyze_index_level(
prev_rec, index, prev_rec_offsets, !level,
n_uniq, &heap);
- cmp_rec_rec_with_match(rec,
- prev_rec,
- rec_offsets,
- prev_rec_offsets,
- index,
- FALSE,
- &matched_fields);
+ cmp_rec_rec(prev_rec, rec,
+ prev_rec_offsets, rec_offsets, index,
+ false, &matched_fields);
for (i = matched_fields; i < n_uniq; i++) {
@@ -1328,11 +1325,11 @@ to the number of externally stored pages which were encountered
@return offsets1 or offsets2 (the offsets of *out_rec),
or NULL if the page is empty and does not contain user records. */
UNIV_INLINE
-ulint*
+rec_offs*
dict_stats_scan_page(
const rec_t** out_rec,
- ulint* offsets1,
- ulint* offsets2,
+ rec_offs* offsets1,
+ rec_offs* offsets2,
const dict_index_t* index,
const page_t* page,
ulint n_prefix,
@@ -1340,8 +1337,8 @@ dict_stats_scan_page(
ib_uint64_t* n_diff,
ib_uint64_t* n_external_pages)
{
- ulint* offsets_rec = offsets1;
- ulint* offsets_next_rec = offsets2;
+ rec_offs* offsets_rec = offsets1;
+ rec_offs* offsets_next_rec = offsets2;
const rec_t* rec;
const rec_t* next_rec;
/* A dummy heap, to be passed to rec_get_offsets().
@@ -1392,9 +1389,8 @@ dict_stats_scan_page(
/* check whether rec != next_rec when looking at
the first n_prefix fields */
- cmp_rec_rec_with_match(rec, next_rec,
- offsets_rec, offsets_next_rec,
- index, FALSE, &matched_fields);
+ cmp_rec_rec(rec, next_rec, offsets_rec, offsets_next_rec,
+ index, false, &matched_fields);
if (matched_fields < n_prefix) {
/* rec != next_rec, => rec is non-boring */
@@ -1407,23 +1403,16 @@ dict_stats_scan_page(
}
rec = next_rec;
- {
- /* Assign offsets_rec = offsets_next_rec
- so that offsets_rec matches with rec which
- was just assigned rec = next_rec above.
- Also need to point offsets_next_rec to the
- place where offsets_rec was pointing before
- because we have just 2 placeholders where
- data is actually stored:
- offsets1 and offsets2 and we
- are using them in circular fashion
- (offsets[_next]_rec are just pointers to
- those placeholders). */
- ulint* offsets_tmp;
- offsets_tmp = offsets_rec;
- offsets_rec = offsets_next_rec;
- offsets_next_rec = offsets_tmp;
- }
+ /* Assign offsets_rec = offsets_next_rec so that
+ offsets_rec matches with rec which was just assigned
+ rec = next_rec above. Also need to point
+ offsets_next_rec to the place where offsets_rec was
+ pointing before because we have just 2 placeholders
+ where data is actually stored: offsets1 and offsets2
+ and we are using them in circular fashion
+ (offsets[_next]_rec are just pointers to those
+ placeholders). */
+ std::swap(offsets_rec, offsets_next_rec);
if (should_count_external_pages) {
*n_external_pages += btr_rec_get_externally_stored_len(
@@ -1462,9 +1451,9 @@ dict_stats_analyze_index_below_cur(
const page_t* page;
mem_heap_t* heap;
const rec_t* rec;
- ulint* offsets1;
- ulint* offsets2;
- ulint* offsets_rec;
+ rec_offs* offsets1;
+ rec_offs* offsets2;
+ rec_offs* offsets_rec;
ulint size;
mtr_t mtr;
@@ -1482,10 +1471,10 @@ dict_stats_analyze_index_below_cur(
heap = mem_heap_create(size * (sizeof *offsets1 + sizeof *offsets2));
- offsets1 = static_cast<ulint*>(mem_heap_alloc(
+ offsets1 = static_cast<rec_offs*>(mem_heap_alloc(
heap, size * sizeof *offsets1));
- offsets2 = static_cast<ulint*>(mem_heap_alloc(
+ offsets2 = static_cast<rec_offs*>(mem_heap_alloc(
heap, size * sizeof *offsets2));
rec_offs_set_n_alloc(offsets1, size);
@@ -1747,7 +1736,7 @@ dict_stats_analyze_index_for_n_prefix(
ut_rnd_interval() to work with too big numbers since
ib_uint64_t could be bigger than ulint */
const ulint rnd = ut_rnd_interval(
- 0, static_cast<ulint>(right - left));
+ static_cast<ulint>(right - left));
const ib_uint64_t dive_below_idx
= boundaries->at(static_cast<unsigned>(left + rnd));
@@ -2321,20 +2310,19 @@ dict_stats_save_index_stat(
pars_info_add_str_literal(pinfo, "database_name", db_utf8);
pars_info_add_str_literal(pinfo, "table_name", table_utf8);
pars_info_add_str_literal(pinfo, "index_name", index->name);
- UNIV_MEM_ASSERT_RW_ABORT(&last_update, 4);
+ MEM_CHECK_DEFINED(&last_update, 4);
pars_info_add_int4_literal(pinfo, "last_update", (lint)last_update);
- UNIV_MEM_ASSERT_RW_ABORT(stat_name, strlen(stat_name));
+ MEM_CHECK_DEFINED(stat_name, strlen(stat_name));
pars_info_add_str_literal(pinfo, "stat_name", stat_name);
- UNIV_MEM_ASSERT_RW_ABORT(&stat_value, 8);
+ MEM_CHECK_DEFINED(&stat_value, 8);
pars_info_add_ull_literal(pinfo, "stat_value", stat_value);
if (sample_size != NULL) {
- UNIV_MEM_ASSERT_RW_ABORT(sample_size, 8);
+ MEM_CHECK_DEFINED(sample_size, 8);
pars_info_add_ull_literal(pinfo, "sample_size", *sample_size);
} else {
pars_info_add_literal(pinfo, "sample_size", NULL,
UNIV_SQL_NULL, DATA_FIXBINARY, 0);
}
- UNIV_MEM_ASSERT_RW_ABORT(stat_description, strlen(stat_description));
pars_info_add_str_literal(pinfo, "stat_description",
stat_description);
@@ -2364,14 +2352,14 @@ dict_stats_save_index_stat(
");\n"
"END;", trx);
- if (ret != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(ret != DB_SUCCESS)) {
if (innodb_index_stats_not_found == false &&
index->stats_error_printed == false) {
ib::error() << "Cannot save index statistics for table "
<< index->table->name
<< ", index " << index->name
<< ", stat name \"" << stat_name << "\": "
- << ut_strerr(ret);
+ << ret;
index->stats_error_printed = true;
}
}
@@ -2482,9 +2470,9 @@ dict_stats_save(
");\n"
"END;", NULL);
- if (ret != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(ret != DB_SUCCESS)) {
ib::error() << "Cannot save table statistics for table "
- << table->name << ": " << ut_strerr(ret);
+ << table->name << ": " << ret;
mutex_exit(&dict_sys->mutex);
rw_lock_x_unlock(&dict_operation_lock);
@@ -3339,7 +3327,7 @@ dict_stats_update(
" for table "
<< table->name
<< " from " TABLE_STATS_NAME_PRINT " and "
- INDEX_STATS_NAME_PRINT ": " << ut_strerr(err)
+ INDEX_STATS_NAME_PRINT ": " << err
<< ". Using transient stats method instead.";
}
@@ -4017,6 +4005,9 @@ test_dict_stats_save()
table.stat_clustered_index_size = TEST_CLUSTERED_INDEX_SIZE;
table.stat_sum_of_other_index_sizes = TEST_SUM_OF_OTHER_INDEX_SIZES;
UT_LIST_INIT(table.indexes, &dict_index_t::indexes);
+#ifdef BTR_CUR_HASH_ADAPT
+ UT_LIST_INIT(table.freed_indexes, &dict_index_t::indexes);
+#endif /* BTR_CUR_HASH_ADAPT */
UT_LIST_ADD_LAST(table.indexes, &index1);
UT_LIST_ADD_LAST(table.indexes, &index2);
ut_d(table.magic_n = DICT_TABLE_MAGIC_N);
@@ -4166,6 +4157,9 @@ test_dict_stats_fetch_from_ps()
/* craft a dummy dict_table_t */
table.name.m_name = (char*) (TEST_DATABASE_NAME "/" TEST_TABLE_NAME);
UT_LIST_INIT(table.indexes, &dict_index_t::indexes);
+#ifdef BTR_CUR_HASH_ADAPT
+ UT_LIST_INIT(table.freed_indexes, &dict_index_t::indexes);
+#endif /* BTR_CUR_HASH_ADAPT */
UT_LIST_ADD_LAST(table.indexes, &index1);
UT_LIST_ADD_LAST(table.indexes, &index2);
ut_d(table.magic_n = DICT_TABLE_MAGIC_N);
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index ec3f0a8eae6..589f53dde38 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -32,6 +32,7 @@ Created Apr 25, 2012 Vasil Dimov
#include "srv0start.h"
#include "fil0fil.h"
#ifdef WITH_WSREP
+# include "trx0trx.h"
# include "mysql/service_wsrep.h"
# include "wsrep.h"
# include "log.h"
@@ -145,12 +146,12 @@ dict_stats_recalc_pool_add(
schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table
@param[in] thd current session */
-void dict_stats_update_if_needed(dict_table_t* table, THD* thd)
+void dict_stats_update_if_needed(dict_table_t *table, const trx_t &trx)
#else
/** Update the table modification counter and if necessary,
schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table */
-void dict_stats_update_if_needed_func(dict_table_t* table)
+void dict_stats_update_if_needed_func(dict_table_t *table)
#endif
{
ut_ad(table->stat_initialized);
@@ -177,10 +178,9 @@ void dict_stats_update_if_needed_func(dict_table_t* table)
generated row locks and allow BF thread
lock waits to be enqueued at head of waiting
queue. */
- if (thd
- && !wsrep_thd_is_applier(thd)
- && wsrep_on(thd)
- && wsrep_thd_is_BF(thd, 0)) {
+ if (trx.is_wsrep()
+ && !wsrep_thd_is_applier(trx.mysql_thd)
+ && wsrep_thd_is_BF(trx.mysql_thd, 0)) {
WSREP_DEBUG("Avoiding background statistics"
" calculation for table %s.",
table->name.m_name);
diff --git a/storage/innobase/eval/eval0eval.cc b/storage/innobase/eval/eval0eval.cc
index e02fc7f561b..6f709707f7f 100644
--- a/storage/innobase/eval/eval0eval.cc
+++ b/storage/innobase/eval/eval0eval.cc
@@ -30,9 +30,6 @@ Created 12/29/1997 Heikki Tuuri
#include "row0sel.h"
#include "rem0cmp.h"
-/** The RND function seed */
-static ulint eval_rnd = 128367121;
-
/** Dummy adress used when we should allocate a buffer of size 0 in
eval_node_alloc_val_buf */
@@ -310,120 +307,18 @@ eval_aggregate(
/*===========*/
func_node_t* node) /*!< in: aggregate operation node */
{
- que_node_t* arg;
lint val;
- lint arg_val;
- int func;
ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
val = eval_node_get_int_val(node);
- func = node->func;
-
- if (func == PARS_COUNT_TOKEN) {
-
- val = val + 1;
- } else {
- ut_ad(func == PARS_SUM_TOKEN);
-
- arg = node->args;
- arg_val = eval_node_get_int_val(arg);
-
- val = val + arg_val;
- }
-
+ ut_a(node->func == PARS_COUNT_TOKEN);
+ val = val + 1;
eval_node_set_int_val(node, val);
}
/*****************************************************************//**
-Evaluates a predefined function node where the function is not relevant
-in benchmarks. */
-static
-void
-eval_predefined_2(
-/*==============*/
- func_node_t* func_node) /*!< in: predefined function node */
-{
- que_node_t* arg;
- que_node_t* arg1;
- que_node_t* arg2 = 0; /* remove warning (??? bug ???) */
- lint int_val;
- byte* data;
- ulint len1;
- ulint len2;
- int func;
- ulint i;
-
- ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
-
- arg1 = func_node->args;
-
- if (arg1) {
- arg2 = que_node_get_next(arg1);
- }
-
- func = func_node->func;
-
- if (func == PARS_PRINTF_TOKEN) {
-
- arg = arg1;
-
- while (arg) {
- dfield_print(que_node_get_val(arg));
-
- arg = que_node_get_next(arg);
- }
-
- putc('\n', stderr);
-
- } else if (func == PARS_ASSERT_TOKEN) {
-
- if (!eval_node_get_ibool_val(arg1)) {
- fputs("SQL assertion fails in a stored procedure!\n",
- stderr);
- }
-
- ut_a(eval_node_get_ibool_val(arg1));
-
- /* This function, or more precisely, a debug procedure,
- returns no value */
-
- } else if (func == PARS_RND_TOKEN) {
-
- len1 = (ulint) eval_node_get_int_val(arg1);
- len2 = (ulint) eval_node_get_int_val(arg2);
-
- ut_ad(len2 >= len1);
-
- if (len2 > len1) {
- int_val = (lint) (len1
- + (eval_rnd % (len2 - len1 + 1)));
- } else {
- int_val = (lint) len1;
- }
-
- eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
-
- eval_node_set_int_val(func_node, int_val);
-
- } else if (func == PARS_RND_STR_TOKEN) {
-
- len1 = (ulint) eval_node_get_int_val(arg1);
-
- data = eval_node_ensure_val_buf(func_node, len1);
-
- for (i = 0; i < len1; i++) {
- data[i] = (byte)(97 + (eval_rnd % 3));
-
- eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
- }
- } else {
- ut_error;
- }
-}
-
-/*****************************************************************//**
Evaluates a notfound-function node. */
UNIV_INLINE
void
@@ -494,46 +389,6 @@ eval_substr(
}
/*****************************************************************//**
-Evaluates a replstr-procedure node. */
-static
-void
-eval_replstr(
-/*=========*/
- func_node_t* func_node) /*!< in: function node */
-{
- que_node_t* arg1;
- que_node_t* arg2;
- que_node_t* arg3;
- que_node_t* arg4;
- byte* str1;
- byte* str2;
- ulint len1;
- ulint len2;
-
- arg1 = func_node->args;
- arg2 = que_node_get_next(arg1);
-
- ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
-
- arg3 = que_node_get_next(arg2);
- arg4 = que_node_get_next(arg3);
-
- str1 = static_cast<byte*>(dfield_get_data(que_node_get_val(arg1)));
- str2 = static_cast<byte*>(dfield_get_data(que_node_get_val(arg2)));
-
- len1 = (ulint) eval_node_get_int_val(arg3);
- len2 = (ulint) eval_node_get_int_val(arg4);
-
- if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
- || (dfield_get_len(que_node_get_val(arg2)) < len2)) {
-
- ut_error;
- }
-
- ut_memcpy(str1 + len1, str2, len2);
-}
-
-/*****************************************************************//**
Evaluates an instr-function node. */
static
void
@@ -607,44 +462,6 @@ match_found:
/*****************************************************************//**
Evaluates a predefined function node. */
-UNIV_INLINE
-void
-eval_binary_to_number(
-/*==================*/
- func_node_t* func_node) /*!< in: function node */
-{
- que_node_t* arg1;
- dfield_t* dfield;
- byte* str1;
- byte* str2;
- ulint len1;
- ulint int_val;
-
- arg1 = func_node->args;
-
- dfield = que_node_get_val(arg1);
-
- str1 = static_cast<byte*>(dfield_get_data(dfield));
- len1 = dfield_get_len(dfield);
-
- if (len1 > 4) {
- ut_error;
- }
-
- if (len1 == 4) {
- str2 = str1;
- } else {
- int_val = 0;
- str2 = (byte*) &int_val;
-
- ut_memcpy(str2 + (4 - len1), str1, len1);
- }
-
- eval_node_copy_and_alloc_val(func_node, str2, 4);
-}
-
-/*****************************************************************//**
-Evaluates a predefined function node. */
static
void
eval_concat(
@@ -734,95 +551,12 @@ eval_to_binary(
}
/*****************************************************************//**
-Evaluates a predefined function node. */
-UNIV_INLINE
-void
-eval_predefined(
-/*============*/
- func_node_t* func_node) /*!< in: function node */
+Evaluate LENGTH(). */
+inline void eval_length(func_node_t* func_node)
{
- que_node_t* arg1;
- lint int_val;
- byte* data;
- int func;
-
- func = func_node->func;
-
- arg1 = func_node->args;
-
- if (func == PARS_LENGTH_TOKEN) {
-
- int_val = (lint) dfield_get_len(que_node_get_val(arg1));
-
- } else if (func == PARS_TO_CHAR_TOKEN) {
-
- /* Convert number to character string as a
- signed decimal integer. */
-
- ulint uint_val;
- int int_len;
-
- int_val = eval_node_get_int_val(arg1);
-
- /* Determine the length of the string. */
-
- if (int_val == 0) {
- int_len = 1; /* the number 0 occupies 1 byte */
- } else {
- int_len = 0;
- if (int_val < 0) {
- uint_val = ((ulint) -int_val - 1) + 1;
- int_len++; /* reserve space for minus sign */
- } else {
- uint_val = (ulint) int_val;
- }
- for (; uint_val > 0; int_len++) {
- uint_val /= 10;
- }
- }
-
- /* allocate the string */
- data = eval_node_ensure_val_buf(func_node, int_len + 1);
-
- /* add terminating NUL character */
- data[int_len] = 0;
-
- /* convert the number */
-
- if (int_val == 0) {
- data[0] = '0';
- } else {
- int tmp;
- if (int_val < 0) {
- data[0] = '-'; /* preceding minus sign */
- uint_val = ((ulint) -int_val - 1) + 1;
- } else {
- uint_val = (ulint) int_val;
- }
- for (tmp = int_len; uint_val > 0; uint_val /= 10) {
- data[--tmp] = (byte)
- ('0' + (byte)(uint_val % 10));
- }
- }
-
- dfield_set_len(que_node_get_val(func_node), int_len);
-
- return;
-
- } else if (func == PARS_TO_NUMBER_TOKEN) {
-
- int_val = atoi((char*)
- dfield_get_data(que_node_get_val(arg1)));
-
- } else if (func == PARS_SYSDATE_TOKEN) {
- int_val = (lint) time(NULL);
- } else {
- eval_predefined_2(func_node);
-
- return;
- }
-
- eval_node_set_int_val(func_node, int_val);
+ eval_node_set_int_val(func_node,
+ dfield_get_len(que_node_get_val
+ (func_node->args)));
}
/*****************************************************************//**
@@ -852,8 +586,7 @@ eval_func(
if (dfield_is_null(que_node_get_val(arg))
&& (fclass != PARS_FUNC_CMP)
- && (func != PARS_NOTFOUND_TOKEN)
- && (func != PARS_PRINTF_TOKEN)) {
+ && (func != PARS_NOTFOUND_TOKEN)) {
ut_error;
}
@@ -878,24 +611,20 @@ eval_func(
case PARS_SUBSTR_TOKEN:
eval_substr(func_node);
return;
- case PARS_REPLSTR_TOKEN:
- eval_replstr(func_node);
- return;
case PARS_INSTR_TOKEN:
eval_instr(func_node);
return;
- case PARS_BINARY_TO_NUMBER_TOKEN:
- eval_binary_to_number(func_node);
- return;
case PARS_CONCAT_TOKEN:
eval_concat(func_node);
return;
case PARS_TO_BINARY_TOKEN:
eval_to_binary(func_node);
return;
- default:
- eval_predefined(func_node);
+ case PARS_LENGTH_TOKEN:
+ eval_length(func_node);
return;
+ default:
+ ut_error;
}
case PARS_FUNC_LOGICAL:
eval_logical(func_node);
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index d1aca92ef62..68a8a9be261 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -41,9 +41,6 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
#include "fil0pagecompress.h"
#include <my_crypt.h>
-/** Mutex for keys */
-static ib_mutex_t fil_crypt_key_mutex;
-
static bool fil_crypt_threads_inited = false;
/** Is encryption enabled/disabled */
@@ -113,8 +110,6 @@ UNIV_INTERN
void
fil_space_crypt_init()
{
- mutex_create(LATCH_ID_FIL_CRYPT_MUTEX, &fil_crypt_key_mutex);
-
fil_crypt_throttle_sleep_event = os_event_create(0);
mutex_create(LATCH_ID_FIL_CRYPT_STAT_MUTEX, &crypt_stat_mutex);
@@ -128,7 +123,6 @@ void
fil_space_crypt_cleanup()
{
os_event_destroy(fil_crypt_throttle_sleep_event);
- mutex_free(&fil_crypt_key_mutex);
mutex_free(&crypt_stat_mutex);
}
@@ -298,14 +292,9 @@ fil_space_read_crypt_data(const page_size_t& page_size, const byte* page)
type == CRYPT_SCHEME_1)
|| iv_length != sizeof crypt_data->iv) {
ib::error() << "Found non sensible crypt scheme: "
- << type << "," << iv_length << " for space: "
- << page_get_space_id(page) << " offset: "
- << offset << " bytes: ["
- << page[offset + 2 + MAGIC_SZ]
- << page[offset + 3 + MAGIC_SZ]
- << page[offset + 4 + MAGIC_SZ]
- << page[offset + 5 + MAGIC_SZ]
- << "].";
+ << type << "," << iv_length
+ << " for space: "
+ << page_get_space_id(page);
return NULL;
}
@@ -418,6 +407,8 @@ fil_space_crypt_t::write_page0(
mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len + 8, encryption,
MLOG_1BYTE, mtr);
+ DBUG_EXECUTE_IF("ib_do_not_log_crypt_data", return;);
+
byte* log_ptr = mlog_open(mtr, 11 + 17 + len);
if (log_ptr != NULL) {
@@ -655,51 +646,10 @@ fil_space_encrypt(
return (src_frame);
}
- fil_space_crypt_t* crypt_data = space->crypt_data;
- const page_size_t page_size(space->flags);
ut_ad(space->n_pending_ios > 0);
- byte* tmp = fil_encrypt_buf(crypt_data, space->id, offset, lsn,
- src_frame, page_size, dst_frame);
-
-#ifdef UNIV_DEBUG
- if (tmp) {
- /* Verify that encrypted buffer is not corrupted */
- dberr_t err = DB_SUCCESS;
- byte* src = src_frame;
- bool page_compressed_encrypted = (mach_read_from_2(tmp+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
- byte uncomp_mem[UNIV_PAGE_SIZE_MAX];
- byte tmp_mem[UNIV_PAGE_SIZE_MAX];
-
- if (page_compressed_encrypted) {
- memcpy(uncomp_mem, src, srv_page_size);
- ulint unzipped1 = fil_page_decompress(
- tmp_mem, uncomp_mem);
- ut_ad(unzipped1);
- if (unzipped1 != srv_page_size) {
- src = uncomp_mem;
- }
- }
-
- ut_ad(!buf_page_is_corrupted(true, src, page_size, space));
- ut_ad(fil_space_decrypt(crypt_data, tmp_mem, page_size, tmp,
- &err));
- ut_ad(err == DB_SUCCESS);
-
- /* Need to decompress the page if it was also compressed */
- if (page_compressed_encrypted) {
- byte buf[UNIV_PAGE_SIZE_MAX];
- memcpy(buf, tmp_mem, srv_page_size);
- ulint unzipped2 = fil_page_decompress(tmp_mem, buf);
- ut_ad(unzipped2);
- }
-
- memcpy(tmp_mem + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
- src + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 8);
- ut_ad(!memcmp(src, tmp_mem, page_size.physical()));
- }
-#endif /* UNIV_DEBUG */
-
- return tmp;
+ return fil_encrypt_buf(space->crypt_data, space->id, offset, lsn,
+ src_frame, page_size_t(space->flags),
+ dst_frame);
}
/** Decrypt a page.
@@ -766,8 +716,10 @@ fil_space_decrypt(
}
ib::fatal() << "Unable to decrypt data-block "
- << " src: " << src << "srclen: "
- << srclen << " buf: " << dst << "buflen: "
+ << " src: " << static_cast<const void*>(src)
+ << "srclen: "
+ << srclen << " buf: "
+ << static_cast<const void*>(dst) << "buflen: "
<< dstlen << " return-code: " << rc
<< " Can't continue!";
}
@@ -1120,6 +1072,7 @@ struct rotate_thread_t {
case SRV_SHUTDOWN_EXIT_THREADS:
/* srv_init_abort() must have been invoked */
case SRV_SHUTDOWN_CLEANUP:
+ case SRV_SHUTDOWN_INITIATED:
return true;
case SRV_SHUTDOWN_FLUSH_PHASE:
case SRV_SHUTDOWN_LAST_PHASE:
@@ -1427,6 +1380,99 @@ fil_crypt_return_iops(
fil_crypt_update_total_stat(state);
}
+/** Return the next tablespace from rotation_list.
+@param space previous tablespace (NULL to start from the start)
+@param recheck whether the removal condition needs to be rechecked after
+the encryption parameters were changed
+@param encrypt expected state of innodb_encrypt_tables
+@return the next tablespace to process (n_pending_ops incremented)
+@retval NULL if this was the last */
+inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
+ bool recheck, bool encrypt)
+{
+ ut_ad(mutex_own(&mutex));
+
+ sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
+ space && space->is_in_rotation_list ? space : rotation_list.begin();
+ const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end=
+ rotation_list.end();
+
+ if (space)
+ {
+ const bool released= !--space->n_pending_ops;
+
+ if (space->is_in_rotation_list)
+ {
+ while (++it != end &&
+ (!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
+
+ /* If one of the encryption threads already started the encryption
+ of the table then don't remove the unencrypted spaces from rotation list
+
+ If there is a change in innodb_encrypt_tables variables value then
+ don't remove the last processed tablespace from the rotation list. */
+ if (released && (!recheck || space->crypt_data) &&
+ !encrypt == !srv_encrypt_tables)
+ {
+ ut_a(!rotation_list.empty());
+ rotation_list.remove(*space);
+ space->is_in_rotation_list= false;
+ }
+ }
+ }
+
+ if (it == end)
+ return NULL;
+
+ space= &*it;
+ space->n_pending_ops++;
+ return space;
+}
+
+/** Return the next tablespace.
+@param space previous tablespace (NULL to start from the beginning)
+@param recheck whether the removal condition needs to be rechecked after
+the encryption parameters were changed
+@param encrypt expected state of innodb_encrypt_tables
+@return pointer to the next tablespace (with n_pending_ops incremented)
+@retval NULL if this was the last */
+static fil_space_t *fil_space_next(fil_space_t *space, bool recheck,
+ bool encrypt)
+{
+ mutex_enter(&fil_system->mutex);
+ ut_ad(!space || space->n_pending_ops);
+
+ if (!srv_fil_crypt_rotate_key_age)
+ space= fil_system->keyrotate_next(space, recheck, encrypt);
+ else if (!space)
+ {
+ space= UT_LIST_GET_FIRST(fil_system->space_list);
+ /* We can trust that space is not NULL because at least the
+ system tablespace is always present and loaded first. */
+ space->n_pending_ops++;
+ }
+ else
+ {
+ ut_ad(space->n_pending_ops > 0);
+ /* Move on to the next fil_space_t */
+ space->n_pending_ops--;
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ /* Skip abnormal tablespaces or those that are being created by
+ fil_ibd_create(), or being dropped. */
+ while (space &&
+ (UT_LIST_GET_LEN(space->chain) == 0 ||
+ space->is_stopping() || space->purpose != FIL_TYPE_TABLESPACE))
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ if (space)
+ space->n_pending_ops++;
+ }
+
+ mutex_exit(&fil_system->mutex);
+ return space;
+}
+
/** Search for a space needing rotation
@param[in,out] key_state Key state
@param[in,out] state Rotation state
@@ -1439,6 +1485,11 @@ static bool fil_crypt_find_space_to_rotate(
{
/* we need iops to start rotating */
while (!state->should_shutdown() && !fil_crypt_alloc_iops(state)) {
+ if (state->space && state->space->is_stopping()) {
+ fil_space_release(state->space);
+ state->space = NULL;
+ }
+
os_event_reset(fil_crypt_threads_event);
os_event_wait_time(fil_crypt_threads_event, 100000);
}
@@ -1459,16 +1510,8 @@ static bool fil_crypt_find_space_to_rotate(
state->space = NULL;
}
- /* If key rotation is enabled (default) we iterate all tablespaces.
- If key rotation is not enabled we iterate only the tablespaces
- added to keyrotation list. */
- if (srv_fil_crypt_rotate_key_age) {
- state->space = fil_space_next(state->space);
- } else {
- state->space = fil_system->keyrotate_next(
- state->space, *recheck,
- key_state->key_version);
- }
+ state->space = fil_space_next(state->space, *recheck,
+ key_state->key_version != 0);
while (!state->should_shutdown() && state->space) {
/* If there is no crypt data and we have not yet read
@@ -1486,16 +1529,16 @@ static bool fil_crypt_find_space_to_rotate(
return true;
}
- if (srv_fil_crypt_rotate_key_age) {
- state->space = fil_space_next(state->space);
- } else {
- state->space = fil_system->keyrotate_next(
- state->space, *recheck,
- key_state->key_version);
- }
+ state->space = fil_space_next(state->space, *recheck,
+ key_state->key_version != 0);
}
- /* if we didn't find any space return iops */
+ if (state->space) {
+ fil_space_release(state->space);
+ state->space = NULL;
+ }
+
+ /* no work to do; release our allocation of I/O capacity */
fil_crypt_return_iops(state);
return false;
@@ -2302,7 +2345,7 @@ static void fil_crypt_rotation_list_fill()
space != NULL;
space = UT_LIST_GET_NEXT(space_list, space)) {
if (space->purpose != FIL_TYPE_TABLESPACE
- || space->is_in_rotation_list()
+ || space->is_in_rotation_list
|| space->is_stopping()
|| UT_LIST_GET_LEN(space->chain) == 0) {
continue;
@@ -2346,7 +2389,8 @@ static void fil_crypt_rotation_list_fill()
}
}
- UT_LIST_ADD_LAST(fil_system->rotation_list, space);
+ fil_system->rotation_list.push_back(*space);
+ space->is_in_rotation_list = true;
}
}
@@ -2469,6 +2513,7 @@ fil_space_crypt_close_tablespace(
/* wakeup throttle (all) sleepers */
os_event_set(fil_crypt_throttle_sleep_event);
+ os_event_set(fil_crypt_threads_event);
os_thread_sleep(20000);
dict_mutex_enter_for_mysql();
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index e37cb963c28..328cd104e5d 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -359,34 +359,6 @@ fil_space_get(
return(space);
}
-/** Returns the latch of a file space.
-@param[in] id space id
-@param[out] flags tablespace flags
-@return latch protecting storage allocation */
-rw_lock_t*
-fil_space_get_latch(
- ulint id,
- ulint* flags)
-{
- fil_space_t* space;
-
- ut_ad(fil_system);
-
- mutex_enter(&fil_system->mutex);
-
- space = fil_space_get_by_id(id);
-
- ut_a(space);
-
- if (flags) {
- *flags = space->flags;
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(&(space->latch));
-}
-
/** Gets the type of a file space.
@param[in] id tablespace identifier
@return file type */
@@ -593,13 +565,17 @@ bool fil_node_t::read_page0(bool first)
}
this->size = ulint(size_bytes / psize);
- space->size += this->size;
+ space->committed_size = space->size += this->size;
} else if (space->id != TRX_SYS_SPACE || space->size_in_header) {
/* If this is not the first-time open, do nothing.
For the system tablespace, we always get invoked as
first=false, so we detect the true first-time-open based
- on size_in_header and proceed to initiailze the data. */
+ on size_in_header and proceed to initialize the data. */
return true;
+ } else {
+ /* Initialize the size of predefined tablespaces
+ to FSP_SIZE. */
+ space->committed_size = size;
}
ut_ad(space->free_limit == 0 || space->free_limit == free_limit);
@@ -629,6 +605,14 @@ static bool fil_node_open_file(fil_node_t* node)
const bool first_time_open = node->size == 0;
+ bool o_direct_possible = !FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags);
+ if (const ulint ssize = FSP_FLAGS_GET_ZIP_SSIZE(space->flags)) {
+ compile_time_assert(((UNIV_ZIP_SIZE_MIN >> 1) << 3) == 4096);
+ if (ssize < 3) {
+ o_direct_possible = false;
+ }
+ }
+
if (first_time_open
|| (space->purpose == FIL_TYPE_TABLESPACE
&& node == UT_LIST_GET_FIRST(space->chain)
@@ -647,7 +631,12 @@ retry:
node->is_raw_disk
? OS_FILE_OPEN_RAW | OS_FILE_ON_ERROR_NO_EXIT
: OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT,
- OS_FILE_AIO, OS_DATA_FILE, read_only_mode, &success);
+ OS_FILE_AIO,
+ o_direct_possible
+ ? OS_DATA_FILE
+ : OS_DATA_FILE_NO_O_DIRECT,
+ read_only_mode,
+ &success);
if (!success) {
/* The following call prints an error message */
@@ -678,7 +667,12 @@ retry:
node->is_raw_disk
? OS_FILE_OPEN_RAW | OS_FILE_ON_ERROR_NO_EXIT
: OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT,
- OS_FILE_AIO, OS_DATA_FILE, read_only_mode, &success);
+ OS_FILE_AIO,
+ o_direct_possible
+ ? OS_DATA_FILE
+ : OS_DATA_FILE_NO_O_DIRECT,
+ read_only_mode,
+ &success);
}
if (space->purpose != FIL_TYPE_LOG) {
@@ -832,7 +826,7 @@ static void fil_flush_low(fil_space_t* space, bool metadata = false)
/* No need to flush. User has explicitly disabled
buffering. */
- ut_ad(!space->is_in_unflushed_spaces());
+ ut_ad(!space->is_in_unflushed_spaces);
ut_ad(fil_space_is_flushed(space));
ut_ad(space->n_pending_flushes == 0);
@@ -895,12 +889,11 @@ static void fil_flush_low(fil_space_t* space, bool metadata = false)
skip_flush:
#endif /* _WIN32 */
if (!node->needs_flush) {
- if (space->is_in_unflushed_spaces()
+ if (space->is_in_unflushed_spaces
&& fil_space_is_flushed(space)) {
- UT_LIST_REMOVE(
- fil_system->unflushed_spaces,
- space);
+ fil_system->unflushed_spaces.remove(*space);
+ space->is_in_unflushed_spaces = false;
}
}
@@ -1127,6 +1120,9 @@ fil_mutex_enter_and_prepare_for_io(
ut_a(success);
/* InnoDB data files cannot shrink. */
ut_a(space->size >= size);
+ if (size > space->committed_size) {
+ space->committed_size = size;
+ }
/* There could be multiple concurrent I/O requests for
this tablespace (multiple threads trying to extend
@@ -1195,13 +1191,14 @@ fil_node_close_to_free(
if (fil_buffering_disabled(space)) {
- ut_ad(!space->is_in_unflushed_spaces());
+ ut_ad(!space->is_in_unflushed_spaces);
ut_ad(fil_space_is_flushed(space));
- } else if (space->is_in_unflushed_spaces()
+ } else if (space->is_in_unflushed_spaces
&& fil_space_is_flushed(space)) {
- UT_LIST_REMOVE(fil_system->unflushed_spaces, space);
+ fil_system->unflushed_spaces.remove(*space);
+ space->is_in_unflushed_spaces = false;
}
fil_node_close_file(node);
@@ -1228,16 +1225,18 @@ fil_space_detach(
HASH_DELETE(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(space->name), space);
- if (space->is_in_unflushed_spaces()) {
+ if (space->is_in_unflushed_spaces) {
ut_ad(!fil_buffering_disabled(space));
- UT_LIST_REMOVE(fil_system->unflushed_spaces, space);
+ fil_system->unflushed_spaces.remove(*space);
+ space->is_in_unflushed_spaces = false;
}
- if (space->is_in_rotation_list()) {
+ if (space->is_in_rotation_list) {
- UT_LIST_REMOVE(fil_system->rotation_list, space);
+ fil_system->rotation_list.remove(*space);
+ space->is_in_rotation_list = false;
}
UT_LIST_REMOVE(fil_system->space_list, space);
@@ -1463,7 +1462,8 @@ fil_space_create(
srv_encrypt_tables)) {
/* Key rotation is not enabled, need to inform background
encryption threads. */
- UT_LIST_ADD_LAST(fil_system->rotation_list, space);
+ fil_system->rotation_list.push_back(*space);
+ space->is_in_rotation_list = true;
mutex_exit(&fil_system->mutex);
mutex_enter(&fil_crypt_threads_mutex);
os_event_set(fil_crypt_threads_event);
@@ -1799,8 +1799,7 @@ fil_init(
ut_a(hash_size > 0);
ut_a(max_n_open > 0);
- fil_system = static_cast<fil_system_t*>(
- ut_zalloc_nokey(sizeof(*fil_system)));
+ fil_system = new fil_system_t();
mutex_create(LATCH_ID_FIL_SYSTEM, &fil_system->mutex);
@@ -1809,9 +1808,6 @@ fil_init(
UT_LIST_INIT(fil_system->LRU, &fil_node_t::LRU);
UT_LIST_INIT(fil_system->space_list, &fil_space_t::space_list);
- UT_LIST_INIT(fil_system->rotation_list, &fil_space_t::rotation_list);
- UT_LIST_INIT(fil_system->unflushed_spaces,
- &fil_space_t::unflushed_spaces);
UT_LIST_INIT(fil_system->named_spaces, &fil_space_t::named_spaces);
fil_system->max_n_open = max_n_open;
@@ -2867,14 +2863,9 @@ bool fil_table_accessible(const dict_table_t* table)
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
+@param[in] if_exists whether to ignore missing tablespace
@return DB_SUCCESS or error */
-dberr_t
-fil_delete_tablespace(
- ulint id
-#ifdef BTR_CUR_HASH_ADAPT
- , bool drop_ahi /*!< whether to drop the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
- )
+dberr_t fil_delete_tablespace(ulint id, bool if_exists)
{
char* path = 0;
fil_space_t* space = 0;
@@ -2885,10 +2876,11 @@ fil_delete_tablespace(
id, FIL_OPERATION_DELETE, &space, &path);
if (err != DB_SUCCESS) {
-
- ib::error() << "Cannot delete tablespace " << id
- << " because it is not found in the tablespace"
- " memory cache.";
+ if (!if_exists) {
+ ib::error() << "Cannot delete tablespace " << id
+ << " because it is not found"
+ " in the tablespace memory cache.";
+ }
return(err);
}
@@ -3129,10 +3121,10 @@ fil_reinit_space_header_for_table(
dict_table_x_unlock_indexes(table);
row_mysql_unlock_data_dictionary(trx);
+ DEBUG_SYNC_C("buffer_pool_scan");
/* Lock the search latch in shared mode to prevent user
from disabling AHI during the scan */
btr_search_s_lock_all();
- DEBUG_SYNC_C("buffer_pool_scan");
buf_LRU_flush_or_remove_pages(id, NULL);
btr_search_s_unlock_all();
@@ -3233,12 +3225,12 @@ fil_discard_tablespace(
case DB_IO_ERROR:
ib::warn() << "While deleting tablespace " << id
<< " in DISCARD TABLESPACE. File rename/delete"
- " failed: " << ut_strerr(err);
+ " failed: " << err;
break;
case DB_TABLESPACE_NOT_FOUND:
ib::warn() << "Cannot delete tablespace " << id
- << " in DISCARD TABLESPACE: " << ut_strerr(err);
+ << " in DISCARD TABLESPACE: " << err;
break;
default:
@@ -4263,6 +4255,7 @@ fil_ibd_discover(
case SRV_OPERATION_RESTORE_DELTA:
ut_ad(0);
break;
+ case SRV_OPERATION_RESTORE_ROLLBACK_XA:
case SRV_OPERATION_RESTORE_EXPORT:
case SRV_OPERATION_RESTORE:
break;
@@ -4360,7 +4353,7 @@ fil_ibd_load(
return(FIL_LOAD_OK);
}
- if (srv_operation == SRV_OPERATION_RESTORE) {
+ if (is_mariabackup_restore()) {
/* Replace absolute DATA DIRECTORY file paths with
short names relative to the backup directory. */
if (const char* name = strrchr(filename, OS_PATH_SEPARATOR)) {
@@ -4760,16 +4753,17 @@ fil_node_complete_io(fil_node_t* node, const IORequest& type)
/* We don't need to keep track of unflushed
changes as user has explicitly disabled
buffering. */
- ut_ad(!node->space->is_in_unflushed_spaces());
+ ut_ad(!node->space->is_in_unflushed_spaces);
ut_ad(node->needs_flush == false);
} else {
node->needs_flush = true;
- if (!node->space->is_in_unflushed_spaces()) {
+ if (!node->space->is_in_unflushed_spaces) {
- UT_LIST_ADD_FIRST(fil_system->unflushed_spaces,
- node->space);
+ fil_system->unflushed_spaces.push_front(
+ *node->space);
+ node->space->is_in_unflushed_spaces = true;
}
}
}
@@ -5180,7 +5174,7 @@ fil_aio_wait(
ib::error() << "Failed to read file '"
<< node->name
<< "' at offset " << offset
- << ": " << ut_strerr(err);
+ << ": " << err;
}
fil_space_release_for_io(space);
@@ -5237,7 +5231,6 @@ void
fil_flush_file_spaces(
fil_type_t purpose)
{
- fil_space_t* space;
ulint* space_ids;
ulint n_space_ids;
@@ -5245,30 +5238,25 @@ fil_flush_file_spaces(
mutex_enter(&fil_system->mutex);
- n_space_ids = UT_LIST_GET_LEN(fil_system->unflushed_spaces);
+ n_space_ids = fil_system->unflushed_spaces.size();
if (n_space_ids == 0) {
mutex_exit(&fil_system->mutex);
return;
}
- /* Assemble a list of space ids to flush. Previously, we
- traversed fil_system->unflushed_spaces and called UT_LIST_GET_NEXT()
- on a space that was just removed from the list by fil_flush().
- Thus, the space could be dropped and the memory overwritten. */
space_ids = static_cast<ulint*>(
ut_malloc_nokey(n_space_ids * sizeof(*space_ids)));
n_space_ids = 0;
- for (space = UT_LIST_GET_FIRST(fil_system->unflushed_spaces);
- space;
- space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
-
- if (space->purpose == purpose
- && !space->is_stopping()) {
+ for (sized_ilist<fil_space_t, unflushed_spaces_tag_t>::iterator it
+ = fil_system->unflushed_spaces.begin(),
+ end = fil_system->unflushed_spaces.end();
+ it != end; ++it) {
- space_ids[n_space_ids++] = space->id;
+ if (it->purpose == purpose && !it->is_stopping()) {
+ space_ids[n_space_ids++] = it->id;
}
}
@@ -5323,24 +5311,15 @@ bool
fil_validate(void)
/*==============*/
{
- fil_space_t* space;
fil_node_t* fil_node;
ulint n_open = 0;
mutex_enter(&fil_system->mutex);
- /* Look for spaces in the hash table */
-
- for (ulint i = 0; i < hash_get_n_cells(fil_system->spaces); i++) {
-
- for (space = static_cast<fil_space_t*>(
- HASH_GET_FIRST(fil_system->spaces, i));
- space != 0;
- space = static_cast<fil_space_t*>(
- HASH_GET_NEXT(hash, space))) {
-
- n_open += Check::validate(space);
- }
+ for (fil_space_t *space = UT_LIST_GET_FIRST(fil_system->space_list);
+ space != NULL;
+ space = UT_LIST_GET_NEXT(space_list, space)) {
+ n_open += Check::validate(space);
}
ut_a(fil_system->n_open == n_open);
@@ -5420,12 +5399,12 @@ fil_close(void)
hash_table_free(fil_system->name_hash);
ut_a(UT_LIST_GET_LEN(fil_system->LRU) == 0);
- ut_a(UT_LIST_GET_LEN(fil_system->unflushed_spaces) == 0);
+ ut_a(fil_system->unflushed_spaces.size() == 0);
ut_a(UT_LIST_GET_LEN(fil_system->space_list) == 0);
mutex_free(&fil_system->mutex);
- ut_free(fil_system);
+ delete fil_system;
fil_system = NULL;
fil_space_crypt_cleanup();
@@ -5455,51 +5434,6 @@ fil_delete_file(
}
}
-/**
-Iterate over all the spaces in the space list and fetch the
-tablespace names. It will return a copy of the name that must be
-freed by the caller using: delete[].
-@return DB_SUCCESS if all OK. */
-dberr_t
-fil_get_space_names(
-/*================*/
- space_name_list_t& space_name_list)
- /*!< in/out: List to append to */
-{
- fil_space_t* space;
- dberr_t err = DB_SUCCESS;
-
- mutex_enter(&fil_system->mutex);
-
- for (space = UT_LIST_GET_FIRST(fil_system->space_list);
- space != NULL;
- space = UT_LIST_GET_NEXT(space_list, space)) {
-
- if (space->purpose == FIL_TYPE_TABLESPACE) {
- ulint len;
- char* name;
-
- len = ::strlen(space->name);
- name = UT_NEW_ARRAY_NOKEY(char, len + 1);
-
- if (name == 0) {
- /* Caller to free elements allocated so far. */
- err = DB_OUT_OF_MEMORY;
- break;
- }
-
- memcpy(name, space->name, len);
- name[len] = 0;
-
- space_name_list.push_back(name);
- }
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(err);
-}
-
/** Generate redo log for swapping two .ibd files
@param[in] old_table old table
@param[in] new_table new table
@@ -5931,134 +5865,6 @@ fil_space_t::release_free_extents(ulint n_reserved)
n_reserved_extents -= n_reserved;
}
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-fil_space_t*
-fil_space_next(fil_space_t* prev_space)
-{
- fil_space_t* space=prev_space;
-
- mutex_enter(&fil_system->mutex);
-
- if (prev_space == NULL) {
- space = UT_LIST_GET_FIRST(fil_system->space_list);
-
- /* We can trust that space is not NULL because at least the
- system tablespace is always present and loaded first. */
- space->n_pending_ops++;
- } else {
- ut_ad(space->n_pending_ops > 0);
-
- /* Move on to the next fil_space_t */
- space->n_pending_ops--;
- space = UT_LIST_GET_NEXT(space_list, space);
-
- /* Skip spaces that are being created by
- fil_ibd_create(), or dropped, or !tablespace. */
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping()
- || space->purpose != FIL_TYPE_TABLESPACE)) {
- space = UT_LIST_GET_NEXT(space_list, space);
- }
-
- if (space != NULL) {
- space->n_pending_ops++;
- }
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(space);
-}
-
-/**
-Remove space from key rotation list if there are no more
-pending operations.
-@param[in,out] space Tablespace */
-static
-void
-fil_space_remove_from_keyrotation(fil_space_t* space)
-{
- ut_ad(mutex_own(&fil_system->mutex));
- ut_ad(space);
-
- if (space->n_pending_ops == 0 && space->is_in_rotation_list()) {
- ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
- UT_LIST_REMOVE(fil_system->rotation_list, space);
- }
-}
-
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Previous tablespace or NULL to start
- from beginning of fil_system->rotation list
-@param[in] recheck recheck of the tablespace is needed or
- still encryption thread does write page0 for it
-@param[in] key_version key version of the key state thread
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last */
-fil_space_t*
-fil_system_t::keyrotate_next(
- fil_space_t* prev_space,
- bool recheck,
- uint key_version)
-{
- mutex_enter(&fil_system->mutex);
-
- /* If one of the encryption threads already started the encryption
- of the table then don't remove the unencrypted spaces from
- rotation list
-
- If there is a change in innodb_encrypt_tables variables value then
- don't remove the last processed tablespace from the rotation list. */
- const bool remove = ((!recheck || prev_space->crypt_data)
- && (!key_version == !srv_encrypt_tables));
-
- fil_space_t* space = prev_space;
-
- if (prev_space == NULL) {
- space = UT_LIST_GET_FIRST(fil_system->rotation_list);
-
- /* We can trust that space is not NULL because we
- checked list length above */
- } else {
- ut_ad(space->n_pending_ops > 0);
-
- /* Move on to the next fil_space_t */
- space->n_pending_ops--;
-
- space = UT_LIST_GET_NEXT(rotation_list, space);
-
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping())) {
- space = UT_LIST_GET_NEXT(rotation_list, space);
- }
-
- if (remove) {
- fil_space_remove_from_keyrotation(prev_space);
- }
- }
-
- if (space != NULL) {
- space->n_pending_ops++;
- }
-
- mutex_exit(&fil_system->mutex);
- return(space);
-}
-
/** Determine the block size of the data file.
@param[in] space tablespace
@param[in] offset page number
@@ -6131,21 +5937,3 @@ fil_space_set_punch_hole(
{
node->space->punch_hole = val;
}
-
-/** Checks that this tablespace in a list of unflushed tablespaces.
-@return true if in a list */
-bool fil_space_t::is_in_unflushed_spaces() const {
- ut_ad(mutex_own(&fil_system->mutex));
-
- return fil_system->unflushed_spaces.start == this
- || unflushed_spaces.next || unflushed_spaces.prev;
-}
-
-/** Checks that this tablespace needs key rotation.
-@return true if in a rotation list */
-bool fil_space_t::is_in_rotation_list() const {
- ut_ad(mutex_own(&fil_system->mutex));
-
- return fil_system->rotation_list.start == this || rotation_list.next
- || rotation_list.prev;
-}
diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc
index 89b8efc4e9b..4f7fa89c662 100644
--- a/storage/innobase/fil/fil0pagecompress.cc
+++ b/storage/innobase/fil/fil0pagecompress.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2018, MariaDB Corporation.
+Copyright (C) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -27,7 +27,6 @@ Updated 14/02/2015
#include "fil0fil.h"
#include "fil0pagecompress.h"
-#include <debug_sync.h>
#include <my_dbug.h>
#include "mem0mem.h"
@@ -236,25 +235,12 @@ success:
/* Set up the actual payload lenght */
mach_write_to_2(out_buf+FIL_PAGE_DATA, write_size);
-#ifdef UNIV_DEBUG
- /* Verify */
ut_ad(fil_page_is_compressed(out_buf) || fil_page_is_compressed_encrypted(out_buf));
ut_ad(mach_read_from_4(out_buf+FIL_PAGE_SPACE_OR_CHKSUM) == BUF_NO_CHECKSUM_MAGIC);
ut_ad(mach_read_from_2(out_buf+FIL_PAGE_DATA) == write_size);
ut_ad(mach_read_from_8(out_buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) == (ulint)comp_method ||
mach_read_from_2(out_buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE) == (ulint)comp_method);
- /* Verify that page can be decompressed */
- {
- page_t tmp_buf[UNIV_PAGE_SIZE_MAX];
- page_t page[UNIV_PAGE_SIZE_MAX];
- memcpy(page, out_buf, srv_page_size);
- ut_ad(fil_page_decompress(tmp_buf, page));
- ut_ad(!buf_page_is_corrupted(false, page, univ_page_size,
- NULL));
- }
-#endif /* UNIV_DEBUG */
-
write_size+=header_len;
if (block_size <= 0) {
diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc
index 673e74cfb3d..b367ed37c2b 100644
--- a/storage/innobase/fsp/fsp0file.cc
+++ b/storage/innobase/fsp/fsp0file.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -331,7 +331,7 @@ Datafile::read_first_page(bool read_only_mode)
ib::error()
<< "Cannot read first page of '"
<< m_filepath << "' "
- << ut_strerr(err);
+ << err;
break;
}
}
@@ -768,10 +768,10 @@ Datafile::restore_from_doublewrite()
}
/* Find if double write buffer contains page_no of given space id. */
- const byte* page = recv_sys->dblwr.find_page(m_space_id, 0);
const page_id_t page_id(m_space_id, 0);
+ const byte* page = recv_sys->dblwr.find_page(page_id);
- if (page == NULL) {
+ if (!page) {
/* If the first page of the given user tablespace is not there
in the doublewrite buffer, then the recovery is going to fail
now. Hence this is treated as an error. */
@@ -788,15 +788,10 @@ Datafile::restore_from_doublewrite()
FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
if (!fsp_flags_is_valid(flags, m_space_id)) {
- ulint cflags = fsp_flags_convert_from_101(flags);
- if (cflags == ULINT_UNDEFINED) {
- ib::warn()
- << "Ignoring a doublewrite copy of page "
- << page_id
- << " due to invalid flags " << ib::hex(flags);
- return(true);
- }
- flags = cflags;
+ flags = fsp_flags_convert_from_101(flags);
+ /* recv_dblwr_t::validate_page() inside find_page()
+ checked this already. */
+ ut_ad(flags != ULINT_UNDEFINED);
/* The flags on the page should be converted later. */
}
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 78d562be9a3..58aa18ac323 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -117,7 +117,6 @@ to minimize file space fragmentation.
@param[in] direction if the new page is needed because of
an index page split, and records are inserted there in order, into which
direction they go alphabetically: FSP_DOWN, FSP_UP, FSP_NO_DIR
-@param[in] rw_latch RW_SX_LATCH, RW_X_LATCH
@param[in,out] mtr mini-transaction
@param[in,out] init_mtr mtr or another mini-transaction in
which the page should be initialized. If init_mtr != mtr, but the page is
@@ -136,7 +135,6 @@ fseg_alloc_free_page_low(
fseg_inode_t* seg_inode,
ulint hint,
byte direction,
- rw_lock_type_t rw_latch,
mtr_t* mtr,
mtr_t* init_mtr
#ifdef UNIV_DEBUG
@@ -224,7 +222,9 @@ xdes_set_bit(
ulint bit_index;
ulint descr_byte;
- ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_SX_FIX));
+ ut_ad(mtr_memo_contains_page(
+ mtr, descr,
+ MTR_MEMO_PAGE_SX_FIX | MTR_MEMO_PAGE_X_FIX));
ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT));
ut_ad(offset < FSP_EXTENT_SIZE);
@@ -351,7 +351,9 @@ xdes_set_state(
ut_ad(descr && mtr);
ut_ad(state >= XDES_FREE);
ut_ad(state <= XDES_FSEG);
- ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_SX_FIX));
+ ut_ad(mtr_memo_contains_page(
+ mtr, descr,
+ MTR_MEMO_PAGE_SX_FIX | MTR_MEMO_PAGE_X_FIX));
mlog_write_ulint(descr + XDES_STATE, state, MLOG_4BYTES, mtr);
}
@@ -388,7 +390,9 @@ xdes_init(
ulint i;
ut_ad(descr && mtr);
- ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_SX_FIX));
+ ut_ad(mtr_memo_contains_page(
+ mtr, descr,
+ MTR_MEMO_PAGE_SX_FIX | MTR_MEMO_PAGE_X_FIX));
ut_ad((XDES_SIZE - XDES_BITMAP) % 4 == 0);
for (i = XDES_BITMAP; i < XDES_SIZE; i += 4) {
@@ -422,8 +426,9 @@ xdes_get_descriptor_with_space_hdr(
ulint size;
ulint descr_page_no;
page_t* descr_page;
- ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_X_LOCK));
- ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_SX_FIX));
+ ut_ad(mtr_memo_contains(mtr, space, MTR_MEMO_SPACE_X_LOCK));
+ ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_SX_FIX)
+ || mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET);
/* Read free limit and space size */
limit = mach_read_from_4(sp_header + FSP_FREE_LIMIT);
@@ -566,7 +571,7 @@ xdes_lst_get_descriptor(
fil_addr_t lst_node,
mtr_t* mtr)
{
- ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_X_LOCK));
+ ut_ad(mtr_memo_contains(mtr, space, MTR_MEMO_SPACE_X_LOCK));
ut_ad(page_size.equals_to(page_size_t(space->flags)));
return(fut_get_ptr(space->id, page_size, lst_node, RW_SX_LATCH, mtr)
- XDES_FLST_NODE);
@@ -701,7 +706,6 @@ fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
const page_size_t page_size(space->flags);
block = buf_page_create(page_id, page_size, mtr);
- buf_page_get(page_id, page_size, RW_SX_LATCH, mtr);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
space->size_in_header = size;
@@ -1100,9 +1104,6 @@ fsp_fill_free_list(
block = buf_page_create(
page_id, page_size, mtr);
- buf_page_get(
- page_id, page_size, RW_SX_LATCH, mtr);
-
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
fsp_init_file_page(space, block, mtr);
@@ -1112,42 +1113,19 @@ fsp_fill_free_list(
MLOG_2BYTES, mtr);
}
- /* Initialize the ibuf bitmap page in a separate
- mini-transaction because it is low in the latching
- order, and we must be able to release its latch.
- Note: Insert-Buffering is disabled for tables that
- reside in the temp-tablespace. */
if (space->purpose != FIL_TYPE_TEMPORARY) {
- mtr_t ibuf_mtr;
-
- mtr_start(&ibuf_mtr);
- ibuf_mtr.set_named_space(space);
-
- /* Avoid logging while truncate table
- fix-up is active. */
- if (srv_is_tablespace_truncated(space->id)) {
- mtr_set_log_mode(
- &ibuf_mtr, MTR_LOG_NO_REDO);
- }
-
const page_id_t page_id(
space->id,
i + FSP_IBUF_BITMAP_OFFSET);
block = buf_page_create(
- page_id, page_size, &ibuf_mtr);
-
- buf_page_get(
- page_id, page_size, RW_SX_LATCH,
- &ibuf_mtr);
+ page_id, page_size, mtr);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
- fsp_init_file_page(space, block, &ibuf_mtr);
-
- ibuf_bitmap_page_init(block, &ibuf_mtr);
+ fsp_init_file_page(space, block, mtr);
- mtr_commit(&ibuf_mtr);
+ ibuf_bitmap_page_init(block, mtr);
}
}
@@ -1288,7 +1266,6 @@ x-latched only by mtr, and freed in mtr in that case.
@param[in,out] space tablespace
@param[in] offset page number of the allocated page
@param[in] page_size page size of the allocated page
-@param[in] rw_latch RW_SX_LATCH, RW_X_LATCH
@param[in,out] mtr mini-transaction of the allocation
@param[in,out] init_mtr mini-transaction for initializing the page
@return block, initialized if init_mtr==mtr
@@ -1299,7 +1276,6 @@ fsp_page_create(
fil_space_t* space,
page_no_t offset,
const page_size_t& page_size,
- rw_lock_type_t rw_latch,
mtr_t* mtr,
mtr_t* init_mtr)
{
@@ -1309,26 +1285,10 @@ fsp_page_create(
page_size, init_mtr);
ut_d(bool latched = mtr_memo_contains_flagged(mtr, block,
- MTR_MEMO_PAGE_X_FIX
- | MTR_MEMO_PAGE_SX_FIX));
-
- ut_ad(rw_latch == RW_X_LATCH || rw_latch == RW_SX_LATCH);
-
- /* Mimic buf_page_get(), but avoid the buf_pool->page_hash lookup. */
- if (rw_latch == RW_X_LATCH) {
- rw_lock_x_lock(&block->lock);
- } else {
- rw_lock_sx_lock(&block->lock);
- }
-
- buf_block_buf_fix_inc(block, __FILE__, __LINE__);
- mtr_memo_push(init_mtr, block, rw_latch == RW_X_LATCH
- ? MTR_MEMO_PAGE_X_FIX : MTR_MEMO_PAGE_SX_FIX);
+ MTR_MEMO_PAGE_X_FIX));
if (init_mtr == mtr
- || (rw_latch == RW_X_LATCH
- ? rw_lock_get_x_lock_count(&block->lock) == 1
- : rw_lock_get_sx_lock_count(&block->lock) == 1)) {
+ || rw_lock_get_x_lock_count(&block->lock) == 1) {
/* Initialize the page, unless it was already
SX-latched in mtr. (In this case, we would want to
@@ -1345,7 +1305,6 @@ The page is marked as used.
@param[in,out] space tablespace
@param[in] page_size page size
@param[in] hint hint of which page would be desirable
-@param[in] rw_latch RW_SX_LATCH, RW_X_LATCH
@param[in,out] mtr mini-transaction
@param[in,out] init_mtr mini-transaction in which the page should be
initialized (may be the same as mtr)
@@ -1359,7 +1318,6 @@ fsp_alloc_free_page(
fil_space_t* space,
const page_size_t& page_size,
ulint hint,
- rw_lock_type_t rw_latch,
mtr_t* mtr,
mtr_t* init_mtr)
{
@@ -1437,7 +1395,7 @@ fsp_alloc_free_page(
ut_a(!is_system_tablespace(space_id));
if (page_no >= FSP_EXTENT_SIZE) {
ib::error() << "Trying to extend a single-table"
- " tablespace " << space << " , by single"
+ " tablespace " << space->name << " , by single"
" page(s) though the space size " << space_size
<< ". Page no " << page_no << ".";
return(NULL);
@@ -1451,8 +1409,7 @@ fsp_alloc_free_page(
}
fsp_alloc_from_free_frag(header, descr, free, mtr);
- return(fsp_page_create(space, page_no, page_size, rw_latch,
- mtr, init_mtr));
+ return(fsp_page_create(space, page_no, page_size, mtr, init_mtr));
}
/** Frees a single page of a space.
@@ -1569,7 +1526,7 @@ fsp_free_extent(
fsp_header_t* header;
xdes_t* descr;
- ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_X_LOCK));
+ ut_ad(mtr_memo_contains(mtr, space, MTR_MEMO_SPACE_X_LOCK));
header = fsp_get_space_header(space, page_size, mtr);
@@ -1689,8 +1646,7 @@ fsp_alloc_seg_inode_page(
const page_size_t page_size(space->flags);
- block = fsp_alloc_free_page(
- space, page_size, 0, RW_SX_LATCH, mtr, mtr);
+ block = fsp_alloc_free_page(space, page_size, 0, mtr, mtr);
if (block == NULL) {
@@ -1698,7 +1654,7 @@ fsp_alloc_seg_inode_page(
}
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
- ut_ad(rw_lock_get_sx_lock_count(&block->lock) == 1);
+ ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
mlog_write_ulint(block->frame + FIL_PAGE_TYPE, FIL_PAGE_INODE,
MLOG_2BYTES, mtr);
@@ -2007,32 +1963,36 @@ fseg_get_n_frag_pages(
return(count);
}
-/**********************************************************************//**
-Creates a new segment.
+/** Creates a new segment.
+@param[in] space_id space_id
+@param[in] byte_offset byte offset of the created segment
+ header on the page
+@param[in] has_done_reservation TRUE if the caller has already
+ done the reservation for the pages
+ with fsp_reserve_free_externts
+ (at least 2 extents: one for
+ the inode and the other for the
+ segment) then there is no need to do
+ the check for this individual
+ operation
+@param[in,out] mtr mini-transaction
+@param[in] block block where the segment header is
+ placed. If it is null then new page
+ will be allocated and it will belong
+ to the created segment
@return the block where the segment header is placed, x-latched, NULL
if could not create segment because of lack of space */
buf_block_t*
fseg_create_general(
-/*================*/
- ulint space_id,/*!< in: space id */
- ulint page, /*!< in: page where the segment header is placed: if
- this is != 0, the page must belong to another segment,
- if this is 0, a new page will be allocated and it
- will belong to the created segment */
- ulint byte_offset, /*!< in: byte offset of the created segment header
- on the page */
- ibool has_done_reservation, /*!< in: TRUE if the caller has already
- done the reservation for the pages with
- fsp_reserve_free_extents (at least 2 extents: one for
- the inode and the other for the segment) then there is
- no need to do the check for this individual
- operation */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+ ulint space_id,
+ ulint byte_offset,
+ ibool has_done_reservation,
+ mtr_t* mtr,
+ buf_block_t* block)
{
fsp_header_t* space_header;
fseg_inode_t* inode;
ib_id_t seg_id;
- buf_block_t* block = 0; /* remove warning */
fseg_header_t* header = 0; /* remove warning */
ulint n_reserved;
ulint i;
@@ -2047,14 +2007,11 @@ fseg_create_general(
const page_size_t page_size(space->flags);
ut_d(space->modify_check(*mtr));
- if (page != 0) {
- block = buf_page_get(page_id_t(space_id, page), page_size,
- RW_SX_LATCH, mtr);
-
+ if (block) {
header = byte_offset + buf_block_get_frame(block);
- const ulint type = space_id == TRX_SYS_SPACE
- && page == TRX_SYS_PAGE_NO
+ const ulint type = block->page.id == page_id_t(TRX_SYS_SPACE,
+ TRX_SYS_PAGE_NO)
? FIL_PAGE_TYPE_TRX_SYS
: FIL_PAGE_TYPE_SYS;
@@ -2095,9 +2052,9 @@ fseg_create_general(
fseg_set_nth_frag_page_no(inode, i, FIL_NULL, mtr);
}
- if (page == 0) {
+ if (!block) {
block = fseg_alloc_free_page_low(space, page_size,
- inode, 0, FSP_UP, RW_SX_LATCH,
+ inode, 0, FSP_UP,
mtr, mtr
#ifdef UNIV_DEBUG
, has_done_reservation
@@ -2115,7 +2072,7 @@ fseg_create_general(
goto funct_exit;
}
- ut_ad(rw_lock_get_sx_lock_count(&block->lock) == 1);
+ ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
header = byte_offset + buf_block_get_frame(block);
mlog_write_ulint(buf_block_get_frame(block) + FIL_PAGE_TYPE,
@@ -2140,23 +2097,25 @@ funct_exit:
DBUG_RETURN(block);
}
-/**********************************************************************//**
-Creates a new segment.
+/** Creates a new segment.
+@param[in] space space id
+@param[in] byte_offset byte offset of the created segment header
+ on the page
+@param[in,out] mtr mini-transaction
+@param[in,out] block block where segment header is placed;
+ If it is null then new page will be
+ allocated and it will belong to
+ the created segment
@return the block where the segment header is placed, x-latched, NULL
if could not create segment because of lack of space */
buf_block_t*
fseg_create(
-/*========*/
- ulint space, /*!< in: space id */
- ulint page, /*!< in: page where the segment header is placed: if
- this is != 0, the page must belong to another segment,
- if this is 0, a new page will be allocated and it
- will belong to the created segment */
- ulint byte_offset, /*!< in: byte offset of the created segment header
- on the page */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+ ulint space,
+ ulint byte_offset,
+ mtr_t* mtr,
+ buf_block_t* block)
{
- return(fseg_create_general(space, page, byte_offset, FALSE, mtr));
+ return(fseg_create_general(space, byte_offset, FALSE, mtr, block));
}
/**********************************************************************//**
@@ -2354,7 +2313,6 @@ minimize file space fragmentation.
@param[in] direction if the new page is needed because of
an index page split, and records are inserted there in order, into which
direction they go alphabetically: FSP_DOWN, FSP_UP, FSP_NO_DIR
-@param[in] rw_latch RW_SX_LATCH, RW_X_LATCH
@param[in,out] mtr mini-transaction
@param[in,out] init_mtr mtr or another mini-transaction in
which the page should be initialized. If init_mtr != mtr, but the page is
@@ -2373,7 +2331,6 @@ fseg_alloc_free_page_low(
fseg_inode_t* seg_inode,
ulint hint,
byte direction,
- rw_lock_type_t rw_latch,
mtr_t* mtr,
mtr_t* init_mtr
#ifdef UNIV_DEBUG
@@ -2516,7 +2473,7 @@ take_hinted_page:
/* 6. We allocate an individual page from the space
===================================================*/
buf_block_t* block = fsp_alloc_free_page(
- space, page_size, hint, rw_latch, mtr, init_mtr);
+ space, page_size, hint, mtr, init_mtr);
ut_ad(!has_done_reservation || block != NULL);
@@ -2597,8 +2554,7 @@ got_hinted_page:
fseg_mark_page_used(seg_inode, ret_page, ret_descr, mtr);
}
- return(fsp_page_create(space, ret_page, page_size, rw_latch,
- mtr, init_mtr));
+ return(fsp_page_create(space, ret_page, page_size, mtr, init_mtr));
}
/**********************************************************************//**
@@ -2653,7 +2609,7 @@ fseg_alloc_free_page_general(
block = fseg_alloc_free_page_low(space, page_size,
inode, hint, direction,
- RW_X_LATCH, mtr, init_mtr
+ mtr, init_mtr
#ifdef UNIV_DEBUG
, has_done_reservation
#endif /* UNIV_DEBUG */
@@ -2976,8 +2932,6 @@ fseg_mark_page_used(
@param[in,out] space tablespace
@param[in] offset page number
@param[in] page_size page size
-@param[in] ahi whether we may need to drop the adaptive
-hash index
@param[in,out] mtr mini-transaction */
static
void
@@ -2986,9 +2940,6 @@ fseg_free_page_low(
fil_space_t* space,
page_no_t offset,
const page_size_t& page_size,
-#ifdef BTR_CUR_HASH_ADAPT
- bool ahi,
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr)
{
xdes_t* descr;
@@ -3003,15 +2954,6 @@ fseg_free_page_low(
== FSEG_MAGIC_N_VALUE);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
ut_d(space->modify_check(*mtr));
-#ifdef BTR_CUR_HASH_ADAPT
- /* Drop search system page hash index if the page is found in
- the pool and is hashed */
-
- if (ahi) {
- btr_search_drop_page_hash_when_freed(
- page_id_t(space->id, offset));
- }
-#endif /* BTR_CUR_HASH_ADAPT */
descr = xdes_get_descriptor(space, offset, page_size, mtr);
@@ -3097,22 +3039,13 @@ fseg_free_page_low(
}
}
-#ifndef BTR_CUR_HASH_ADAPT
-# define fseg_free_page_low(inode, space, offset, page_size, ahi, mtr) \
- fseg_free_page_low(inode, space, offset, page_size, mtr)
-#endif /* !BTR_CUR_HASH_ADAPT */
-
/**********************************************************************//**
Frees a single page of a segment. */
void
-fseg_free_page_func(
+fseg_free_page(
fseg_header_t* seg_header, /*!< in: segment header */
ulint space_id,/*!< in: space id */
ulint page, /*!< in: page offset */
-#ifdef BTR_CUR_HASH_ADAPT
- bool ahi, /*!< in: whether we may need to drop
- the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
DBUG_ENTER("fseg_free_page");
@@ -3128,7 +3061,7 @@ fseg_free_page_func(
&iblock);
fil_block_check_type(*iblock, FIL_PAGE_INODE, mtr);
- fseg_free_page_low(seg_inode, space, page, page_size, ahi, mtr);
+ fseg_free_page_low(seg_inode, space, page, page_size, mtr);
ut_d(buf_page_set_file_page_was_freed(page_id_t(space_id, page)));
@@ -3169,8 +3102,6 @@ fseg_page_is_free(fil_space_t* space, unsigned page)
@param[in,out] space tablespace
@param[in] page_size page size
@param[in] page page number in the extent
-@param[in] ahi whether we may need to drop
- the adaptive hash index
@param[in,out] mtr mini-transaction */
MY_ATTRIBUTE((nonnull))
static
@@ -3180,12 +3111,8 @@ fseg_free_extent(
fil_space_t* space,
const page_size_t& page_size,
ulint page,
-#ifdef BTR_CUR_HASH_ADAPT
- bool ahi,
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr)
{
- ulint first_page_in_extent;
xdes_t* descr;
ulint not_full_n_used;
ulint descr_n_used;
@@ -3199,25 +3126,7 @@ fseg_free_extent(
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
ut_d(space->modify_check(*mtr));
-
- first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
-
-#ifdef BTR_CUR_HASH_ADAPT
- if (ahi) {
- for (ulint i = 0; i < FSP_EXTENT_SIZE; i++) {
- if (!xdes_mtr_get_bit(descr, XDES_FREE_BIT, i, mtr)) {
-
- /* Drop search system page hash index
- if the page is found in the pool and
- is hashed */
-
- btr_search_drop_page_hash_when_freed(
- page_id_t(space->id,
- first_page_in_extent + i));
- }
- }
- }
-#endif /* BTR_CUR_HASH_ADAPT */
+ ut_d(ulint first_page_in_extent = page - (page % FSP_EXTENT_SIZE));
if (xdes_is_full(descr, mtr)) {
flst_remove(seg_inode + FSEG_FULL,
@@ -3250,27 +3159,18 @@ fseg_free_extent(
#endif /* UNIV_DEBUG */
}
-#ifndef BTR_CUR_HASH_ADAPT
-# define fseg_free_extent(inode, space, page_size, page, ahi, mtr) \
- fseg_free_extent(inode, space, page_size, page, mtr)
-#endif /* !BTR_CUR_HASH_ADAPT */
-
/**********************************************************************//**
Frees part of a segment. This function can be used to free a segment by
repeatedly calling this function in different mini-transactions. Doing
the freeing in a single mini-transaction might result in too big a
mini-transaction.
-@return TRUE if freeing completed */
-ibool
-fseg_free_step_func(
+@return whether the freeing was completed */
+bool
+fseg_free_step(
fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
resides on the first page of the frag list
of the segment, this pointer becomes obsolete
after the last freeing step */
-#ifdef BTR_CUR_HASH_ADAPT
- bool ahi, /*!< in: whether we may need to drop
- the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint n;
@@ -3302,7 +3202,7 @@ fseg_free_step_func(
if (inode == NULL) {
ib::info() << "Double free of inode from "
<< page_id_t(space_id, header_page);
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(true);
}
fil_block_check_type(*iblock, FIL_PAGE_INODE, mtr);
@@ -3312,9 +3212,9 @@ fseg_free_step_func(
/* Free the extent held by the segment */
page = xdes_get_offset(descr);
- fseg_free_extent(inode, space, page_size, page, ahi, mtr);
+ fseg_free_extent(inode, space, page_size, page, mtr);
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(false);
}
/* Free a frag page */
@@ -3324,13 +3224,13 @@ fseg_free_step_func(
/* Freeing completed: free the segment inode */
fsp_free_seg_inode(space, page_size, inode, mtr);
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(true);
}
fseg_free_page_low(
inode, space,
fseg_get_nth_frag_page_no(inode, n, mtr),
- page_size, ahi, mtr);
+ page_size, mtr);
n = fseg_find_last_used_frag_page_slot(inode, mtr);
@@ -3338,24 +3238,20 @@ fseg_free_step_func(
/* Freeing completed: free the segment inode */
fsp_free_seg_inode(space, page_size, inode, mtr);
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(true);
}
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(false);
}
/**********************************************************************//**
Frees part of a segment. Differs from fseg_free_step because this function
leaves the header page unfreed.
-@return TRUE if freeing completed, except the header page */
-ibool
-fseg_free_step_not_header_func(
+@return whether the freeing was completed, except for the header page */
+bool
+fseg_free_step_not_header(
fseg_header_t* header, /*!< in: segment header which must reside on
the first fragment page of the segment */
-#ifdef BTR_CUR_HASH_ADAPT
- bool ahi, /*!< in: whether we may need to drop
- the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint n;
@@ -3381,29 +3277,27 @@ fseg_free_step_not_header_func(
/* Free the extent held by the segment */
page = xdes_get_offset(descr);
- fseg_free_extent(inode, space, page_size, page, ahi, mtr);
+ fseg_free_extent(inode, space, page_size, page, mtr);
- return(FALSE);
+ return false;
}
/* Free a frag page */
n = fseg_find_last_used_frag_page_slot(inode, mtr);
- if (n == ULINT_UNDEFINED) {
- ut_error;
- }
+ ut_a(n != ULINT_UNDEFINED);
page_no = fseg_get_nth_frag_page_no(inode, n, mtr);
if (page_no == page_get_page_no(page_align(header))) {
- return(TRUE);
+ return true;
}
- fseg_free_page_low(inode, space, page_no, page_size, ahi, mtr);
+ fseg_free_page_low(inode, space, page_no, page_size, mtr);
- return(FALSE);
+ return false;
}
/** Returns the first extent descriptor for a segment.
@@ -3470,7 +3364,7 @@ fseg_print_low(
ulint page_no;
ib_id_t seg_id;
- ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_SX_FIX));
+ ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
space = page_get_space_id(page_align(inode));
page_no = page_get_page_no(page_align(inode));
diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc
index 6130546e963..ed4340d818b 100644
--- a/storage/innobase/fts/fts0config.cc
+++ b/storage/innobase/fts/fts0config.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -148,9 +148,7 @@ fts_config_create_index_param_name(
::strcpy(name, param);
name[len] = '_';
- fts_write_object_id(index->id, name + len + 1,
- DICT_TF2_FLAG_IS_SET(index->table,
- DICT_TF2_FTS_AUX_HEX_NAME));
+ fts_write_object_id(index->id, name + len + 1);
return(name);
}
@@ -317,9 +315,7 @@ fts_config_get_index_ulint(
error = fts_config_get_index_value(trx, index, name, &value);
if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
-
- ib::error() << "(" << ut_strerr(error) << ") reading `"
- << name << "'";
+ ib::error() << "(" << error << ") reading `" << name << "'";
} else {
*int_value = strtoul((char*) value.f_str, NULL, 10);
}
@@ -357,9 +353,7 @@ fts_config_set_index_ulint(
error = fts_config_set_index_value(trx, index, name, &value);
if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
-
- ib::error() << "(" << ut_strerr(error) << ") writing `"
- << name << "'";
+ ib::error() << "(" << error << ") writing `" << name << "'";
}
ut_free(value.f_str);
@@ -391,8 +385,7 @@ fts_config_get_ulint(
error = fts_config_get_value(trx, fts_table, name, &value);
if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
- ib::error() << "(" << ut_strerr(error) << ") reading `"
- << name << "'";
+ ib::error() << "(" << error << ") reading `" << name << "'";
} else {
*int_value = strtoul((char*) value.f_str, NULL, 10);
}
@@ -430,8 +423,7 @@ fts_config_set_ulint(
error = fts_config_set_value(trx, fts_table, name, &value);
if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
- ib::error() << "(" << ut_strerr(error) << ") writing `"
- << name << "'";
+ ib::error() << "(" << error << ") writing `" << name << "'";
}
ut_free(value.f_str);
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 458f4277988..fb06d300803 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -286,7 +286,6 @@ fts_cache_destroy(fts_cache_t* cache)
{
rw_lock_free(&cache->lock);
rw_lock_free(&cache->init_lock);
- mutex_free(&cache->optimize_lock);
mutex_free(&cache->deleted_lock);
mutex_free(&cache->doc_id_lock);
os_event_destroy(cache->sync->event);
@@ -444,9 +443,9 @@ fts_read_stopword(
/******************************************************************//**
Load user defined stopword from designated user table
-@return TRUE if load operation is successful */
+@return whether the operation is successful */
static
-ibool
+bool
fts_load_user_stopword(
/*===================*/
fts_t* fts, /*!< in: FTS struct */
@@ -454,27 +453,26 @@ fts_load_user_stopword(
name */
fts_stopword_t* stopword_info) /*!< in: Stopword info */
{
- pars_info_t* info;
- que_t* graph;
- dberr_t error = DB_SUCCESS;
- ibool ret = TRUE;
- trx_t* trx;
- ibool has_lock = fts->dict_locked;
-
- trx = trx_allocate_for_background();
- trx->op_info = "Load user stopword table into FTS cache";
-
- if (!has_lock) {
+ if (!fts->dict_locked) {
mutex_enter(&dict_sys->mutex);
}
- /* Validate the user table existence and in the right
- format */
+ /* Validate the user table existence in the right format */
+ bool ret= false;
stopword_info->charset = fts_valid_stopword_table(stopword_table_name);
if (!stopword_info->charset) {
- ret = FALSE;
- goto cleanup;
- } else if (!stopword_info->cached_stopword) {
+cleanup:
+ if (!fts->dict_locked) {
+ mutex_exit(&dict_sys->mutex);
+ }
+
+ return ret;
+ }
+
+ trx_t* trx = trx_allocate_for_background();
+ trx->op_info = "Load user stopword table into FTS cache";
+
+ if (!stopword_info->cached_stopword) {
/* Create the stopword RB tree with the stopword column
charset. All comparison will use this charset */
stopword_info->cached_stopword = rbt_create_arg_cmp(
@@ -483,14 +481,14 @@ fts_load_user_stopword(
}
- info = pars_info_create();
+ pars_info_t* info = pars_info_create();
pars_info_bind_id(info, TRUE, "table_stopword", stopword_table_name);
pars_info_bind_function(info, "my_func", fts_read_stopword,
stopword_info);
- graph = fts_parse_sql_no_dict_lock(
+ que_t* graph = fts_parse_sql_no_dict_lock(
NULL,
info,
"DECLARE FUNCTION my_func;\n"
@@ -509,14 +507,13 @@ fts_load_user_stopword(
"CLOSE c;");
for (;;) {
- error = fts_eval_sql(trx, graph);
+ dberr_t error = fts_eval_sql(trx, graph);
- if (error == DB_SUCCESS) {
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
fts_sql_commit(trx);
stopword_info->status = STOPWORD_USER_TABLE;
break;
} else {
-
fts_sql_rollback(trx);
if (error == DB_LOCK_WAIT_TIMEOUT) {
@@ -525,7 +522,7 @@ fts_load_user_stopword(
trx->error_state = DB_SUCCESS;
} else {
- ib::error() << "Error '" << ut_strerr(error)
+ ib::error() << "Error '" << error
<< "' while reading user stopword"
" table.";
ret = FALSE;
@@ -535,14 +532,9 @@ fts_load_user_stopword(
}
que_graph_free(graph);
-
-cleanup:
- if (!has_lock) {
- mutex_exit(&dict_sys->mutex);
- }
-
trx_free_for_background(trx);
- return(ret);
+ ret = true;
+ goto cleanup;
}
/******************************************************************//**
@@ -591,7 +583,7 @@ fts_cache_init(
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
cache->deleted_doc_ids = ib_vector_create(
- cache->sync_heap, sizeof(fts_update_t), 4);
+ cache->sync_heap, sizeof(doc_id_t), 4);
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
/* Reset the cache data for all the FTS indexes. */
@@ -630,8 +622,6 @@ fts_cache_create(
mutex_create(LATCH_ID_FTS_DELETE, &cache->deleted_lock);
- mutex_create(LATCH_ID_FTS_OPTIMIZE, &cache->optimize_lock);
-
mutex_create(LATCH_ID_FTS_DOC_ID, &cache->doc_id_lock);
/* This is the heap used to create the cache itself. */
@@ -812,6 +802,29 @@ fts_check_cached_index(
return(TRUE);
}
+/** Clear all fts resources when there is no internal DOC_ID
+and there are no new fts index to add.
+@param[in,out] table table where fts is to be freed
+@param[in] trx transaction to drop all fts tables */
+void fts_clear_all(dict_table_t *table, trx_t *trx)
+{
+ if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID) ||
+ !table->fts ||
+ !ib_vector_is_empty(table->fts->indexes))
+ return;
+
+ for (const dict_index_t *index= dict_table_get_first_index(table);
+ index; index= dict_table_get_next_index(index))
+ if (index->type & DICT_FTS)
+ return;
+
+ fts_optimize_remove_table(table);
+
+ fts_drop_tables(trx, table);
+ fts_free(table);
+ DICT_TF2_FLAG_UNSET(table, DICT_TF2_FTS);
+}
+
/*******************************************************************//**
Drop auxiliary tables related to an FTS index
@return DB_SUCCESS or error number */
@@ -828,9 +841,10 @@ fts_drop_index(
ut_a(indexes);
if ((ib_vector_size(indexes) == 1
- && (index == static_cast<dict_index_t*>(
- ib_vector_getp(table->fts->indexes, 0))))
- || ib_vector_is_empty(indexes)) {
+ && (index == static_cast<dict_index_t*>(
+ ib_vector_getp(table->fts->indexes, 0)))
+ && DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID))
+ || ib_vector_is_empty(indexes)) {
doc_id_t current_doc_id;
doc_id_t first_doc_id;
@@ -840,27 +854,6 @@ fts_drop_index(
DICT_TF2_FLAG_UNSET(table, DICT_TF2_FTS);
- /* If Doc ID column is not added internally by FTS index,
- we can drop all FTS auxiliary tables. Otherwise, we will
- need to keep some common table such as CONFIG table, so
- as to keep track of incrementing Doc IDs */
- if (!DICT_TF2_FLAG_IS_SET(
- table, DICT_TF2_FTS_HAS_DOC_ID)) {
-
- err = fts_drop_tables(trx, table);
-
- err = fts_drop_index_tables(trx, index);
-
- while (index->index_fts_syncing
- && !trx_is_interrupted(trx)) {
- DICT_BG_YIELD(trx);
- }
-
- fts_free(table);
-
- return(err);
- }
-
while (index->index_fts_syncing
&& !trx_is_interrupted(trx)) {
DICT_BG_YIELD(trx);
@@ -1110,9 +1103,6 @@ fts_cache_clear(
index_cache->doc_stats = NULL;
}
- mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
- cache->sync_heap->arg = NULL;
-
fts_need_sync = false;
cache->total_size = 0;
@@ -1120,6 +1110,9 @@ fts_cache_clear(
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
cache->deleted_doc_ids = NULL;
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
+
+ mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
+ cache->sync_heap->arg = NULL;
}
/*********************************************************************//**
@@ -1461,9 +1454,9 @@ fts_drop_table(
error = row_drop_table_for_mysql(table_name, trx,
SQLCOM_DROP_DB, false, false);
- if (error != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
ib::error() << "Unable to drop FTS index aux table "
- << table_name << ": " << ut_strerr(error);
+ << table_name << ": " << error;
}
} else {
error = DB_FAIL;
@@ -1569,18 +1562,19 @@ fts_rename_aux_tables(
return(DB_SUCCESS);
}
-/****************************************************************//**
-Drops the common ancillary tables needed for supporting an FTS index
+/** Drops the common ancillary tables needed for supporting an FTS index
on the given table. row_mysql_lock_data_dictionary must have been called
before this.
+@param[in] trx transaction to drop fts common table
+@param[in] fts_table table with an FTS index
+@param[in] drop_orphan True if the function is used to drop
+ orphaned table
@return DB_SUCCESS or error code */
-static MY_ATTRIBUTE((nonnull, warn_unused_result))
-dberr_t
+static dberr_t
fts_drop_common_tables(
-/*===================*/
- trx_t* trx, /*!< in: transaction */
- fts_table_t* fts_table) /*!< in: table with an FTS
- index */
+ trx_t* trx,
+ fts_table_t* fts_table,
+ bool drop_orphan=false)
{
ulint i;
dberr_t error = DB_SUCCESS;
@@ -1598,6 +1592,16 @@ fts_drop_common_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
+
+ if (drop_orphan && err == DB_FAIL) {
+ char* path = fil_make_filepath(
+ NULL, table_name, IBD, false);
+ if (path != NULL) {
+ os_file_delete_if_exists(
+ innodb_data_file_key, path, NULL);
+ ut_free(path);
+ }
+ }
}
return(error);
@@ -2136,37 +2140,6 @@ fts_create_index_tables(
return(err);
}
-#if 0
-/******************************************************************//**
-Return string representation of state. */
-static
-const char*
-fts_get_state_str(
-/*==============*/
- /* out: string representation of state */
- fts_row_state state) /*!< in: state */
-{
- switch (state) {
- case FTS_INSERT:
- return("INSERT");
-
- case FTS_MODIFY:
- return("MODIFY");
-
- case FTS_DELETE:
- return("DELETE");
-
- case FTS_NOTHING:
- return("NOTHING");
-
- case FTS_INVALID:
- return("INVALID");
-
- default:
- return("UNKNOWN");
- }
-}
-#endif
/******************************************************************//**
Calculate the new state of a row given the existing state and a new event.
@@ -2542,8 +2515,7 @@ fts_get_max_cache_size(
error = fts_config_get_value(
trx, fts_table, FTS_MAX_CACHE_SIZE_IN_MB, &value);
- if (error == DB_SUCCESS) {
-
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
value.f_str[value.f_len] = 0;
cache_size_in_mb = strtoul((char*) value.f_str, NULL, 10);
@@ -2573,7 +2545,7 @@ fts_get_max_cache_size(
cache_size_in_mb = FTS_CACHE_SIZE_LOWER_LIMIT_IN_MB;
}
} else {
- ib::error() << "(" << ut_strerr(error) << ") reading max"
+ ib::error() << "(" << error << ") reading max"
" cache config value from config table";
}
@@ -2644,11 +2616,11 @@ dberr_t
fts_cmp_set_sync_doc_id(
/*====================*/
const dict_table_t* table, /*!< in: table */
- doc_id_t doc_id_cmp, /*!< in: Doc ID to compare */
+ doc_id_t cmp_doc_id, /*!< in: Doc ID to compare */
ibool read_only, /*!< in: TRUE if read the
synced_doc_id only */
doc_id_t* doc_id) /*!< out: larger document id
- after comparing "doc_id_cmp"
+ after comparing "cmp_doc_id"
to the one stored in CONFIG
table */
{
@@ -2719,10 +2691,10 @@ retry:
goto func_exit;
}
- if (doc_id_cmp == 0 && *doc_id) {
+ if (cmp_doc_id == 0 && *doc_id) {
cache->synced_doc_id = *doc_id - 1;
} else {
- cache->synced_doc_id = ut_max(doc_id_cmp, *doc_id);
+ cache->synced_doc_id = ut_max(cmp_doc_id, *doc_id);
}
mutex_enter(&cache->doc_id_lock);
@@ -2733,7 +2705,7 @@ retry:
}
mutex_exit(&cache->doc_id_lock);
- if (doc_id_cmp > *doc_id) {
+ if (cmp_doc_id > *doc_id) {
error = fts_update_sync_doc_id(
table, cache->synced_doc_id, trx);
}
@@ -2742,13 +2714,12 @@ retry:
func_exit:
- if (error == DB_SUCCESS) {
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
fts_sql_commit(trx);
} else {
*doc_id = 0;
- ib::error() << "(" << ut_strerr(error) << ") while getting"
- " next doc id.";
+ ib::error() << "(" << error << ") while getting next doc id.";
fts_sql_rollback(trx);
if (error == DB_DEADLOCK) {
@@ -2823,12 +2794,11 @@ fts_update_sync_doc_id(
fts_que_graph_free_check_lock(&fts_table, NULL, graph);
if (local_trx) {
- if (error == DB_SUCCESS) {
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
fts_sql_commit(trx);
cache->synced_doc_id = doc_id;
} else {
-
- ib::error() << "(" << ut_strerr(error) << ") while"
+ ib::error() << "(" << error << ") while"
" updating last doc id.";
fts_sql_rollback(trx);
@@ -2855,7 +2825,7 @@ fts_doc_ids_create(void)
fts_doc_ids->self_heap = ib_heap_allocator_create(heap);
fts_doc_ids->doc_ids = static_cast<ib_vector_t*>(ib_vector_create(
- fts_doc_ids->self_heap, sizeof(fts_update_t), 32));
+ fts_doc_ids->self_heap, sizeof(doc_id_t), 32));
return(fts_doc_ids);
}
@@ -3229,7 +3199,7 @@ fts_fetch_doc_from_rec(
dict_index_t* clust_index, /*!< in: cluster index */
btr_pcur_t* pcur, /*!< in: cursor whose position
has been stored */
- ulint* offsets, /*!< in: offsets */
+ rec_offs* offsets, /*!< in: offsets */
fts_doc_t* doc) /*!< out: fts doc to hold parsed
documents */
{
@@ -3412,7 +3382,7 @@ fts_add_doc_from_tuple(
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
fts_load_stopword(table, NULL, NULL,
- NULL, TRUE, TRUE);
+ true, true);
}
fts_cache_add_doc(
@@ -3511,7 +3481,7 @@ fts_add_doc_by_id(
btr_pcur_t* doc_pcur;
const rec_t* clust_rec;
btr_pcur_t clust_pcur;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
ulint num_idx = ib_vector_size(cache->get_docs);
rec = btr_pcur_get_rec(&pcur);
@@ -3576,8 +3546,8 @@ fts_add_doc_by_id(
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
- fts_load_stopword(table, NULL, NULL,
- NULL, TRUE, TRUE);
+ fts_load_stopword(table, NULL,
+ NULL, true, true);
}
fts_cache_add_doc(
@@ -3700,8 +3670,8 @@ fts_get_max_doc_id(
if (!page_is_empty(btr_pcur_get_page(&pcur))) {
const rec_t* rec = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
mem_heap_t* heap = NULL;
ulint len;
const void* data;
@@ -3950,7 +3920,7 @@ fts_sync_add_deleted_cache(
ut_a(ib_vector_size(doc_ids) > 0);
- ib_vector_sort(doc_ids, fts_update_doc_id_cmp);
+ ib_vector_sort(doc_ids, fts_doc_id_cmp);
info = pars_info_create();
@@ -3968,13 +3938,13 @@ fts_sync_add_deleted_cache(
"BEGIN INSERT INTO $table_name VALUES (:doc_id);");
for (i = 0; i < n_elems && error == DB_SUCCESS; ++i) {
- fts_update_t* update;
+ doc_id_t* update;
doc_id_t write_doc_id;
- update = static_cast<fts_update_t*>(ib_vector_get(doc_ids, i));
+ update = static_cast<doc_id_t*>(ib_vector_get(doc_ids, i));
/* Convert to "storage" byte order. */
- fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
+ fts_write_doc_id((byte*) &write_doc_id, *update);
fts_bind_doc_id(info, "doc_id", &write_doc_id);
error = fts_eval_sql(sync->trx, graph);
@@ -4072,14 +4042,14 @@ fts_sync_write_words(
n_nodes += ib_vector_size(word->nodes);
- if (error != DB_SUCCESS && !print_error) {
- ib::error() << "(" << ut_strerr(error) << ") writing"
+ if (UNIV_UNLIKELY(error != DB_SUCCESS) && !print_error) {
+ ib::error() << "(" << error << ") writing"
" word node to FTS auxiliary index table.";
print_error = TRUE;
}
}
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
printf("Avg number of nodes: %lf\n",
(double) n_nodes / (double) (n_words > 1 ? n_words : 1));
}
@@ -4105,7 +4075,7 @@ fts_sync_begin(
sync->trx = trx_allocate_for_background();
trx_start_internal(sync->trx);
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "FTS SYNC for table " << sync->table->name
<< ", deleted count: "
<< ib_vector_size(cache->deleted_doc_ids)
@@ -4128,7 +4098,7 @@ fts_sync_index(
trx->op_info = "doing SYNC index";
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "SYNC words: " << rbt_size(index_cache->words);
}
@@ -4225,18 +4195,14 @@ fts_sync_commit(
fts_cache_init(cache);
rw_lock_x_unlock(&cache->lock);
- if (error == DB_SUCCESS) {
-
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
fts_sql_commit(trx);
-
- } else if (error != DB_SUCCESS) {
-
+ } else {
fts_sql_rollback(trx);
-
- ib::error() << "(" << ut_strerr(error) << ") during SYNC.";
+ ib::error() << "(" << error << ") during SYNC.";
}
- if (fts_enable_diag_print && elapsed_time) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print) && elapsed_time) {
ib::info() << "SYNC for table " << sync->table->name
<< ": SYNC time: "
<< (time(NULL) - sync->start_time)
@@ -4245,7 +4211,7 @@ fts_sync_commit(
<< " ins/sec";
}
- /* Avoid assertion in trx_free(). */
+ /* Avoid assertion in trx_t::free(). */
trx->dict_operation_lock_mode = 0;
trx_free_for_background(trx);
@@ -4299,7 +4265,7 @@ fts_sync_rollback(
fts_sql_rollback(trx);
- /* Avoid assertion in trx_free(). */
+ /* Avoid assertion in trx_t::free(). */
trx->dict_operation_lock_mode = 0;
trx_free_for_background(trx);
}
@@ -4990,7 +4956,7 @@ fts_get_rows_count(
for (;;) {
error = fts_eval_sql(trx, graph);
- if (error == DB_SUCCESS) {
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
fts_sql_commit(trx);
break; /* Exit the loop. */
@@ -5003,7 +4969,7 @@ fts_get_rows_count(
trx->error_state = DB_SUCCESS;
} else {
- ib::error() << "(" << ut_strerr(error)
+ ib::error() << "(" << error
<< ") while reading FTS table.";
break; /* Exit the loop. */
@@ -5208,8 +5174,8 @@ fts_get_doc_id_from_rec(
const byte* data;
ulint col_no;
doc_id_t doc_id = 0;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
mem_heap_t* my_heap = heap;
ut_a(table->fts->doc_col != ULINT_UNDEFINED);
@@ -5299,12 +5265,12 @@ fts_cache_append_deleted_doc_ids(
for (ulint i = 0; i < ib_vector_size(cache->deleted_doc_ids); ++i) {
- fts_update_t* update;
+ doc_id_t* update;
- update = static_cast<fts_update_t*>(
+ update = static_cast<doc_id_t*>(
ib_vector_get(cache->deleted_doc_ids, i));
- ib_vector_push(vector, &update->doc_id);
+ ib_vector_push(vector, &update);
}
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
@@ -5393,7 +5359,6 @@ fts_t::fts_t(
mem_heap_t* heap)
:
added_synced(0), dict_locked(0),
- bg_threads(0),
add_wq(NULL),
cache(NULL),
doc_col(ULINT_UNDEFINED), in_queue(false),
@@ -5401,8 +5366,6 @@ fts_t::fts_t(
{
ut_a(table->fts == NULL);
- mutex_create(LATCH_ID_FTS_BG_THREADS, &bg_threads_mutex);
-
ib_alloc_t* heap_alloc = ib_heap_allocator_create(fts_heap);
indexes = ib_vector_create(heap_alloc, sizeof(dict_index_t*), 4);
@@ -5413,8 +5376,6 @@ fts_t::fts_t(
/** fts_t destructor. */
fts_t::~fts_t()
{
- mutex_free(&bg_threads_mutex);
-
ut_ad(add_wq == NULL);
if (cache != NULL) {
@@ -5777,1336 +5738,245 @@ fts_savepoint_rollback(
}
}
-/** Check if a table is an FTS auxiliary table name.
-@param[out] table FTS table info
-@param[in] name Table name
-@param[in] len Length of table name
-@return true if the name matches an auxiliary table name pattern */
-static
-bool
-fts_is_aux_table_name(
- fts_aux_table_t* table,
- const char* name,
- ulint len)
-{
- const char* ptr;
- char* end;
- char my_name[MAX_FULL_NAME_LEN + 1];
-
- ut_ad(len <= MAX_FULL_NAME_LEN);
- ut_memcpy(my_name, name, len);
- my_name[len] = 0;
- end = my_name + len;
-
- ptr = static_cast<const char*>(memchr(my_name, '/', len));
-
- if (ptr != NULL) {
- /* We will start the match after the '/' */
- ++ptr;
- len = end - ptr;
- }
-
- /* All auxiliary tables are prefixed with "FTS_" and the name
- length will be at the very least greater than 20 bytes. */
- if (ptr != NULL && len > 20 && strncmp(ptr, "FTS_", 4) == 0) {
- ulint i;
-
- /* Skip the prefix. */
- ptr += 4;
- len -= 4;
-
- /* Try and read the table id. */
- if (!fts_read_object_id(&table->parent_id, ptr)) {
- return(false);
- }
-
- /* Skip the table id. */
- ptr = static_cast<const char*>(memchr(ptr, '_', len));
-
- if (ptr == NULL) {
- return(false);
- }
-
- /* Skip the underscore. */
- ++ptr;
- ut_a(end > ptr);
- len = end - ptr;
-
- /* First search the common table suffix array. */
- for (i = 0; fts_common_tables[i] != NULL; ++i) {
-
- if (strncmp(ptr, fts_common_tables[i], len) == 0) {
- return(true);
- }
- }
-
- /* Could be obsolete common tables. */
- if (strncmp(ptr, "ADDED", len) == 0
- || strncmp(ptr, "STOPWORDS", len) == 0) {
- return(true);
- }
-
- /* Try and read the index id. */
- if (!fts_read_object_id(&table->index_id, ptr)) {
- return(false);
- }
-
- /* Skip the table id. */
- ptr = static_cast<const char*>(memchr(ptr, '_', len));
-
- if (ptr == NULL) {
- return(false);
- }
-
- /* Skip the underscore. */
- ++ptr;
- ut_a(end > ptr);
- len = end - ptr;
-
- /* Search the FT index specific array. */
- for (i = 0; i < FTS_NUM_AUX_INDEX; ++i) {
-
- if (strncmp(ptr, fts_get_suffix(i), len) == 0) {
- return(true);
- }
- }
-
- /* Other FT index specific table(s). */
- if (strncmp(ptr, "DOC_ID", len) == 0) {
- return(true);
- }
- }
-
- return(false);
-}
-
-/**********************************************************************//**
-Callback function to read a single table ID column.
-@return Always return TRUE */
-static
-ibool
-fts_read_tables(
-/*============*/
- void* row, /*!< in: sel_node_t* */
- void* user_arg) /*!< in: pointer to ib_vector_t */
-{
- int i;
- fts_aux_table_t*table;
- mem_heap_t* heap;
- ibool done = FALSE;
- ib_vector_t* tables = static_cast<ib_vector_t*>(user_arg);
- sel_node_t* sel_node = static_cast<sel_node_t*>(row);
- que_node_t* exp = sel_node->select_list;
-
- /* Must be a heap allocated vector. */
- ut_a(tables->allocator->arg != NULL);
-
- /* We will use this heap for allocating strings. */
- heap = static_cast<mem_heap_t*>(tables->allocator->arg);
- table = static_cast<fts_aux_table_t*>(ib_vector_push(tables, NULL));
-
- memset(table, 0x0, sizeof(*table));
-
- /* Iterate over the columns and read the values. */
- for (i = 0; exp && !done; exp = que_node_get_next(exp), ++i) {
-
- dfield_t* dfield = que_node_get_val(exp);
- void* data = dfield_get_data(dfield);
- ulint len = dfield_get_len(dfield);
-
- ut_a(len != UNIV_SQL_NULL);
-
- /* Note: The column numbers below must match the SELECT */
- switch (i) {
- case 0: /* NAME */
-
- if (!fts_is_aux_table_name(
- table, static_cast<const char*>(data), len)) {
- ib_vector_pop(tables);
- done = TRUE;
- break;
- }
-
- table->name = static_cast<char*>(
- mem_heap_alloc(heap, len + 1));
- memcpy(table->name, data, len);
- table->name[len] = 0;
- break;
-
- case 1: /* ID */
- ut_a(len == 8);
- table->id = mach_read_from_8(
- static_cast<const byte*>(data));
- break;
-
- default:
- ut_error;
- }
- }
-
- return(TRUE);
-}
-
-/******************************************************************//**
-Callback that sets a hex formatted FTS table's flags2 in
-SYS_TABLES. The flags is stored in MIX_LEN column.
-@return FALSE if all OK */
-static
-ibool
-fts_set_hex_format(
-/*===============*/
- void* row, /*!< in: sel_node_t* */
- void* user_arg) /*!< in: bool set/unset flag */
-{
- sel_node_t* node = static_cast<sel_node_t*>(row);
- dfield_t* dfield = que_node_get_val(node->select_list);
-
- ut_ad(dtype_get_mtype(dfield_get_type(dfield)) == DATA_INT);
- ut_ad(dfield_get_len(dfield) == sizeof(ib_uint32_t));
- /* There should be at most one matching record. So the value
- must be the default value. */
- ut_ad(mach_read_from_4(static_cast<byte*>(user_arg))
- == ULINT32_UNDEFINED);
-
- ulint flags2 = mach_read_from_4(
- static_cast<byte*>(dfield_get_data(dfield)));
-
- flags2 |= DICT_TF2_FTS_AUX_HEX_NAME;
-
- mach_write_to_4(static_cast<byte*>(user_arg), flags2);
-
- return(FALSE);
-}
-
-/*****************************************************************//**
-Update the DICT_TF2_FTS_AUX_HEX_NAME flag in SYS_TABLES.
-@return DB_SUCCESS or error code. */
-static
-dberr_t
-fts_update_hex_format_flag(
-/*=======================*/
- trx_t* trx, /*!< in/out: transaction that
- covers the update */
- table_id_t table_id, /*!< in: Table for which we want
- to set the root table->flags2 */
- bool dict_locked) /*!< in: set to true if the
- caller already owns the
- dict_sys_t::mutex. */
-{
- pars_info_t* info;
- ib_uint32_t flags2;
-
- static const char sql[] =
- "PROCEDURE UPDATE_HEX_FORMAT_FLAG() IS\n"
- "DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS\n"
- " SELECT MIX_LEN"
- " FROM SYS_TABLES"
- " WHERE ID = :table_id FOR UPDATE;"
- "\n"
- "BEGIN\n"
- "OPEN c;\n"
- "WHILE 1 = 1 LOOP\n"
- " FETCH c INTO my_func();\n"
- " IF c % NOTFOUND THEN\n"
- " EXIT;\n"
- " END IF;\n"
- "END LOOP;\n"
- "UPDATE SYS_TABLES"
- " SET MIX_LEN = :flags2"
- " WHERE ID = :table_id;\n"
- "CLOSE c;\n"
- "END;\n";
-
- flags2 = ULINT32_UNDEFINED;
-
- info = pars_info_create();
-
- pars_info_add_ull_literal(info, "table_id", table_id);
- pars_info_bind_int4_literal(info, "flags2", &flags2);
-
- pars_info_bind_function(
- info, "my_func", fts_set_hex_format, &flags2);
-
- if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- }
-
- dberr_t err = que_eval_sql(info, sql, !dict_locked, trx);
-
- ut_a(flags2 != ULINT32_UNDEFINED);
-
- return(err);
-}
-
-/*********************************************************************//**
-Rename an aux table to HEX format. It's called when "%016llu" is used
-to format an object id in table name, which only happens in Windows. */
-static MY_ATTRIBUTE((nonnull, warn_unused_result))
-dberr_t
-fts_rename_one_aux_table_to_hex_format(
-/*===================================*/
- trx_t* trx, /*!< in: transaction */
- const fts_aux_table_t* aux_table, /*!< in: table info */
- const dict_table_t* parent_table) /*!< in: parent table name */
-{
- const char* ptr;
- fts_table_t fts_table;
- char new_name[MAX_FULL_NAME_LEN];
- dberr_t error;
-
- ptr = strchr(aux_table->name, '/');
- ut_a(ptr != NULL);
- ++ptr;
- /* Skip "FTS_", table id and underscore */
- for (ulint i = 0; i < 2; ++i) {
- ptr = strchr(ptr, '_');
- ut_a(ptr != NULL);
- ++ptr;
- }
-
- fts_table.suffix = NULL;
- if (aux_table->index_id == 0) {
- fts_table.type = FTS_COMMON_TABLE;
-
- for (ulint i = 0; fts_common_tables[i] != NULL; ++i) {
- if (strcmp(ptr, fts_common_tables[i]) == 0) {
- fts_table.suffix = fts_common_tables[i];
- break;
- }
- }
- } else {
- fts_table.type = FTS_INDEX_TABLE;
-
- /* Skip index id and underscore */
- ptr = strchr(ptr, '_');
- ut_a(ptr != NULL);
- ++ptr;
-
- for (ulint i = 0; fts_index_selector[i].value; ++i) {
- if (strcmp(ptr, fts_get_suffix(i)) == 0) {
- fts_table.suffix = fts_get_suffix(i);
- break;
- }
- }
- }
-
- ut_a(fts_table.suffix != NULL);
-
- fts_table.table_id = aux_table->parent_id;
- fts_table.index_id = aux_table->index_id;
- fts_table.table = parent_table;
-
- fts_get_table_name(&fts_table, new_name);
- ut_ad(strcmp(new_name, aux_table->name) != 0);
-
- if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- }
-
- error = row_rename_table_for_mysql(aux_table->name, new_name, trx,
- false, false);
-
- if (error != DB_SUCCESS) {
- ib::warn() << "Failed to rename aux table '"
- << aux_table->name << "' to new format '"
- << new_name << "'.";
- } else {
- ib::info() << "Renamed aux table '" << aux_table->name
- << "' to '" << new_name << "'.";
- }
-
- return(error);
-}
-
-/**********************************************************************//**
-Rename all aux tables of a parent table to HEX format. Also set aux tables'
-flags2 and parent table's flags2 with DICT_TF2_FTS_AUX_HEX_NAME.
-It's called when "%016llu" is used to format an object id in table name,
-which only happens in Windows.
-Note the ids in tables are correct but the names are old ambiguous ones.
-
-This function should make sure that either all the parent table and aux tables
-are set DICT_TF2_FTS_AUX_HEX_NAME with flags2 or none of them are set */
-static MY_ATTRIBUTE((nonnull, warn_unused_result))
-dberr_t
-fts_rename_aux_tables_to_hex_format_low(
-/*====================================*/
- trx_t* trx, /*!< in: transaction */
- dict_table_t* parent_table, /*!< in: parent table */
- ib_vector_t* tables) /*!< in: aux tables to rename. */
-{
- dberr_t error;
- ulint count;
-
- ut_ad(!DICT_TF2_FLAG_IS_SET(parent_table, DICT_TF2_FTS_AUX_HEX_NAME));
- ut_ad(!ib_vector_is_empty(tables));
-
- error = fts_update_hex_format_flag(trx, parent_table->id, true);
-
- if (error != DB_SUCCESS) {
- ib::warn() << "Setting parent table " << parent_table->name
- << " to hex format failed.";
- fts_sql_rollback(trx);
- return(error);
- }
-
- DICT_TF2_FLAG_SET(parent_table, DICT_TF2_FTS_AUX_HEX_NAME);
-
- for (count = 0; count < ib_vector_size(tables); ++count) {
- dict_table_t* table;
- fts_aux_table_t* aux_table;
-
- aux_table = static_cast<fts_aux_table_t*>(
- ib_vector_get(tables, count));
-
- table = dict_table_open_on_id(aux_table->id, TRUE,
- DICT_TABLE_OP_NORMAL);
-
- ut_ad(table != NULL);
- ut_ad(!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_AUX_HEX_NAME));
-
- /* Set HEX_NAME flag here to make sure we can get correct
- new table name in following function */
- DICT_TF2_FLAG_SET(table, DICT_TF2_FTS_AUX_HEX_NAME);
- error = fts_rename_one_aux_table_to_hex_format(trx,
- aux_table, parent_table);
- /* We will rollback the trx if the error != DB_SUCCESS,
- so setting the flag here is the same with setting it in
- row_rename_table_for_mysql */
- DBUG_EXECUTE_IF("rename_aux_table_fail", error = DB_ERROR;);
-
- if (error != DB_SUCCESS) {
- dict_table_close(table, TRUE, FALSE);
-
- ib::warn() << "Failed to rename one aux table "
- << aux_table->name << ". Will revert"
- " all successful rename operations.";
-
- fts_sql_rollback(trx);
- break;
- }
-
- error = fts_update_hex_format_flag(trx, aux_table->id, true);
- dict_table_close(table, TRUE, FALSE);
-
- if (error != DB_SUCCESS) {
- ib::warn() << "Setting aux table " << aux_table->name
- << " to hex format failed.";
-
- fts_sql_rollback(trx);
- break;
- }
- }
-
- if (error != DB_SUCCESS) {
- ut_ad(count != ib_vector_size(tables));
-
- /* If rename fails, thr trx would be rolled back, we can't
- use it any more, we'll start a new background trx to do
- the reverting. */
-
- ut_ad(!trx_is_started(trx));
-
- bool not_rename = false;
-
- /* Try to revert those succesful rename operations
- in order to revert the ibd file rename. */
- for (ulint i = 0; i <= count; ++i) {
- dict_table_t* table;
- fts_aux_table_t* aux_table;
- trx_t* trx_bg;
- dberr_t err;
-
- aux_table = static_cast<fts_aux_table_t*>(
- ib_vector_get(tables, i));
-
- table = dict_table_open_on_id(aux_table->id, TRUE,
- DICT_TABLE_OP_NORMAL);
- ut_ad(table != NULL);
-
- if (not_rename) {
- DICT_TF2_FLAG_UNSET(table,
- DICT_TF2_FTS_AUX_HEX_NAME);
- }
-
- if (!DICT_TF2_FLAG_IS_SET(table,
- DICT_TF2_FTS_AUX_HEX_NAME)) {
- dict_table_close(table, TRUE, FALSE);
- continue;
- }
-
- trx_bg = trx_allocate_for_background();
- trx_bg->op_info = "Revert half done rename";
- trx_bg->dict_operation_lock_mode = RW_X_LATCH;
- trx_start_for_ddl(trx_bg, TRX_DICT_OP_TABLE);
-
- DICT_TF2_FLAG_UNSET(table, DICT_TF2_FTS_AUX_HEX_NAME);
- err = row_rename_table_for_mysql(table->name.m_name,
- aux_table->name,
- trx_bg, false, false);
-
- trx_bg->dict_operation_lock_mode = 0;
- dict_table_close(table, TRUE, FALSE);
-
- if (err != DB_SUCCESS) {
- ib::warn() << "Failed to revert table "
- << table->name << ". Please revert"
- " manually.";
- fts_sql_rollback(trx_bg);
- trx_free_for_background(trx_bg);
- /* Continue to clear aux tables' flags2 */
- not_rename = true;
- continue;
- }
-
- fts_sql_commit(trx_bg);
- trx_free_for_background(trx_bg);
- }
-
- DICT_TF2_FLAG_UNSET(parent_table, DICT_TF2_FTS_AUX_HEX_NAME);
- }
-
- return(error);
-}
-
-/**********************************************************************//**
-Convert an id, which is actually a decimal number but was regard as a HEX
-from a string, to its real value. */
-static
-ib_id_t
-fts_fake_hex_to_dec(
-/*================*/
- ib_id_t id) /*!< in: number to convert */
-{
- ib_id_t dec_id = 0;
- char tmp_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
-
-#ifdef UNIV_DEBUG
- int ret =
-#endif /* UNIV_DEBUG */
- sprintf(tmp_id, UINT64PFx, id);
- ut_ad(ret == 16);
-#ifdef UNIV_DEBUG
- ret =
-#endif /* UNIV_DEBUG */
- sscanf(tmp_id, "%016" UINT64scan, &dec_id);
- ut_ad(ret == 1);
-
- return dec_id;
-}
-
-/*********************************************************************//**
-Compare two fts_aux_table_t parent_ids.
-@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */
-UNIV_INLINE
-int
-fts_check_aux_table_parent_id_cmp(
-/*==============================*/
- const void* p1, /*!< in: id1 */
- const void* p2) /*!< in: id2 */
-{
- const fts_aux_table_t* fa1 = static_cast<const fts_aux_table_t*>(p1);
- const fts_aux_table_t* fa2 = static_cast<const fts_aux_table_t*>(p2);
-
- return static_cast<int>(fa1->parent_id - fa2->parent_id);
-}
-
-/** Mark all the fts index associated with the parent table as corrupted.
-@param[in] trx transaction
-@param[in, out] parent_table fts index associated with this parent table
- will be marked as corrupted. */
-static
-void
-fts_parent_all_index_set_corrupt(
- trx_t* trx,
- dict_table_t* parent_table)
-{
- fts_t* fts = parent_table->fts;
-
- if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- }
-
- for (ulint j = 0; j < ib_vector_size(fts->indexes); j++) {
- dict_index_t* index = static_cast<dict_index_t*>(
- ib_vector_getp_const(fts->indexes, j));
- dict_set_corrupted(index,
- trx, "DROP ORPHANED TABLE");
- }
-}
-
-/** Mark the fts index which index id matches the id as corrupted.
-@param[in] trx transaction
-@param[in] id index id to search
-@param[in, out] parent_table parent table to check with all
- the index. */
-static
-void
-fts_set_index_corrupt(
- trx_t* trx,
- index_id_t id,
- dict_table_t* table)
-{
- fts_t* fts = table->fts;
-
- if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- }
-
- for (ulint j = 0; j < ib_vector_size(fts->indexes); j++) {
- dict_index_t* index = static_cast<dict_index_t*>(
- ib_vector_getp_const(fts->indexes, j));
- if (index->id == id) {
- dict_set_corrupted(index, trx,
- "DROP ORPHANED TABLE");
- break;
- }
- }
-}
-
-/** Check the index for the aux table is corrupted.
-@param[in] aux_table auxiliary table
-@retval nonzero if index is corrupted, zero for valid index */
-static
-ulint
-fts_check_corrupt_index(
- fts_aux_table_t* aux_table)
-{
- dict_table_t* table;
- dict_index_t* index;
- table = dict_table_open_on_id(
- aux_table->parent_id, TRUE, DICT_TABLE_OP_NORMAL);
-
- if (table == NULL) {
- return(0);
- }
-
- for (index = UT_LIST_GET_FIRST(table->indexes);
- index;
- index = UT_LIST_GET_NEXT(indexes, index)) {
- if (index->id == aux_table->index_id) {
- ut_ad(index->type & DICT_FTS);
- dict_table_close(table, true, false);
- return index->is_corrupted();
- }
- }
-
- dict_table_close(table, true, false);
- return(0);
-}
-
-/* Get parent table name if it's a fts aux table
-@param[in] aux_table_name aux table name
-@param[in] aux_table_len aux table length
-@return parent table name, or NULL */
-char*
-fts_get_parent_table_name(
- const char* aux_table_name,
- ulint aux_table_len)
-{
- fts_aux_table_t aux_table;
- char* parent_table_name = NULL;
-
- if (fts_is_aux_table_name(&aux_table, aux_table_name, aux_table_len)) {
- dict_table_t* parent_table;
-
- parent_table = dict_table_open_on_id(
- aux_table.parent_id, TRUE, DICT_TABLE_OP_NORMAL);
-
- if (parent_table != NULL) {
- parent_table_name = mem_strdupl(
- parent_table->name.m_name,
- strlen(parent_table->name.m_name));
-
- dict_table_close(parent_table, TRUE, FALSE);
- }
- }
-
- return(parent_table_name);
-}
-
-/** Check the validity of the parent table.
-@param[in] aux_table auxiliary table
-@return true if it is a valid table or false if it is not */
-static
-bool
-fts_valid_parent_table(
- const fts_aux_table_t* aux_table)
-{
- dict_table_t* parent_table;
- bool valid = false;
-
- parent_table = dict_table_open_on_id(
- aux_table->parent_id, TRUE, DICT_TABLE_OP_NORMAL);
-
- if (parent_table != NULL && parent_table->fts != NULL) {
- if (aux_table->index_id == 0) {
- valid = true;
- } else {
- index_id_t id = aux_table->index_id;
- dict_index_t* index;
-
- /* Search for the FT index in the table's list. */
- for (index = UT_LIST_GET_FIRST(parent_table->indexes);
- index;
- index = UT_LIST_GET_NEXT(indexes, index)) {
- if (index->id == id) {
- valid = true;
- break;
- }
-
- }
- }
- }
-
- if (parent_table) {
- dict_table_close(parent_table, TRUE, FALSE);
- }
-
- return(valid);
-}
-
-/** Try to rename all aux tables of the specified parent table.
-@param[in] aux_tables aux_tables to be renamed
-@param[in] parent_table parent table of all aux
- tables stored in tables. */
-static
-void
-fts_rename_aux_tables_to_hex_format(
- ib_vector_t* aux_tables,
- dict_table_t* parent_table)
-{
- dberr_t err;
- trx_t* trx_rename = trx_allocate_for_background();
- trx_rename->op_info = "Rename aux tables to hex format";
- trx_rename->dict_operation_lock_mode = RW_X_LATCH;
- trx_start_for_ddl(trx_rename, TRX_DICT_OP_TABLE);
-
- err = fts_rename_aux_tables_to_hex_format_low(trx_rename,
- parent_table, aux_tables);
-
- trx_rename->dict_operation_lock_mode = 0;
-
- if (err != DB_SUCCESS) {
-
- ib::warn() << "Rollback operations on all aux tables of "
- "table "<< parent_table->name << ". All the fts index "
- "associated with the table are marked as corrupted. "
- "Please rebuild the index again.";
-
- /* Corrupting the fts index related to parent table. */
- trx_t* trx_corrupt;
- trx_corrupt = trx_allocate_for_background();
- trx_corrupt->dict_operation_lock_mode = RW_X_LATCH;
- trx_start_for_ddl(trx_corrupt, TRX_DICT_OP_TABLE);
- fts_parent_all_index_set_corrupt(trx_corrupt, parent_table);
- trx_corrupt->dict_operation_lock_mode = 0;
- fts_sql_commit(trx_corrupt);
- trx_free_for_background(trx_corrupt);
- } else {
- fts_sql_commit(trx_rename);
- }
-
- trx_free_for_background(trx_rename);
- ib_vector_reset(aux_tables);
-}
-
-/** Set the hex format flag for the parent table.
-@param[in, out] parent_table parent table
-@param[in] trx transaction */
-static
-void
-fts_set_parent_hex_format_flag(
- dict_table_t* parent_table,
- trx_t* trx)
-{
- if (!DICT_TF2_FLAG_IS_SET(parent_table,
- DICT_TF2_FTS_AUX_HEX_NAME)) {
- DBUG_EXECUTE_IF("parent_table_flag_fail", DBUG_SUICIDE(););
-
- dberr_t err = fts_update_hex_format_flag(
- trx, parent_table->id, true);
-
- if (err != DB_SUCCESS) {
- ib::fatal() << "Setting parent table "
- << parent_table->name
- << "to hex format failed. Please try "
- << "to restart the server again, if it "
- << "doesn't work, the system tables "
- << "might be corrupted.";
- } else {
- DICT_TF2_FLAG_SET(
- parent_table, DICT_TF2_FTS_AUX_HEX_NAME);
- }
- }
-}
-
-/** Drop the obsolete auxilary table.
-@param[in] tables tables to be dropped. */
-static
-void
-fts_drop_obsolete_aux_table_from_vector(
- ib_vector_t* tables)
-{
- dberr_t err;
-
- for (ulint count = 0; count < ib_vector_size(tables);
- ++count) {
-
- fts_aux_table_t* aux_drop_table;
- aux_drop_table = static_cast<fts_aux_table_t*>(
- ib_vector_get(tables, count));
- trx_t* trx_drop = trx_allocate_for_background();
- trx_drop->op_info = "Drop obsolete aux tables";
- trx_drop->dict_operation_lock_mode = RW_X_LATCH;
- trx_start_for_ddl(trx_drop, TRX_DICT_OP_TABLE);
-
- err = row_drop_table_for_mysql(
- aux_drop_table->name, trx_drop,
- SQLCOM_DROP_TABLE, true);
-
- trx_drop->dict_operation_lock_mode = 0;
-
- if (err != DB_SUCCESS) {
- /* We don't need to worry about the
- failure, since server would try to
- drop it on next restart, even if
- the table was broken. */
- ib::warn() << "Failed to drop obsolete aux table "
- << aux_drop_table->name << ", which is "
- << "harmless. will try to drop it on next "
- << "restart.";
-
- fts_sql_rollback(trx_drop);
- } else {
- ib::info() << "Dropped obsolete aux"
- " table '" << aux_drop_table->name
- << "'.";
-
- fts_sql_commit(trx_drop);
- }
-
- trx_free_for_background(trx_drop);
- }
-}
-
-/** Drop all the auxiliary table present in the vector.
-@param[in] trx transaction
-@param[in] tables tables to be dropped */
-static
-void
-fts_drop_aux_table_from_vector(
- trx_t* trx,
- ib_vector_t* tables)
-{
- for (ulint count = 0; count < ib_vector_size(tables);
- ++count) {
- fts_aux_table_t* aux_drop_table;
- aux_drop_table = static_cast<fts_aux_table_t*>(
- ib_vector_get(tables, count));
-
- /* Check for the validity of the parent table */
- if (!fts_valid_parent_table(aux_drop_table)) {
-
- ib::warn() << "Parent table of FTS auxiliary table "
- << aux_drop_table->name << " not found.";
-
- dberr_t err = fts_drop_table(trx, aux_drop_table->name);
- if (err == DB_FAIL) {
-
- char* path = fil_make_filepath(
- NULL, aux_drop_table->name, IBD, false);
-
- if (path != NULL) {
- os_file_delete_if_exists(
- innodb_data_file_key,
- path , NULL);
- ut_free(path);
- }
- }
- }
- }
-}
-
-/**********************************************************************//**
-Check and drop all orphaned FTS auxiliary tables, those that don't have
-a parent table or FTS index defined on them.
-@return DB_SUCCESS or error code */
-static MY_ATTRIBUTE((nonnull))
-void
-fts_check_and_drop_orphaned_tables(
-/*===============================*/
- trx_t* trx, /*!< in: transaction */
- ib_vector_t* tables) /*!< in: tables to check */
-{
- mem_heap_t* heap;
- ib_vector_t* aux_tables_to_rename;
- ib_vector_t* invalid_aux_tables;
- ib_vector_t* valid_aux_tables;
- ib_vector_t* drop_aux_tables;
- ib_vector_t* obsolete_aux_tables;
- ib_alloc_t* heap_alloc;
-
- heap = mem_heap_create(1024);
- heap_alloc = ib_heap_allocator_create(heap);
-
- /* We store all aux tables belonging to the same parent table here,
- and rename all these tables in a batch mode. */
- aux_tables_to_rename = ib_vector_create(heap_alloc,
- sizeof(fts_aux_table_t), 128);
-
- /* We store all fake auxiliary table and orphaned table here. */
- invalid_aux_tables = ib_vector_create(heap_alloc,
- sizeof(fts_aux_table_t), 128);
-
- /* We store all valid aux tables. We use this to filter the
- fake auxiliary table from invalid auxiliary tables. */
- valid_aux_tables = ib_vector_create(heap_alloc,
- sizeof(fts_aux_table_t), 128);
-
- /* We store all auxiliary tables to be dropped. */
- drop_aux_tables = ib_vector_create(heap_alloc,
- sizeof(fts_aux_table_t), 128);
-
- /* We store all obsolete auxiliary tables to be dropped. */
- obsolete_aux_tables = ib_vector_create(heap_alloc,
- sizeof(fts_aux_table_t), 128);
-
- /* Sort by parent_id first, in case rename will fail */
- ib_vector_sort(tables, fts_check_aux_table_parent_id_cmp);
-
- for (ulint i = 0; i < ib_vector_size(tables); ++i) {
- dict_table_t* parent_table;
- fts_aux_table_t* aux_table;
- bool drop = false;
- dict_table_t* table;
- fts_aux_table_t* next_aux_table = NULL;
- ib_id_t orig_parent_id = 0;
- ib_id_t orig_index_id = 0;
- bool rename = false;
-
- aux_table = static_cast<fts_aux_table_t*>(
- ib_vector_get(tables, i));
-
- table = dict_table_open_on_id(
- aux_table->id, TRUE, DICT_TABLE_OP_NORMAL);
- orig_parent_id = aux_table->parent_id;
- orig_index_id = aux_table->index_id;
-
- if (table == NULL
- || strcmp(table->name.m_name, aux_table->name)) {
-
- bool fake_aux = false;
-
- if (table != NULL) {
- dict_table_close(table, TRUE, FALSE);
- }
-
- if (i + 1 < ib_vector_size(tables)) {
- next_aux_table = static_cast<fts_aux_table_t*>(
- ib_vector_get(tables, i + 1));
- }
-
- /* To know whether aux table is fake fts or
- orphan fts table. */
- for (ulint count = 0;
- count < ib_vector_size(valid_aux_tables);
- count++) {
- fts_aux_table_t* valid_aux;
- valid_aux = static_cast<fts_aux_table_t*>(
- ib_vector_get(valid_aux_tables, count));
- if (strcmp(valid_aux->name,
- aux_table->name) == 0) {
- fake_aux = true;
- break;
- }
- }
-
- /* All aux tables of parent table, whose id is
- last_parent_id, have been checked, try to rename
- them if necessary. */
- if ((next_aux_table == NULL
- || orig_parent_id != next_aux_table->parent_id)
- && (!ib_vector_is_empty(aux_tables_to_rename))) {
+bool fts_check_aux_table(const char *name,
+ table_id_t *table_id,
+ index_id_t *index_id)
+{
+ ulint len= strlen(name);
+ const char* ptr;
+ const char* end= name + len;
- ib_id_t parent_id = fts_fake_hex_to_dec(
- aux_table->parent_id);
+ ut_ad(len <= MAX_FULL_NAME_LEN);
+ ptr= static_cast<const char*>(memchr(name, '/', len));
- parent_table = dict_table_open_on_id(
- parent_id, TRUE,
- DICT_TABLE_OP_NORMAL);
+ if (ptr != NULL)
+ {
+ /* We will start the match after the '/' */
+ ++ptr;
+ len = end - ptr;
+ }
+
+ /* All auxiliary tables are prefixed with "FTS_" and the name
+ length will be at the very least greater than 20 bytes. */
+ if (ptr && len > 20 && !memcmp(ptr, "FTS_", 4))
+ {
+ /* Skip the prefix. */
+ ptr+= 4;
+ len-= 4;
+
+ const char *table_id_ptr= ptr;
+ /* Skip the table id. */
+ ptr= static_cast<const char*>(memchr(ptr, '_', len));
+
+ if (!ptr)
+ return false;
+
+ /* Skip the underscore. */
+ ++ptr;
+ ut_ad(end > ptr);
+ len= end - ptr;
+
+ sscanf(table_id_ptr, UINT64PFx, table_id);
+ /* First search the common table suffix array. */
+ for (ulint i = 0; fts_common_tables[i]; ++i)
+ {
+ if (!strncmp(ptr, fts_common_tables[i], len))
+ return true;
+ }
+
+ /* Could be obsolete common tables. */
+ if ((len == 5 && !memcmp(ptr, "ADDED", len)) ||
+ (len == 9 && !memcmp(ptr, "STOPWORDS", len)))
+ return true;
+
+ const char* index_id_ptr= ptr;
+ /* Skip the index id. */
+ ptr= static_cast<const char*>(memchr(ptr, '_', len));
+ if (!ptr)
+ return false;
+
+ sscanf(index_id_ptr, UINT64PFx, index_id);
+
+ /* Skip the underscore. */
+ ++ptr;
+ ut_a(end > ptr);
+ len= end - ptr;
+
+ if (len > 7)
+ return false;
+
+ /* Search the FT index specific array. */
+ for (ulint i = 0; i < FTS_NUM_AUX_INDEX; ++i)
+ {
+ if (!memcmp(ptr, "INDEX_", len - 1))
+ return true;
+ }
+
+ /* Other FT index specific table(s). */
+ if (len == 6 && !memcmp(ptr, "DOC_ID", len))
+ return true;
+ }
+
+ return false;
+}
+
+typedef std::pair<table_id_t,index_id_t> fts_aux_id;
+typedef std::set<fts_aux_id> fts_space_set_t;
+
+/** Iterate over all the spaces in the space list and fetch the
+fts parent table id and index id.
+@param[in,out] fts_space_set store the list of tablespace id and
+ index id */
+static void fil_get_fts_spaces(fts_space_set_t& fts_space_set)
+{
+ mutex_enter(&fil_system->mutex);
+
+ for (fil_space_t *space = UT_LIST_GET_FIRST(fil_system->space_list);
+ space != NULL;
+ space = UT_LIST_GET_NEXT(space_list, space))
+ {
+ index_id_t index_id = 0;
+ table_id_t table_id = 0;
+
+ if (space->purpose == FIL_TYPE_TABLESPACE
+ && fts_check_aux_table(space->name, &table_id, &index_id))
+ fts_space_set.insert(std::make_pair(table_id, index_id));
+ }
+
+ mutex_exit(&fil_system->mutex);
+}
+
+/** Check whether the parent table id and index id of fts auxilary
+tables with SYS_INDEXES. If it exists then we can safely ignore the
+fts table from orphaned tables.
+@param[in,out] fts_space_set fts space set contains set of auxiliary
+ table ids */
+static void fts_check_orphaned_tables(fts_space_set_t& fts_space_set)
+{
+ btr_pcur_t pcur;
+ mtr_t mtr;
+ trx_t* trx = trx_allocate_for_background();
+ trx->op_info = "checking fts orphaned tables";
+
+ row_mysql_lock_data_dictionary(trx);
+
+ mtr.start();
+ btr_pcur_open_at_index_side(
+ true, dict_table_get_first_index(dict_sys->sys_indexes),
+ BTR_SEARCH_LEAF, &pcur, true, 0, &mtr);
+
+ do
+ {
+ const rec_t *rec;
+ const byte *tbl_field;
+ const byte *index_field;
+ ulint len;
+
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+ if (!btr_pcur_is_on_user_rec(&pcur))
+ break;
+
+ rec= btr_pcur_get_rec(&pcur);
+ if (rec_get_deleted_flag(rec, 0))
+ continue;
+
+ tbl_field= rec_get_nth_field_old(rec, 0, &len);
+ if (len != 8)
+ continue;
+
+ index_field= rec_get_nth_field_old(rec, 1, &len);
+ if (len != 8)
+ continue;
+
+ table_id_t table_id = mach_read_from_8(tbl_field);
+ index_id_t index_id = mach_read_from_8(index_field);
+
+ fts_space_set_t::iterator it = fts_space_set.find(
+ fts_aux_id(table_id, index_id));
- fts_rename_aux_tables_to_hex_format(
- aux_tables_to_rename, parent_table);
-
- dict_table_close(parent_table, TRUE,
- FALSE);
- }
-
- /* If the aux table is fake aux table. Skip it. */
- if (!fake_aux) {
- ib_vector_push(invalid_aux_tables, aux_table);
- }
-
- continue;
- } else if (!DICT_TF2_FLAG_IS_SET(table,
- DICT_TF2_FTS_AUX_HEX_NAME)) {
-
- aux_table->parent_id = fts_fake_hex_to_dec(
- aux_table->parent_id);
-
- if (aux_table->index_id != 0) {
- aux_table->index_id = fts_fake_hex_to_dec(
- aux_table->index_id);
- }
-
- ut_ad(aux_table->id > aux_table->parent_id);
-
- /* Check whether parent table id and index id
- are stored as decimal format. */
- if (fts_valid_parent_table(aux_table)) {
-
- parent_table = dict_table_open_on_id(
- aux_table->parent_id, true,
- DICT_TABLE_OP_NORMAL);
-
- ut_ad(parent_table != NULL);
- ut_ad(parent_table->fts != NULL);
-
- if (!DICT_TF2_FLAG_IS_SET(
- parent_table,
- DICT_TF2_FTS_AUX_HEX_NAME)) {
- rename = true;
- }
-
- dict_table_close(parent_table, TRUE, FALSE);
- }
-
- if (!rename) {
- /* Reassign the original value of
- aux table if it is not in decimal format */
- aux_table->parent_id = orig_parent_id;
- aux_table->index_id = orig_index_id;
- }
- }
-
- if (table != NULL) {
- dict_table_close(table, TRUE, FALSE);
- }
-
- if (!rename) {
- /* Check the validity of the parent table. */
- if (!fts_valid_parent_table(aux_table)) {
- drop = true;
- }
- }
-
- /* Filter out the fake aux table by comparing with the
- current valid auxiliary table name. */
- for (ulint count = 0;
- count < ib_vector_size(invalid_aux_tables); count++) {
- fts_aux_table_t* invalid_aux;
- invalid_aux = static_cast<fts_aux_table_t*>(
- ib_vector_get(invalid_aux_tables, count));
- if (strcmp(invalid_aux->name, aux_table->name) == 0) {
- ib_vector_remove(
- invalid_aux_tables,
- *reinterpret_cast<void**>(invalid_aux));
- break;
- }
- }
-
- ib_vector_push(valid_aux_tables, aux_table);
-
- /* If the index associated with aux table is corrupted,
- skip it. */
- if (fts_check_corrupt_index(aux_table) > 0) {
-
- if (i + 1 < ib_vector_size(tables)) {
- next_aux_table = static_cast<fts_aux_table_t*>(
- ib_vector_get(tables, i + 1));
- }
-
- if (next_aux_table == NULL
- || orig_parent_id != next_aux_table->parent_id) {
-
- parent_table = dict_table_open_on_id(
- aux_table->parent_id, TRUE,
- DICT_TABLE_OP_NORMAL);
-
- if (!ib_vector_is_empty(aux_tables_to_rename)) {
- fts_rename_aux_tables_to_hex_format(
- aux_tables_to_rename, parent_table);
- } else {
- fts_set_parent_hex_format_flag(
- parent_table, trx);
- }
-
- dict_table_close(parent_table, TRUE, FALSE);
- }
-
- continue;
- }
-
- parent_table = dict_table_open_on_id(
- aux_table->parent_id, TRUE, DICT_TABLE_OP_NORMAL);
-
- if (drop) {
- ib_vector_push(drop_aux_tables, aux_table);
- } else {
- if (FTS_IS_OBSOLETE_AUX_TABLE(aux_table->name)) {
- ib_vector_push(obsolete_aux_tables, aux_table);
- continue;
- }
- }
-
- /* If the aux table is in decimal format, we should
- rename it, so push it to aux_tables_to_rename */
- if (!drop && rename) {
- bool rename_table = true;
- for (ulint count = 0;
- count < ib_vector_size(aux_tables_to_rename);
- count++) {
- fts_aux_table_t* rename_aux =
- static_cast<fts_aux_table_t*>(
- ib_vector_get(aux_tables_to_rename,
- count));
- if (strcmp(rename_aux->name,
- aux_table->name) == 0) {
- rename_table = false;
- break;
- }
- }
-
- if (rename_table) {
- ib_vector_push(aux_tables_to_rename,
- aux_table);
- }
- }
-
- if (i + 1 < ib_vector_size(tables)) {
- next_aux_table = static_cast<fts_aux_table_t*>(
- ib_vector_get(tables, i + 1));
- }
-
- if ((next_aux_table == NULL
- || orig_parent_id != next_aux_table->parent_id)
- && !ib_vector_is_empty(aux_tables_to_rename)) {
-
- ut_ad(rename);
- ut_ad(!DICT_TF2_FLAG_IS_SET(
- parent_table, DICT_TF2_FTS_AUX_HEX_NAME));
-
- fts_rename_aux_tables_to_hex_format(
- aux_tables_to_rename,parent_table);
- }
-
- /* The IDs are already in correct hex format. */
- if (!drop && !rename) {
- dict_table_t* table;
-
- table = dict_table_open_on_id(
- aux_table->id, TRUE, DICT_TABLE_OP_NORMAL);
-
- if (table != NULL
- && strcmp(table->name.m_name, aux_table->name)) {
- dict_table_close(table, TRUE, FALSE);
- table = NULL;
- }
-
- if (table != NULL
- && !DICT_TF2_FLAG_IS_SET(
- table,
- DICT_TF2_FTS_AUX_HEX_NAME)) {
-
- DBUG_EXECUTE_IF("aux_table_flag_fail",
- ib::warn() << "Setting aux table "
- << table->name << " to hex "
- "format failed.";
- fts_set_index_corrupt(
- trx, aux_table->index_id,
- parent_table);
- goto table_exit;);
-
- dberr_t err = fts_update_hex_format_flag(
- trx, table->id, true);
-
- if (err != DB_SUCCESS) {
- ib::warn() << "Setting aux table "
- << table->name << " to hex "
- "format failed.";
-
- fts_set_index_corrupt(
- trx, aux_table->index_id,
- parent_table);
- } else {
- DICT_TF2_FLAG_SET(table,
- DICT_TF2_FTS_AUX_HEX_NAME);
- }
- }
-#ifndef DBUG_OFF
-table_exit:
-#endif /* !DBUG_OFF */
-
- if (table != NULL) {
- dict_table_close(table, TRUE, FALSE);
- }
-
- ut_ad(parent_table != NULL);
-
- fts_set_parent_hex_format_flag(
- parent_table, trx);
- }
-
- if (parent_table != NULL) {
- dict_table_close(parent_table, TRUE, FALSE);
- }
- }
-
- fts_drop_aux_table_from_vector(trx, invalid_aux_tables);
- fts_drop_aux_table_from_vector(trx, drop_aux_tables);
- fts_sql_commit(trx);
-
- fts_drop_obsolete_aux_table_from_vector(obsolete_aux_tables);
-
- /* Free the memory allocated at the beginning */
- if (heap != NULL) {
- mem_heap_free(heap);
- }
+ if (it != fts_space_set.end())
+ fts_space_set.erase(*it);
+ else
+ {
+ it= fts_space_set.find(fts_aux_id(table_id, 0));
+ if (it != fts_space_set.end())
+ fts_space_set.erase(*it);
+ }
+ } while(!fts_space_set.empty());
+
+ btr_pcur_close(&pcur);
+ mtr.commit();
+ row_mysql_unlock_data_dictionary(trx);
+ trx_free_for_background(trx);
}
-/**********************************************************************//**
-Drop all orphaned FTS auxiliary tables, those that don't have a parent
-table or FTS index defined on them. */
-void
-fts_drop_orphaned_tables(void)
-/*==========================*/
+/** Drop all fts auxilary table for the respective fts_id
+@param[in] fts_id fts auxilary table ids */
+static void fts_drop_all_aux_tables(trx_t *trx, fts_table_t *fts_table)
{
- trx_t* trx;
- pars_info_t* info;
- mem_heap_t* heap;
- que_t* graph;
- ib_vector_t* tables;
- ib_alloc_t* heap_alloc;
- space_name_list_t space_name_list;
- dberr_t error = DB_SUCCESS;
-
- /* Note: We have to free the memory after we are done with the list. */
- error = fil_get_space_names(space_name_list);
-
- if (error == DB_OUT_OF_MEMORY) {
- ib::fatal() << "Out of memory";
- }
-
- heap = mem_heap_create(1024);
- heap_alloc = ib_heap_allocator_create(heap);
-
- /* We store the table ids of all the FTS indexes that were found. */
- tables = ib_vector_create(heap_alloc, sizeof(fts_aux_table_t), 128);
-
- /* Get the list of all known .ibd files and check for orphaned
- FTS auxiliary files in that list. We need to remove them because
- users can't map them back to table names and this will create
- unnecessary clutter. */
-
- for (space_name_list_t::iterator it = space_name_list.begin();
- it != space_name_list.end();
- ++it) {
-
- fts_aux_table_t* fts_aux_table;
-
- fts_aux_table = static_cast<fts_aux_table_t*>(
- ib_vector_push(tables, NULL));
-
- memset(fts_aux_table, 0x0, sizeof(*fts_aux_table));
-
- if (!fts_is_aux_table_name(fts_aux_table, *it, strlen(*it))) {
- ib_vector_pop(tables);
- } else {
- ulint len = strlen(*it);
-
- fts_aux_table->id = fil_space_get_id_by_name(*it);
-
- /* We got this list from fil0fil.cc. The tablespace
- with this name must exist. */
- ut_a(fts_aux_table->id != ULINT_UNDEFINED);
-
- fts_aux_table->name = static_cast<char*>(
- mem_heap_dup(heap, *it, len + 1));
-
- fts_aux_table->name[len] = 0;
- }
- }
-
- trx = trx_allocate_for_background();
- trx->op_info = "dropping orphaned FTS tables";
- row_mysql_lock_data_dictionary(trx);
-
- info = pars_info_create();
-
- pars_info_bind_function(info, "my_func", fts_read_tables, tables);
-
- graph = fts_parse_sql_no_dict_lock(
- NULL,
- info,
- "DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS"
- " SELECT NAME, ID"
- " FROM SYS_TABLES;\n"
- "BEGIN\n"
- "\n"
- "OPEN c;\n"
- "WHILE 1 = 1 LOOP\n"
- " FETCH c INTO my_func();\n"
- " IF c % NOTFOUND THEN\n"
- " EXIT;\n"
- " END IF;\n"
- "END LOOP;\n"
- "CLOSE c;");
-
- for (;;) {
- error = fts_eval_sql(trx, graph);
+ char fts_table_name[MAX_FULL_NAME_LEN];
+ for (ulint i= 0;i < FTS_NUM_AUX_INDEX; i++)
+ {
+ fts_table->suffix= fts_get_suffix(i);
+ fts_get_table_name(fts_table, fts_table_name, true);
+
+ /* Drop all fts aux and common table */
+ dberr_t err= fts_drop_table(trx, fts_table_name);
+
+ if (err == DB_FAIL)
+ {
+ char *path= fil_make_filepath(NULL, fts_table_name, IBD, false);
+
+ if (path != NULL)
+ {
+ os_file_delete_if_exists(innodb_data_file_key, path , NULL);
+ ut_free(path);
+ }
+ }
+ }
+}
+
+/** Drop all orphaned FTS auxiliary tables, those that don't have
+a parent table or FTS index defined on them. */
+void fts_drop_orphaned_tables()
+{
+ fts_space_set_t fts_space_set;
+ fil_get_fts_spaces(fts_space_set);
- if (error == DB_SUCCESS) {
- fts_check_and_drop_orphaned_tables(trx, tables);
- break; /* Exit the loop. */
- } else {
- ib_vector_reset(tables);
-
- fts_sql_rollback(trx);
+ if (fts_space_set.empty())
+ return;
+
+ fts_check_orphaned_tables(fts_space_set);
+
+ if (fts_space_set.empty())
+ return;
+
+ trx_t* trx= trx_allocate_for_background();
+ trx->op_info= "Drop orphaned aux FTS tables";
+ row_mysql_lock_data_dictionary(trx);
+
+ for (fts_space_set_t::iterator it = fts_space_set.begin();
+ it != fts_space_set.end(); it++)
+ {
+ fts_table_t fts_table;
+ dict_table_t *table= dict_table_open_on_id(it->first, TRUE,
+ DICT_TABLE_OP_NORMAL);
+ if (!table)
+ continue;
+
+ FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
+ fts_drop_common_tables(trx, &fts_table, true);
+
+ fts_table.type= FTS_INDEX_TABLE;
+ fts_table.index_id= it->second;
+ fts_drop_all_aux_tables(trx, &fts_table);
- if (error == DB_LOCK_WAIT_TIMEOUT) {
- ib::warn() << "lock wait timeout reading"
- " SYS_TABLES. Retrying!";
-
- trx->error_state = DB_SUCCESS;
- } else {
- ib::error() << "(" << ut_strerr(error)
- << ") while reading SYS_TABLES.";
-
- break; /* Exit the loop. */
- }
- }
- }
-
- que_graph_free(graph);
-
- row_mysql_unlock_data_dictionary(trx);
-
- trx_free_for_background(trx);
-
- if (heap != NULL) {
- mem_heap_free(heap);
- }
-
- /** Free the memory allocated to store the .ibd names. */
- for (space_name_list_t::iterator it = space_name_list.begin();
- it != space_name_list.end();
- ++it) {
-
- UT_DELETE_ARRAY(*it);
- }
+ dict_table_close(table, true, false);
+ }
+ trx_commit_for_mysql(trx);
+ row_mysql_unlock_data_dictionary(trx);
+ trx->dict_operation_lock_mode= 0;
+ trx_free_for_background(trx);
}
/**********************************************************************//**
@@ -7168,20 +6038,18 @@ This function loads the stopword into the FTS cache. It also
records/fetches stopword configuration to/from FTS configure
table, depending on whether we are creating or reloading the
FTS.
-@return TRUE if load operation is successful */
-ibool
+@return true if load operation is successful */
+bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transactions */
- const char* global_stopword_table, /*!< in: Global stopword table
- name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
- ibool stopword_is_on, /*!< in: Whether stopword
+ bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
- ibool reload) /*!< in: Whether it is
+ bool reload) /*!< in: Whether it is
for reloading FTS table */
{
fts_table_t fts_table;
@@ -7197,9 +6065,8 @@ fts_load_stopword(
cache = table->fts->cache;
- if (!reload && !(cache->stopword_info.status
- & STOPWORD_NOT_INIT)) {
- return(TRUE);
+ if (!reload && !(cache->stopword_info.status & STOPWORD_NOT_INIT)) {
+ return true;
}
if (!trx) {
@@ -7249,12 +6116,11 @@ fts_load_stopword(
goto cleanup;
}
- if (strlen((char*) str.f_str) > 0) {
+ if (*str.f_str) {
stopword_to_use = (const char*) str.f_str;
}
} else {
- stopword_to_use = (session_stopword_table)
- ? session_stopword_table : global_stopword_table;
+ stopword_to_use = session_stopword_table;
}
if (stopword_to_use
@@ -7292,7 +6158,7 @@ cleanup:
&my_charset_latin1);
}
- return(error == DB_SUCCESS);
+ return error == DB_SUCCESS;
}
/**********************************************************************//**
@@ -7493,7 +6359,7 @@ fts_init_index(
} else {
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
- fts_load_stopword(table, NULL, NULL, NULL, TRUE, TRUE);
+ fts_load_stopword(table, NULL, NULL, true, true);
}
for (ulint i = 0; i < ib_vector_size(cache->get_docs); ++i) {
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index 202bd80d20a..3cabb64b851 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -525,7 +525,7 @@ fts_index_fetch_nodes(
for (;;) {
error = fts_eval_sql(trx, *graph);
- if (error == DB_SUCCESS) {
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
fts_sql_commit(trx);
break; /* Exit the loop. */
@@ -538,7 +538,7 @@ fts_index_fetch_nodes(
trx->error_state = DB_SUCCESS;
} else {
- ib::error() << "(" << ut_strerr(error)
+ ib::error() << "(" << error
<< ") while reading FTS index.";
break; /* Exit the loop. */
@@ -860,7 +860,7 @@ fts_index_fetch_words(
error = fts_eval_sql(optim->trx, graph);
}
- if (error == DB_SUCCESS) {
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
//FIXME fts_sql_commit(optim->trx);
break;
} else {
@@ -877,7 +877,7 @@ fts_index_fetch_words(
optim->trx->error_state = DB_SUCCESS;
} else {
- ib::error() << "(" << ut_strerr(error)
+ ib::error() << "(" << error
<< ") while reading document.";
break; /* Exit the loop. */
@@ -920,7 +920,7 @@ fts_fetch_doc_ids(
int i = 0;
sel_node_t* sel_node = static_cast<sel_node_t*>(row);
fts_doc_ids_t* fts_doc_ids = static_cast<fts_doc_ids_t*>(user_arg);
- fts_update_t* update = static_cast<fts_update_t*>(
+ doc_id_t* update = static_cast<doc_id_t*>(
ib_vector_push(fts_doc_ids->doc_ids, NULL));
for (exp = sel_node->select_list;
@@ -936,8 +936,7 @@ fts_fetch_doc_ids(
/* Note: The column numbers below must match the SELECT. */
switch (i) {
case 0: /* DOC_ID */
- update->fts_indexes = NULL;
- update->doc_id = fts_read_doc_id(
+ *update = fts_read_doc_id(
static_cast<byte*>(data));
break;
@@ -1005,7 +1004,7 @@ fts_table_fetch_doc_ids(
mutex_exit(&dict_sys->mutex);
if (error == DB_SUCCESS) {
- ib_vector_sort(doc_ids->doc_ids, fts_update_doc_id_cmp);
+ ib_vector_sort(doc_ids->doc_ids, fts_doc_id_cmp);
}
if (alloc_bk_trx) {
@@ -1022,7 +1021,7 @@ Do a binary search for a doc id in the array
int
fts_bsearch(
/*========*/
- fts_update_t* array, /*!< in: array to sort */
+ doc_id_t* array, /*!< in: array to sort */
int lower, /*!< in: the array lower bound */
int upper, /*!< in: the array upper bound */
doc_id_t doc_id) /*!< in: the doc id to search for */
@@ -1036,9 +1035,9 @@ fts_bsearch(
while (lower < upper) {
int i = (lower + upper) >> 1;
- if (doc_id > array[i].doc_id) {
+ if (doc_id > array[i]) {
lower = i + 1;
- } else if (doc_id < array[i].doc_id) {
+ } else if (doc_id < array[i]) {
upper = i - 1;
} else {
return(i); /* Found. */
@@ -1047,7 +1046,7 @@ fts_bsearch(
}
if (lower == upper && lower < orig_size) {
- if (doc_id == array[lower].doc_id) {
+ if (doc_id == array[lower]) {
return(lower);
} else if (lower == 0) {
return(-1);
@@ -1074,7 +1073,7 @@ fts_optimize_lookup(
{
int pos;
int upper = static_cast<int>(ib_vector_size(doc_ids));
- fts_update_t* array = (fts_update_t*) doc_ids->data;
+ doc_id_t* array = (doc_id_t*) doc_ids->data;
pos = fts_bsearch(array, static_cast<int>(lower), upper, first_doc_id);
@@ -1087,10 +1086,10 @@ fts_optimize_lookup(
/* If i is 1, it could be first_doc_id is less than
either the first or second array item, do a
double check */
- if (i == 1 && array[0].doc_id <= last_doc_id
- && first_doc_id < array[0].doc_id) {
+ if (i == 1 && array[0] <= last_doc_id
+ && first_doc_id < array[0]) {
pos = 0;
- } else if (i < upper && array[i].doc_id <= last_doc_id) {
+ } else if (i < upper && array[i] <= last_doc_id) {
/* Check if the "next" doc id is within the
first & last doc id of the node. */
@@ -1229,12 +1228,12 @@ test_again:
delta for decoding the entries following this document's
entries. */
if (*del_pos >= 0 && *del_pos < (int) ib_vector_size(del_vec)) {
- fts_update_t* update;
+ doc_id_t* update;
- update = (fts_update_t*) ib_vector_get(
+ update = (doc_id_t*) ib_vector_get(
del_vec, *del_pos);
- del_doc_id = update->doc_id;
+ del_doc_id = *update;
}
if (enc->src_ilist_ptr == src_node->ilist && doc_id == 0) {
@@ -1357,12 +1356,6 @@ fts_optimize_word(
enc.src_last_doc_id = 0;
enc.src_ilist_ptr = NULL;
- if (fts_enable_diag_print) {
- word->text.f_str[word->text.f_len] = 0;
- ib::info() << "FTS_OPTIMIZE: optimize \"" << word->text.f_str
- << "\"";
- }
-
while (i < size) {
ulint copied;
fts_node_t* src_node;
@@ -1440,11 +1433,6 @@ fts_optimize_write_word(
ut_ad(fts_table->charset);
- if (fts_enable_diag_print) {
- ib::info() << "FTS_OPTIMIZE: processed \"" << word->f_str
- << "\"";
- }
-
pars_info_bind_varchar_literal(
info, "word", word->f_str, word->f_len);
@@ -1462,8 +1450,8 @@ fts_optimize_write_word(
error = fts_eval_sql(trx, graph);
- if (error != DB_SUCCESS) {
- ib::error() << "(" << ut_strerr(error) << ") during optimize,"
+ if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
+ ib::error() << "(" << error << ") during optimize,"
" when deleting a word from the FTS index.";
}
@@ -1486,8 +1474,8 @@ fts_optimize_write_word(
error = fts_write_node(
trx, &graph, fts_table, word, node);
- if (error != DB_SUCCESS) {
- ib::error() << "(" << ut_strerr(error) << ")"
+ if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
+ ib::error() << "(" << error << ")"
" during optimize, while adding a"
" word to the FTS index.";
}
@@ -1876,9 +1864,8 @@ fts_optimize_index_completed(
error = fts_config_set_index_value(
optim->trx, index, FTS_LAST_OPTIMIZED_WORD, &word);
- if (error != DB_SUCCESS) {
-
- ib::error() << "(" << ut_strerr(error) << ") while updating"
+ if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
+ ib::error() << "(" << error << ") while updating"
" last optimized word!";
}
@@ -2020,7 +2007,7 @@ fts_optimize_purge_deleted_doc_ids(
ulint i;
pars_info_t* info;
que_t* graph;
- fts_update_t* update;
+ doc_id_t* update;
doc_id_t write_doc_id;
dberr_t error = DB_SUCCESS;
char deleted[MAX_FULL_NAME_LEN];
@@ -2030,11 +2017,11 @@ fts_optimize_purge_deleted_doc_ids(
ut_a(ib_vector_size(optim->to_delete->doc_ids) > 0);
- update = static_cast<fts_update_t*>(
+ update = static_cast<doc_id_t*>(
ib_vector_get(optim->to_delete->doc_ids, 0));
/* Convert to "storage" byte order. */
- fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
+ fts_write_doc_id((byte*) &write_doc_id, *update);
/* This is required for the SQL parser to work. It must be able
to find the following variables. So we do it twice. */
@@ -2056,11 +2043,11 @@ fts_optimize_purge_deleted_doc_ids(
/* Delete the doc ids that were copied at the start. */
for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) {
- update = static_cast<fts_update_t*>(ib_vector_get(
+ update = static_cast<doc_id_t*>(ib_vector_get(
optim->to_delete->doc_ids, i));
/* Convert to "storage" byte order. */
- fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
+ fts_write_doc_id((byte*) &write_doc_id, *update);
fts_bind_doc_id(info, "doc_id1", &write_doc_id);
@@ -2430,7 +2417,7 @@ fts_optimize_table(
fts_optimize_t* optim = NULL;
fts_t* fts = table->fts;
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "FTS start optimize " << table->name;
}
@@ -2482,7 +2469,7 @@ fts_optimize_table(
if (error == DB_SUCCESS
&& optim->n_completed == ib_vector_size(fts->indexes)) {
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "FTS_OPTIMIZE: Completed"
" Optimize, cleanup DELETED table";
}
@@ -2505,7 +2492,7 @@ fts_optimize_table(
fts_optimize_free(optim);
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "FTS end optimize " << table->name;
}
@@ -2586,6 +2573,11 @@ fts_optimize_remove_table(
if (fts_opt_start_shutdown) {
ib::info() << "Try to remove table " << table->name
<< " after FTS optimize thread exiting.";
+ /* If the table can't be removed then wait till
+ fts optimize thread shuts down */
+ while (fts_optimize_wq) {
+ os_thread_sleep(10000);
+ }
return;
}
@@ -2616,9 +2608,13 @@ fts_optimize_remove_table(
os_event_destroy(event);
- ut_d(mutex_enter(&fts_optimize_wq->mutex));
- ut_ad(!table->fts->in_queue);
- ut_d(mutex_exit(&fts_optimize_wq->mutex));
+#ifdef UNIV_DEBUG
+ if (!fts_opt_start_shutdown) {
+ mutex_enter(&fts_optimize_wq->mutex);
+ ut_ad(!table->fts->in_queue);
+ mutex_exit(&fts_optimize_wq->mutex);
+ }
+#endif /* UNIV_DEBUG */
}
/** Send sync fts cache for the table.
@@ -2645,8 +2641,6 @@ fts_optimize_request_sync_table(
ib_wqueue_add(fts_optimize_wq, msg, msg->heap, true);
- table->fts->in_queue = true;
-
mutex_exit(&fts_optimize_wq->mutex);
}
@@ -2692,7 +2686,7 @@ static bool fts_optimize_del_table(const dict_table_t* table)
slot = static_cast<fts_slot_t*>(ib_vector_get(fts_slots, i));
if (slot->table == table) {
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "FTS Optimize Removing table "
<< table->name;
}
@@ -2805,8 +2799,7 @@ fts_optimize_thread(
/* Assign number of tables added in fts_slots_t to n_tables */
n_tables = ib_vector_size(fts_slots);
- while (!done && srv_shutdown_state == SRV_SHUTDOWN_NONE) {
-
+ while (!done && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
/* If there is no message in the queue and we have tables
to optimize then optimize the tables. */
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index 6baec777270..be758c13d52 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -144,6 +144,8 @@ struct fts_query_t {
ib_rbt_t* wildcard_words; /*!< words with wildcard */
bool multi_exist; /*!< multiple FTS_EXIST oper */
+ byte visiting_sub_exp; /*!< count of nested
+ fts_ast_visit_sub_exp() */
st_mysql_ftparser* parser; /*!< fts plugin parser */
};
@@ -730,10 +732,10 @@ fts_query_union_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's not already in our set. */
- if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
+ if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) != 0) {
fts_ranking_t ranking;
@@ -761,10 +763,10 @@ fts_query_remove_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's in our set. */
- if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
+ if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) == 0) {
ut_free(rbt_remove_node(query->doc_ids, parent.last));
@@ -791,10 +793,10 @@ fts_query_change_ranking(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's in our set. */
- if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
+ if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) == 0) {
fts_ranking_t* ranking;
@@ -828,7 +830,7 @@ fts_query_intersect_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
fts_ranking_t* ranking= NULL;
/* There are three types of intersect:
@@ -840,7 +842,7 @@ fts_query_intersect_doc_id(
if it matches 'b' and it's in doc_ids.(multi_exist = true). */
/* Check if the doc id is deleted and it's in our set */
- if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0) {
+ if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0) {
fts_ranking_t new_ranking;
if (rbt_search(query->doc_ids, &parent, &doc_id) != 0) {
@@ -2447,9 +2449,8 @@ fts_query_match_document(
get_doc, match->doc_id, NULL, FTS_FETCH_DOC_BY_ID_EQUAL,
fts_query_fetch_document, &phrase);
- if (error != DB_SUCCESS) {
- ib::error() << "(" << ut_strerr(error)
- << ") matching document.";
+ if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
+ ib::error() << "(" << error << ") matching document.";
} else {
*found = phrase.found;
}
@@ -2495,8 +2496,8 @@ fts_query_is_in_proximity_range(
&get_doc, match[0]->doc_id, NULL, FTS_FETCH_DOC_BY_ID_EQUAL,
fts_query_fetch_document, &phrase);
- if (err != DB_SUCCESS) {
- ib::error() << "(" << ut_strerr(err) << ") in verification"
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
+ ib::error() << "(" << err << ") in verification"
" phase of proximity search";
}
@@ -2743,7 +2744,7 @@ fts_query_phrase_search(
/* Ignore empty strings. */
if (num_token > 0) {
- fts_string_t* token;
+ fts_string_t* token = NULL;
fts_fetch_t fetch;
trx_t* trx = query->trx;
fts_ast_oper_t oper = query->oper;
@@ -2964,6 +2965,8 @@ fts_query_get_token(
return(new_ptr);
}
+static dberr_t fts_ast_visit_sub_exp(fts_ast_node_t*, fts_ast_callback, void*);
+
/*****************************************************************//**
Visit every node of the AST. */
static
@@ -3088,6 +3091,14 @@ fts_ast_visit_sub_exp(
ut_a(node->type == FTS_AST_SUBEXP_LIST);
+ /* To avoid stack overflow, we limit the mutual recursion
+ depth between fts_ast_visit(), fts_query_visitor() and
+ fts_ast_visit_sub_exp(). */
+ if (query->visiting_sub_exp++ > 31) {
+ query->error = DB_OUT_OF_MEMORY;
+ DBUG_RETURN(query->error);
+ }
+
cur_oper = query->oper;
/* Save current result set */
@@ -3110,6 +3121,7 @@ fts_ast_visit_sub_exp(
/* Reinstate parent node state */
query->multi_exist = multi_exist;
query->oper = cur_oper;
+ query->visiting_sub_exp--;
/* Merge the sub-expression result with the parent result set. */
subexpr_doc_ids = query->doc_ids;
@@ -3501,14 +3513,6 @@ fts_query_calculate_idf(
/ (double) word_freq->doc_count);
}
}
-
- if (fts_enable_diag_print) {
- ib::info() << "'" << word_freq->word.f_str << "' -> "
- << query->total_docs << "/"
- << word_freq->doc_count << " "
- << std::setw(6) << std::setprecision(5)
- << word_freq->idf;
- }
}
}
@@ -3649,8 +3653,8 @@ fts_query_prepare_result(
if (query->flags == FTS_OPT_RANKING) {
fts_word_freq_t* word_freq;
ulint size = ib_vector_size(query->deleted->doc_ids);
- fts_update_t* array =
- (fts_update_t*) query->deleted->doc_ids->data;
+ doc_id_t* updates =
+ (doc_id_t*) query->deleted->doc_ids->data;
node = rbt_first(query->word_freqs);
ut_ad(node);
@@ -3665,7 +3669,7 @@ fts_query_prepare_result(
doc_freq = rbt_value(fts_doc_freq_t, node);
/* Don't put deleted docs into result */
- if (fts_bsearch(array, 0, static_cast<int>(size),
+ if (fts_bsearch(updates, 0, static_cast<int>(size),
doc_freq->doc_id) >= 0) {
/* one less matching doc count */
--word_freq->doc_count;
@@ -3884,7 +3888,7 @@ fts_query_parse(
} else {
query->root = state.root;
- if (fts_enable_diag_print && query->root != NULL) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print) && query->root) {
fts_ast_node_print(query->root);
}
}
@@ -4016,7 +4020,7 @@ fts_query(
DEBUG_SYNC_C("fts_deleted_doc_ids_append");
/* Sort the vector so that we can do a binary search over the ids. */
- ib_vector_sort(query.deleted->doc_ids, fts_update_doc_id_cmp);
+ ib_vector_sort(query.deleted->doc_ids, fts_doc_id_cmp);
/* Convert the query string to lower case before parsing. We own
the ut_malloc'ed result and so remember to free it before return. */
@@ -4108,7 +4112,7 @@ fts_query(
ut_free(lc_query_str);
- if (fts_enable_diag_print && (*result)) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print) && (*result)) {
ulint diff_time = ut_time_ms() - start_time_ms;
ib::info() << "FTS Search Processing time: "
@@ -4264,7 +4268,7 @@ fts_expand_query(
query->total_size += SIZEOF_RBT_CREATE;
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
fts_print_doc_id(query);
}
diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc
index 376662bba8a..e61f2118e70 100644
--- a/storage/innobase/fts/fts0sql.cc
+++ b/storage/innobase/fts/fts0sql.cc
@@ -55,28 +55,23 @@ fts_get_table_id(
long */
{
int len;
- bool hex_name = DICT_TF2_FLAG_IS_SET(fts_table->table,
- DICT_TF2_FTS_AUX_HEX_NAME);
ut_a(fts_table->table != NULL);
switch (fts_table->type) {
case FTS_COMMON_TABLE:
- len = fts_write_object_id(fts_table->table_id, table_id,
- hex_name);
+ len = fts_write_object_id(fts_table->table_id, table_id);
break;
case FTS_INDEX_TABLE:
- len = fts_write_object_id(fts_table->table_id, table_id,
- hex_name);
+ len = fts_write_object_id(fts_table->table_id, table_id);
table_id[len] = '_';
++len;
table_id += len;
- len += fts_write_object_id(fts_table->index_id, table_id,
- hex_name);
+ len += fts_write_object_id(fts_table->index_id, table_id);
break;
default:
diff --git a/storage/innobase/gis/gis0geo.cc b/storage/innobase/gis/gis0geo.cc
index cad3877d3e9..3a727185632 100644
--- a/storage/innobase/gis/gis0geo.cc
+++ b/storage/innobase/gis/gis0geo.cc
@@ -444,26 +444,6 @@ pick_seeds(
}
}
-/*********************************************************//**
-Generates a random iboolean value.
-@return the random value */
-static
-ibool
-ut_rnd_gen_ibool(void)
-/*=================*/
-{
- ulint x;
-
- x = ut_rnd_gen_ulint();
-
- if (((x >> 20) + (x >> 15)) & 1) {
-
- return(TRUE);
- }
-
- return(FALSE);
-}
-
/*************************************************************//**
Select next node and group where to add. */
static
@@ -500,8 +480,7 @@ pick_next(
/* Introduce some randomness if the record
is identical */
if (diff == 0) {
- diff = static_cast<double>(
- ut_rnd_gen_ibool());
+ diff = static_cast<double>(ut_rnd_gen() & 1);
}
*n_group = 1 + (diff > 0);
@@ -801,35 +780,3 @@ rtree_area_overlapping(
return(area);
}
-
-/** Get the wkb of default POINT value, which represents POINT(0 0)
-if it's of dimension 2, etc.
-@param[in] n_dims dimensions
-@param[out] wkb wkb buffer for default POINT
-@param[in] len length of wkb buffer
-@return non-0 indicate the length of wkb of the default POINT,
-0 if the buffer is too small */
-uint
-get_wkb_of_default_point(
- uint n_dims,
- uchar* wkb,
- uint len)
-{
- // JAN: TODO: MYSQL 5.7 GIS
- #define GEOM_HEADER_SIZE 16
- if (len < GEOM_HEADER_SIZE + sizeof(double) * n_dims) {
- return(0);
- }
-
- /** POINT wkb comprises SRID, wkb header(byte order and type)
- and coordinates of the POINT */
- len = GEOM_HEADER_SIZE + sizeof(double) * n_dims;
- /** We always use 0 as default coordinate */
- memset(wkb, 0, len);
- /** We don't need to write SRID, write 0x01 for Byte Order */
- mach_write_to_n_little_endian(wkb + SRID_SIZE, 1, 0x01);
- /** Write wkbType::wkbPoint for the POINT type */
- mach_write_to_n_little_endian(wkb + SRID_SIZE + 1, 4, wkbPoint);
-
- return(len);
-}
diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc
index ce1749820c3..e3d5a09f736 100644
--- a/storage/innobase/gis/gis0rtree.cc
+++ b/storage/innobase/gis/gis0rtree.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, MariaDB Corporation.
+Copyright (c) 2019, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -50,7 +50,7 @@ rtr_page_split_initialize_nodes(
btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
- ulint** offsets,/*!< in: offsets on inserted record */
+ rec_offs** offsets,/*!< in: offsets on inserted record */
const dtuple_t* tuple, /*!< in: tuple to insert */
double** buf_pos)/*!< in/out: current buffer position */
{
@@ -193,7 +193,7 @@ rtr_update_mbr_field_in_place(
/*==========================*/
dict_index_t* index, /*!< in: spatial index. */
rec_t* rec, /*!< in/out: rec to be modified.*/
- ulint* offsets, /*!< in/out: offsets on rec. */
+ rec_offs* offsets, /*!< in/out: offsets on rec. */
rtr_mbr_t* mbr, /*!< in: the new mbr. */
mtr_t* mtr) /*!< in: mtr */
{
@@ -267,7 +267,7 @@ bool
rtr_update_mbr_field(
/*=================*/
btr_cur_t* cursor, /*!< in/out: cursor pointed to rec.*/
- ulint* offsets, /*!< in/out: offsets on rec. */
+ rec_offs* offsets, /*!< in/out: offsets on rec. */
btr_cur_t* cursor2, /*!< in/out: cursor pointed to rec
that should be deleted.
this cursor is for btr_compress to
@@ -297,7 +297,7 @@ rtr_update_mbr_field(
bool ins_suc = true;
ulint cur2_pos = 0;
ulint del_page_no = 0;
- ulint* offsets2;
+ rec_offs* offsets2;
rec = btr_cur_get_rec(cursor);
page = page_align(rec);
@@ -384,7 +384,7 @@ rtr_update_mbr_field(
}
if (cursor2) {
- ulint* offsets2;
+ rec_offs* offsets2;
if (page_zip) {
cursor2->page_cur.rec
@@ -406,7 +406,7 @@ rtr_update_mbr_field(
page_cur_t page_cur;
rec_t* insert_rec;
- ulint* insert_offsets = NULL;
+ rec_offs* insert_offsets = NULL;
ulint old_pos;
rec_t* old_rec;
@@ -438,7 +438,7 @@ update_mbr:
/* When there're not only 1 rec in the page, we do delete/insert
to avoid page split. */
rec_t* insert_rec;
- ulint* insert_offsets = NULL;
+ rec_offs* insert_offsets = NULL;
rec_t* next_rec;
/* Delete the rec which cursor point to. */
@@ -639,7 +639,7 @@ rtr_adjust_upper_level(
page_zip_des_t* new_page_zip;
dict_index_t* index = sea_cur->index;
btr_cur_t cursor;
- ulint* offsets;
+ rec_offs* offsets;
mem_heap_t* heap;
ulint level;
dtuple_t* node_ptr_upper;
@@ -809,8 +809,8 @@ rtr_split_page_move_rec_list(
page_cur_t new_page_cursor;
page_t* page;
page_t* new_page;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
page_zip_des_t* new_page_zip
= buf_block_get_page_zip(new_block);
rec_t* rec;
@@ -970,7 +970,7 @@ rtr_page_split_and_insert(
btr_cur_t* cursor, /*!< in/out: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
- ulint** offsets,/*!< out: offsets on inserted record */
+ rec_offs** offsets,/*!< out: offsets on inserted record */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
@@ -1322,7 +1322,7 @@ rtr_ins_enlarge_mbr(
mem_heap_t* heap;
dict_index_t* index = btr_cur->index;
page_cur_t* page_cursor;
- ulint* offsets;
+ rec_offs* offsets;
node_visit_t* node_visit;
btr_cur_t cursor;
page_t* page;
@@ -1406,10 +1406,10 @@ rtr_page_copy_rec_list_end_no_locks(
page_cur_t page_cur;
page_cur_t cur1;
rec_t* cur_rec;
- ulint offsets_1[REC_OFFS_NORMAL_SIZE];
- ulint* offsets1 = offsets_1;
- ulint offsets_2[REC_OFFS_NORMAL_SIZE];
- ulint* offsets2 = offsets_2;
+ rec_offs offsets_1[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets1 = offsets_1;
+ rec_offs offsets_2[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets2 = offsets_2;
ulint moved = 0;
bool is_leaf = page_is_leaf(new_page);
@@ -1449,10 +1449,9 @@ rtr_page_copy_rec_list_end_no_locks(
offsets2 = rec_get_offsets(cur_rec, index, offsets2,
is_leaf,
ULINT_UNDEFINED, &heap);
- cmp = cmp_rec_rec_with_match(cur1_rec, cur_rec,
- offsets1, offsets2,
- index, FALSE,
- &cur_matched_fields);
+ cmp = cmp_rec_rec(cur1_rec, cur_rec,
+ offsets1, offsets2, index, false,
+ &cur_matched_fields);
if (cmp < 0) {
page_cur_move_to_prev(&page_cur);
break;
@@ -1533,10 +1532,10 @@ rtr_page_copy_rec_list_start_no_locks(
{
page_cur_t cur1;
rec_t* cur_rec;
- ulint offsets_1[REC_OFFS_NORMAL_SIZE];
- ulint* offsets1 = offsets_1;
- ulint offsets_2[REC_OFFS_NORMAL_SIZE];
- ulint* offsets2 = offsets_2;
+ rec_offs offsets_1[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets1 = offsets_1;
+ rec_offs offsets_2[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets2 = offsets_2;
page_cur_t page_cur;
ulint moved = 0;
bool is_leaf = page_is_leaf(buf_block_get_frame(block));
@@ -1564,15 +1563,13 @@ rtr_page_copy_rec_list_start_no_locks(
while (!page_rec_is_supremum(cur_rec)) {
ulint cur_matched_fields = 0;
- int cmp;
offsets2 = rec_get_offsets(cur_rec, index, offsets2,
is_leaf,
ULINT_UNDEFINED, &heap);
- cmp = cmp_rec_rec_with_match(cur1_rec, cur_rec,
- offsets1, offsets2,
- index, FALSE,
- &cur_matched_fields);
+ int cmp = cmp_rec_rec(cur1_rec, cur_rec,
+ offsets1, offsets2, index, false,
+ &cur_matched_fields);
if (cmp < 0) {
page_cur_move_to_prev(&page_cur);
cur_rec = page_cur_get_rec(&page_cur);
@@ -1645,8 +1642,8 @@ rtr_merge_mbr_changed(
/*==================*/
btr_cur_t* cursor, /*!< in/out: cursor */
btr_cur_t* cursor2, /*!< in: the other cursor */
- ulint* offsets, /*!< in: rec offsets */
- ulint* offsets2, /*!< in: rec offsets */
+ rec_offs* offsets, /*!< in: rec offsets */
+ rec_offs* offsets2, /*!< in: rec offsets */
rtr_mbr_t* new_mbr, /*!< out: MBR to update */
buf_block_t* merge_block, /*!< in: page to merge */
buf_block_t* block, /*!< in: page be merged */
@@ -1692,8 +1689,8 @@ rtr_merge_and_update_mbr(
/*=====================*/
btr_cur_t* cursor, /*!< in/out: cursor */
btr_cur_t* cursor2, /*!< in: the other cursor */
- ulint* offsets, /*!< in: rec offsets */
- ulint* offsets2, /*!< in: rec offsets */
+ rec_offs* offsets, /*!< in: rec offsets */
+ rec_offs* offsets2, /*!< in: rec offsets */
page_t* child_page, /*!< in: the page. */
buf_block_t* merge_block, /*!< in: page to merge */
buf_block_t* block, /*!< in: page be merged */
@@ -1762,7 +1759,7 @@ rtr_check_same_block(
{
ulint page_no = childb->page.id.page_no();
- ulint* offsets;
+ rec_offs* offsets;
rec_t* rec = page_rec_get_next(page_get_infimum_rec(
buf_block_get_frame(parentb)));
@@ -1793,7 +1790,7 @@ rtr_rec_cal_increase(
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
double* area) /*!< out: increased area */
{
const dfield_t* dtuple_field;
@@ -1889,7 +1886,7 @@ rtr_estimate_n_rows_in_range(
rec_t* rec;
byte* field;
ulint len;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
mem_heap_t* heap;
heap = mem_heap_create(512);
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 84307659873..c372a3f1cd4 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -527,7 +527,7 @@ rtr_compare_cursor_rec(
mem_heap_t** heap) /*!< in: memory heap */
{
const rec_t* rec;
- ulint* offsets;
+ rec_offs* offsets;
rec = btr_cur_get_rec(cursor);
@@ -590,7 +590,7 @@ rtr_pcur_open_low(
}
btr_cur_search_to_nth_level(index, level, tuple, mode, latch_mode,
- btr_cursor, 0, file, line, mtr);
+ btr_cursor, 0, file, line, mtr, 0);
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->trx_if_known = NULL;
@@ -669,7 +669,7 @@ rtr_page_get_father(
{
mem_heap_t* heap = mem_heap_create(100);
#ifdef UNIV_DEBUG
- ulint* offsets;
+ rec_offs* offsets;
offsets = rtr_page_get_father_block(
NULL, heap, index, block, mtr, sea_cur, cursor);
@@ -686,13 +686,128 @@ rtr_page_get_father(
mem_heap_free(heap);
}
+/********************************************************************//**
+Returns the upper level node pointer to a R-Tree page. It is assumed
+that mtr holds an x-latch on the tree. */
+static void rtr_get_father_node(
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: the tree level of search */
+ const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
+ tuple must be set so that it cannot get
+ compared to the node ptr page number field! */
+ btr_cur_t* sea_cur,/*!< in: search cursor */
+ btr_cur_t* btr_cur,/*!< in/out: tree cursor; the cursor page is
+ s- or x-latched, but see also above! */
+ ulint page_no,/*!< Current page no */
+ mtr_t* mtr) /*!< in: mtr */
+{
+ mem_heap_t* heap = NULL;
+ bool ret = false;
+ const rec_t* rec;
+ ulint n_fields;
+ bool new_rtr = false;
+
+ /* Try to optimally locate the parent node. Level should always
+ less than sea_cur->tree_height unless the root is splitting */
+ if (sea_cur && sea_cur->tree_height > level) {
+
+ ut_ad(mtr_memo_contains_flagged(mtr,
+ dict_index_get_lock(index),
+ MTR_MEMO_X_LOCK
+ | MTR_MEMO_SX_LOCK));
+ ret = rtr_cur_restore_position(
+ BTR_CONT_MODIFY_TREE, sea_cur, level, mtr);
+
+ /* Once we block shrink tree nodes while there are
+ active search on it, this optimal locating should always
+ succeeds */
+ ut_ad(ret);
+
+ if (ret) {
+ btr_pcur_t* r_cursor = rtr_get_parent_cursor(
+ sea_cur, level, false);
+
+ rec = btr_pcur_get_rec(r_cursor);
+
+ ut_ad(r_cursor->rel_pos == BTR_PCUR_ON);
+ page_cur_position(rec,
+ btr_pcur_get_block(r_cursor),
+ btr_cur_get_page_cur(btr_cur));
+ btr_cur->rtr_info = sea_cur->rtr_info;
+ btr_cur->tree_height = sea_cur->tree_height;
+ ut_ad(rtr_compare_cursor_rec(
+ index, btr_cur, page_no, &heap));
+ goto func_exit;
+ }
+ }
+
+ /* We arrive here in one of two scenario
+ 1) check table and btr_valide
+ 2) index root page being raised */
+ ut_ad(!sea_cur || sea_cur->tree_height == level);
+
+ if (btr_cur->rtr_info) {
+ rtr_clean_rtr_info(btr_cur->rtr_info, true);
+ } else {
+ new_rtr = true;
+ }
+
+ btr_cur->rtr_info = rtr_create_rtr_info(false, false, btr_cur, index);
+
+ if (sea_cur && sea_cur->tree_height == level) {
+ /* root split, and search the new root */
+ btr_cur_search_to_nth_level(
+ index, level, tuple, PAGE_CUR_RTREE_LOCATE,
+ BTR_CONT_MODIFY_TREE, btr_cur, 0,
+ __FILE__, __LINE__, mtr, 0);
+
+ } else {
+ /* btr_validate */
+ ut_ad(level >= 1);
+ ut_ad(!sea_cur);
+
+ btr_cur_search_to_nth_level(
+ index, level, tuple, PAGE_CUR_RTREE_LOCATE,
+ BTR_CONT_MODIFY_TREE, btr_cur, 0,
+ __FILE__, __LINE__, mtr, 0);
+
+ rec = btr_cur_get_rec(btr_cur);
+ n_fields = dtuple_get_n_fields_cmp(tuple);
+
+ if (page_rec_is_infimum(rec)
+ || (btr_cur->low_match != n_fields)) {
+ ret = rtr_pcur_getnext_from_path(
+ tuple, PAGE_CUR_RTREE_LOCATE, btr_cur,
+ level, BTR_CONT_MODIFY_TREE,
+ true, mtr);
+
+ ut_ad(ret && btr_cur->low_match == n_fields);
+ }
+ }
+
+ ret = rtr_compare_cursor_rec(
+ index, btr_cur, page_no, &heap);
+
+ ut_ad(ret);
+
+func_exit:
+ if (heap) {
+ mem_heap_free(heap);
+ }
+
+ if (new_rtr && btr_cur->rtr_info) {
+ rtr_clean_rtr_info(btr_cur->rtr_info, true);
+ btr_cur->rtr_info = NULL;
+ }
+}
+
/** Returns the upper level node pointer to a R-Tree page. It is assumed
that mtr holds an SX-latch or X-latch on the tree.
@return rec_get_offsets() of the node pointer record */
static
-ulint*
+rec_offs*
rtr_page_get_father_node_ptr(
- ulint* offsets,/*!< in: work area for the return value */
+ rec_offs* offsets,/*!< in: work area for the return value */
mem_heap_t* heap, /*!< in: memory heap to use */
btr_cur_t* sea_cur,/*!< in: search cursor */
btr_cur_t* cursor, /*!< in: cursor pointing to user record,
@@ -785,10 +900,10 @@ rtr_page_get_father_node_ptr(
Returns the father block to a page. It is assumed that mtr holds
an X or SX latch on the tree.
@return rec_get_offsets() of the node pointer record */
-ulint*
+rec_offs*
rtr_page_get_father_block(
/*======================*/
- ulint* offsets,/*!< in: work area for the return value */
+ rec_offs* offsets,/*!< in: work area for the return value */
mem_heap_t* heap, /*!< in: memory heap to use */
dict_index_t* index, /*!< in: b-tree index */
buf_block_t* block, /*!< in: child page in the index */
@@ -806,123 +921,6 @@ rtr_page_get_father_block(
cursor, mtr));
}
-/********************************************************************//**
-Returns the upper level node pointer to a R-Tree page. It is assumed
-that mtr holds an x-latch on the tree. */
-void
-rtr_get_father_node(
-/*================*/
- dict_index_t* index, /*!< in: index */
- ulint level, /*!< in: the tree level of search */
- const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
- tuple must be set so that it cannot get
- compared to the node ptr page number field! */
- btr_cur_t* sea_cur,/*!< in: search cursor */
- btr_cur_t* btr_cur,/*!< in/out: tree cursor; the cursor page is
- s- or x-latched, but see also above! */
- ulint page_no,/*!< Current page no */
- mtr_t* mtr) /*!< in: mtr */
-{
- mem_heap_t* heap = NULL;
- bool ret = false;
- const rec_t* rec;
- ulint n_fields;
- bool new_rtr = false;
-
- /* Try to optimally locate the parent node. Level should always
- less than sea_cur->tree_height unless the root is splitting */
- if (sea_cur && sea_cur->tree_height > level) {
-
- ut_ad(mtr_memo_contains_flagged(mtr,
- dict_index_get_lock(index),
- MTR_MEMO_X_LOCK
- | MTR_MEMO_SX_LOCK));
- ret = rtr_cur_restore_position(
- BTR_CONT_MODIFY_TREE, sea_cur, level, mtr);
-
- /* Once we block shrink tree nodes while there are
- active search on it, this optimal locating should always
- succeeds */
- ut_ad(ret);
-
- if (ret) {
- btr_pcur_t* r_cursor = rtr_get_parent_cursor(
- sea_cur, level, false);
-
- rec = btr_pcur_get_rec(r_cursor);
-
- ut_ad(r_cursor->rel_pos == BTR_PCUR_ON);
- page_cur_position(rec,
- btr_pcur_get_block(r_cursor),
- btr_cur_get_page_cur(btr_cur));
- btr_cur->rtr_info = sea_cur->rtr_info;
- btr_cur->tree_height = sea_cur->tree_height;
- ut_ad(rtr_compare_cursor_rec(
- index, btr_cur, page_no, &heap));
- goto func_exit;
- }
- }
-
- /* We arrive here in one of two scenario
- 1) check table and btr_valide
- 2) index root page being raised */
- ut_ad(!sea_cur || sea_cur->tree_height == level);
-
- if (btr_cur->rtr_info) {
- rtr_clean_rtr_info(btr_cur->rtr_info, true);
- } else {
- new_rtr = true;
- }
-
- btr_cur->rtr_info = rtr_create_rtr_info(false, false, btr_cur, index);
-
- if (sea_cur && sea_cur->tree_height == level) {
- /* root split, and search the new root */
- btr_cur_search_to_nth_level(
- index, level, tuple, PAGE_CUR_RTREE_LOCATE,
- BTR_CONT_MODIFY_TREE, btr_cur, 0,
- __FILE__, __LINE__, mtr);
-
- } else {
- /* btr_validate */
- ut_ad(level >= 1);
- ut_ad(!sea_cur);
-
- btr_cur_search_to_nth_level(
- index, level, tuple, PAGE_CUR_RTREE_LOCATE,
- BTR_CONT_MODIFY_TREE, btr_cur, 0,
- __FILE__, __LINE__, mtr);
-
- rec = btr_cur_get_rec(btr_cur);
- n_fields = dtuple_get_n_fields_cmp(tuple);
-
- if (page_rec_is_infimum(rec)
- || (btr_cur->low_match != n_fields)) {
- ret = rtr_pcur_getnext_from_path(
- tuple, PAGE_CUR_RTREE_LOCATE, btr_cur,
- level, BTR_CONT_MODIFY_TREE,
- true, mtr);
-
- ut_ad(ret && btr_cur->low_match == n_fields);
- }
- }
-
- ret = rtr_compare_cursor_rec(
- index, btr_cur, page_no, &heap);
-
- ut_ad(ret);
-
-func_exit:
- if (heap) {
- mem_heap_free(heap);
- }
-
- if (new_rtr && btr_cur->rtr_info) {
- rtr_clean_rtr_info(btr_cur->rtr_info, true);
- btr_cur->rtr_info = NULL;
- }
-}
-
/*******************************************************************//**
Create a RTree search info structure */
rtr_info_t*
@@ -1303,8 +1301,8 @@ rtr_cur_restore_position(
#ifdef UNIV_DEBUG
do {
const rec_t* rec;
- const ulint* offsets1;
- const ulint* offsets2;
+ const rec_offs* offsets1;
+ const rec_offs* offsets2;
ulint comp;
rec = btr_pcur_get_rec(r_cursor);
@@ -1377,8 +1375,8 @@ search_again:
if (low_match == r_cursor->old_n_fields) {
const rec_t* rec;
- const ulint* offsets1;
- const ulint* offsets2;
+ const rec_offs* offsets1;
+ const rec_offs* offsets2;
ulint comp;
rec = btr_pcur_get_rec(r_cursor);
@@ -1424,7 +1422,7 @@ rtr_leaf_push_match_rec(
/*====================*/
const rec_t* rec, /*!< in: record to copy */
rtr_info_t* rtr_info, /*!< in/out: search stack */
- ulint* offsets, /*!< in: offsets */
+ rec_offs* offsets, /*!< in: offsets */
bool is_comp) /*!< in: is compact format */
{
byte* buf;
@@ -1610,7 +1608,7 @@ void
rtr_get_mbr_from_rec(
/*=================*/
const rec_t* rec, /*!< in: data tuple */
- const ulint* offsets,/*!< in: offsets array */
+ const rec_offs* offsets,/*!< in: offsets array */
rtr_mbr_t* mbr) /*!< out MBR */
{
ulint rec_f_len;
@@ -1657,8 +1655,8 @@ rtr_cur_search_with_match(
const page_t* page;
const rec_t* rec;
const rec_t* last_rec;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
mem_heap_t* heap = NULL;
int cmp = 1;
double least_inc = DBL_MAX;
@@ -1941,8 +1939,8 @@ rtr_cur_search_with_match(
test_rec = match_rec->matched_recs->back();
#ifdef UNIV_DEBUG
- ulint offsets_2[REC_OFFS_NORMAL_SIZE];
- ulint* offsets2 = offsets_2;
+ rec_offs offsets_2[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets2 = offsets_2;
rec_offs_init(offsets_2);
ut_ad(found);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index caa0b1e861c..e36dcbad8ff 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1,10 +1,10 @@
/*****************************************************************************
-Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2020, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -103,6 +103,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "srv0mon.h"
#include "srv0srv.h"
#include "srv0start.h"
+#include "rem0rec.h"
#ifdef UNIV_DEBUG
#include "trx0purge.h"
#endif /* UNIV_DEBUG */
@@ -585,9 +586,7 @@ static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(file_format_max_mutex),
PSI_KEY(fil_system_mutex),
PSI_KEY(flush_list_mutex),
- PSI_KEY(fts_bg_threads_mutex),
PSI_KEY(fts_delete_mutex),
- PSI_KEY(fts_optimize_mutex),
PSI_KEY(fts_doc_id_mutex),
PSI_KEY(log_flush_order_mutex),
PSI_KEY(hash_table_mutex),
@@ -626,7 +625,6 @@ static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(rtr_active_mutex),
PSI_KEY(rtr_match_mutex),
PSI_KEY(rtr_path_mutex),
- PSI_KEY(rtr_ssn_mutex),
PSI_KEY(trx_sys_mutex),
PSI_KEY(zip_pad_mutex)
};
@@ -1408,18 +1406,6 @@ innobase_commit_by_xid(
handlerton* hton, /*!< in: InnoDB handlerton */
XID* xid); /*!< in: X/Open XA transaction
identification */
-/*******************************************************************//**
-This function is used to rollback one X/Open XA distributed transaction
-which is in the prepared state
-@return 0 or error number */
-static
-int
-innobase_rollback_by_xid(
-/*=====================*/
- handlerton* hton, /*!< in: InnoDB handlerton */
- XID* xid); /*!< in: X/Open XA transaction
- identification */
-
/** Remove all tables in the named database inside InnoDB.
@param[in] hton handlerton from InnoDB
@param[in] path Database path; Inside InnoDB the name of the last
@@ -1727,20 +1713,14 @@ thd_trx_is_auto_commit(
/** Enter InnoDB engine after checking the max number of user threads
allowed, else the thread is put into sleep.
@param[in,out] prebuilt row prebuilt handler */
-static inline
-void
-innobase_srv_conc_enter_innodb(
- row_prebuilt_t* prebuilt)
+static inline void innobase_srv_conc_enter_innodb(row_prebuilt_t *prebuilt)
{
+ trx_t* trx = prebuilt->trx;
+
#ifdef WITH_WSREP
- if (wsrep_on(prebuilt->trx->mysql_thd) &&
- wsrep_thd_is_BF(prebuilt->trx->mysql_thd, FALSE)) {
- return;
- }
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
- trx_t* trx = prebuilt->trx;
-
if (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1767,22 +1747,16 @@ innobase_srv_conc_enter_innodb(
/** Note that the thread wants to leave InnoDB only if it doesn't have
any spare tickets.
@param[in,out] m_prebuilt row prebuilt handler */
-static inline
-void
-innobase_srv_conc_exit_innodb(
- row_prebuilt_t* prebuilt)
+static inline void innobase_srv_conc_exit_innodb(row_prebuilt_t *prebuilt)
{
ut_ad(!sync_check_iterate(sync_check()));
+ trx_t* trx = prebuilt->trx;
+
#ifdef WITH_WSREP
- if (wsrep_on(prebuilt->trx->mysql_thd) &&
- wsrep_thd_is_BF(prebuilt->trx->mysql_thd, FALSE)) {
- return;
- }
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
- trx_t* trx = prebuilt->trx;
-
/* This is to avoid making an unnecessary function call. */
if (trx->declared_to_be_inside_innodb
&& trx->n_tickets_to_enter_innodb == 0) {
@@ -2324,17 +2298,6 @@ innobase_casedn_str(
my_casedn_str(system_charset_info, a);
}
-/**********************************************************************//**
-Determines the connection character set.
-@return connection character set */
-CHARSET_INFO*
-innobase_get_charset(
-/*=================*/
- THD* mysql_thd) /*!< in: MySQL thread handle */
-{
- return(thd_charset(mysql_thd));
-}
-
/** Determines the current SQL statement.
Thread unsafe, can only be called from the thread owning the THD.
@param[in] thd MySQL thread handle
@@ -2354,22 +2317,6 @@ innobase_get_stmt_unsafe(
return NULL;
}
-/** Determines the current SQL statement.
-Thread safe, can be called from any thread as the string is copied
-into the provided buffer.
-@param[in] thd MySQL thread handle
-@param[out] buf Buffer containing SQL statement
-@param[in] buflen Length of provided buffer
-@return Length of the SQL statement */
-size_t
-innobase_get_stmt_safe(
- THD* thd,
- char* buf,
- size_t buflen)
-{
- return thd_query_safe(thd, buf, buflen);
-}
-
/**********************************************************************//**
Get the current setting of the tdc_size global parameter. We do
a dirty read because for one there is no synchronization object and
@@ -2770,11 +2717,20 @@ innobase_trx_init(
DBUG_ENTER("innobase_trx_init");
DBUG_ASSERT(thd == trx->mysql_thd);
+ /* Ensure that thd_lock_wait_timeout(), which may be called
+ while holding lock_sys.mutex, by lock_rec_enqueue_waiting(),
+ will not end up acquiring LOCK_global_system_variables in
+ intern_sys_var_ptr(). */
+ THDVAR(thd, lock_wait_timeout);
+
trx->check_foreigns = !thd_test_options(
thd, OPTION_NO_FOREIGN_KEY_CHECKS);
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
+#ifdef WITH_WSREP
+ trx->wsrep = wsrep_on(thd);
+#endif
DBUG_VOID_RETURN;
}
@@ -2850,18 +2806,6 @@ trx_is_registered_for_2pc(
}
/*********************************************************************//**
-Note that innobase_commit_ordered() was run. */
-static inline
-void
-trx_set_active_commit_ordered(
-/*==========================*/
- trx_t* trx) /* in: transaction */
-{
- ut_a(trx_is_registered_for_2pc(trx));
- trx->active_commit_ordered = 1;
-}
-
-/*********************************************************************//**
Note that a transaction has been registered with MySQL 2PC coordinator. */
static inline
void
@@ -2870,7 +2814,7 @@ trx_register_for_2pc(
trx_t* trx) /* in: transaction */
{
trx->is_registered = 1;
- ut_ad(trx->active_commit_ordered == 0);
+ ut_ad(!trx->active_commit_ordered);
}
/*********************************************************************//**
@@ -2881,19 +2825,8 @@ trx_deregister_from_2pc(
/*====================*/
trx_t* trx) /* in: transaction */
{
- trx->is_registered = 0;
- trx->active_commit_ordered = 0;
-}
-
-/*********************************************************************//**
-Check whether a transaction has active_commit_ordered set */
-static inline
-bool
-trx_is_active_commit_ordered(
-/*=========================*/
- const trx_t* trx) /* in: transaction */
-{
- return(trx->active_commit_ordered == 1);
+ trx->is_registered= false;
+ trx->active_commit_ordered= false;
}
/*********************************************************************//**
@@ -3504,17 +3437,6 @@ trx_is_interrupted(
return(trx && trx->mysql_thd && thd_kill_level(trx->mysql_thd));
}
-/**********************************************************************//**
-Determines if the currently running transaction is in strict mode.
-@return TRUE if strict */
-ibool
-trx_is_strict(
-/*==========*/
- trx_t* trx) /*!< in: transaction */
-{
- return(trx && trx->mysql_thd && THDVAR(trx->mysql_thd, strict_mode));
-}
-
/**************************************************************//**
Resets some fields of a m_prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
@@ -3528,7 +3450,7 @@ ha_innobase::reset_template(void)
/* Force table to be freed in close_thread_table(). */
DBUG_EXECUTE_IF("free_table_in_fts_query",
if (m_prebuilt->in_fts_query) {
- table->m_needs_reopen = true;
+ table->mark_table_for_reopen();
}
);
@@ -3602,12 +3524,8 @@ ha_innobase::init_table_handle_for_HANDLER(void)
reset_template();
}
-/*********************************************************************//**
-Free tablespace resources allocated. */
-static
-void
-innobase_space_shutdown()
-/*=====================*/
+/** Free tablespace resources allocated. */
+void innobase_space_shutdown()
{
DBUG_ENTER("innobase_space_shutdown");
@@ -3688,8 +3606,7 @@ static const char* deprecated_mtflush_threads
static my_bool innodb_instrument_semaphores;
-/** Update log_checksum_algorithm_ptr with a pointer to the function
-corresponding to whether checksums are enabled.
+/** If applicable, emit a message that log checksums cannot be disabled.
@param[in,out] thd client session, or NULL if at startup
@param[in] check whether redo log block checksums are enabled
@return whether redo log block checksums are enabled */
@@ -3697,34 +3614,21 @@ static inline
bool
innodb_log_checksums_func_update(THD* thd, bool check)
{
- static const char msg[] = "innodb_encrypt_log implies"
- " innodb_log_checksums";
+ static const char msg[] = "innodb_log_checksums is deprecated"
+ " and has no effect outside recovery";
ut_ad(!thd == !srv_was_started);
if (!check) {
- check = srv_encrypt_log;
- if (!check) {
- } else if (thd) {
+ if (thd) {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
HA_ERR_UNSUPPORTED, msg);
+ check = true;
} else {
sql_print_warning(msg);
}
}
- if (thd) {
- log_mutex_enter();
- log_checksum_algorithm_ptr = check
- ? log_block_calc_checksum_crc32
- : log_block_calc_checksum_none;
- log_mutex_exit();
- } else {
- log_checksum_algorithm_ptr = check
- ? log_block_calc_checksum_crc32
- : log_block_calc_checksum_none;
- }
-
return(check);
}
@@ -3845,21 +3749,30 @@ innobase_init(
pages, even for larger pages */
if (UNIV_PAGE_SIZE > UNIV_PAGE_SIZE_DEF
&& innobase_buffer_pool_size < (24 * 1024 * 1024)) {
- ib::info() << "innodb_page_size="
+ ib::error() << "innodb_page_size="
<< UNIV_PAGE_SIZE << " requires "
<< "innodb_buffer_pool_size > 24M current "
<< innobase_buffer_pool_size;
goto error;
}
+ if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS) {
+ ib::warn() << "The parameter innodb_lock_schedule_algorithm"
+ " is deprecated, and the setting"
+ " innodb_lock_schedule_algorithm=vats"
+ " may cause corruption. The parameter may be removed"
+ " in future releases.";
+
#ifdef WITH_WSREP
- /* Currently, Galera does not support VATS lock schedule algorithm. */
- if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
- && global_system_variables.wsrep_on) {
- ib::info() << "For Galera, using innodb_lock_schedule_algorithm=fcfs";
- innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
+ /* Currently, Galera does not support VATS lock schedule algorithm. */
+ if (global_system_variables.wsrep_on) {
+ ib::info() << "For Galera, using innodb_lock_schedule_algorithm=fcfs";
+ innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
+ }
+#endif /* WITH_WSREP */
}
+#ifdef WITH_WSREP
/* Print deprecation info if xtrabackup is used for SST method */
if (global_system_variables.wsrep_on
&& wsrep_sst_method
@@ -4502,29 +4415,26 @@ innobase_commit_low(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
- THD* thd = (THD*)trx->mysql_thd;
const char* tmp = 0;
- if (thd && wsrep_on(thd)) {
-#ifdef WSREP_PROC_INFO
- char info[64];
- info[sizeof(info) - 1] = '\0';
- snprintf(info, sizeof(info) - 1,
- "innobase_commit_low():trx_commit_for_mysql(%lld)",
- (long long) wsrep_thd_trx_seqno(thd));
- tmp = thd_proc_info(thd, info);
-
-#else
+ const bool is_wsrep = trx->is_wsrep();
+ THD* thd = trx->mysql_thd;
+ if (is_wsrep) {
tmp = thd_proc_info(thd, "innobase_commit_low()");
-#endif /* WSREP_PROC_INFO */
}
#endif /* WITH_WSREP */
if (trx_is_started(trx)) {
-
trx_commit_for_mysql(trx);
+ } else {
+ trx->will_lock = 0;
+#ifdef WITH_WSREP
+ trx->wsrep = false;
+#endif /* WITH_WSREP */
}
- trx->will_lock = 0;
+
#ifdef WITH_WSREP
- if (thd && wsrep_on(thd)) { thd_proc_info(thd, tmp); }
+ if (is_wsrep) {
+ thd_proc_info(thd, tmp);
+ }
#endif /* WITH_WSREP */
}
@@ -4698,8 +4608,7 @@ innobase_commit_ordered(
(!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
innobase_commit_ordered_2(trx, thd);
-
- trx_set_active_commit_ordered(trx);
+ trx->active_commit_ordered = true;
DBUG_VOID_RETURN;
}
@@ -4752,7 +4661,7 @@ innobase_commit(
DBUG_SUICIDE(););
/* Run the fast part of commit if we did not already. */
- if (!trx_is_active_commit_ordered(trx)) {
+ if (!trx->active_commit_ordered) {
innobase_commit_ordered_2(trx, thd);
}
@@ -4874,6 +4783,9 @@ innobase_rollback_trx(
if (!trx->has_logged()) {
trx->will_lock = 0;
+#ifdef WITH_WSREP
+ trx->wsrep = false;
+#endif
DBUG_RETURN(0);
}
@@ -5256,13 +5168,43 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels)
}
#endif /* WITH_WSREP */
- if (trx_t* trx = thd_to_trx(thd)) {
- ut_ad(trx->mysql_thd == thd);
- /* Cancel a pending lock request if there are any */
- lock_trx_handle_wait(trx);
- }
+ if (trx_t* trx= thd_to_trx(thd))
+ {
+ lock_mutex_enter();
+ trx_sys_mutex_enter();
+ trx_mutex_enter(trx);
+ /* It is possible that innobase_close_connection() is concurrently
+ being executed on our victim. In that case, trx->mysql_thd would
+ be reset before invoking trx_t::free(). Even if the trx object is later
+ reused for another client connection or a background transaction,
+ its trx->mysql_thd will differ from our thd.
+
+ If trx never performed any changes, nothing is really protecting
+ the trx_t::free() call or the changes of trx_t::state when the
+ transaction is being rolled back and trx_commit_low() is being
+ executed.
+
+ The function trx_allocate_for_mysql() acquires
+ trx_sys_t::mutex, but trx_allocate_for_background() will not.
+ Luckily, background transactions cannot be read-only, because
+ for read-only transactions, trx_start_low() will avoid acquiring
+ any of the trx_sys_t::mutex, lock_sys_t::mutex, trx_t::mutex before
+ assigning trx_t::state.
+
+ At this point, trx may have been reallocated for another client
+ connection, or for a background operation. In that case, either
+ trx_t::state or trx_t::mysql_thd should not match our expectations. */
+ bool cancel= trx->mysql_thd == thd && trx->state == TRX_STATE_ACTIVE &&
+ !trx->lock.was_chosen_as_deadlock_victim;
+ trx_sys_mutex_exit();
+ if (!cancel);
+ else if (lock_t *lock= trx->lock.wait_lock)
+ lock_cancel_waiting_and_release(lock);
+ lock_mutex_exit();
+ trx_mutex_exit(trx);
+ }
- DBUG_VOID_RETURN;
+ DBUG_VOID_RETURN;
}
@@ -5846,14 +5788,13 @@ innobase_vcol_build_templ(
mysql_row_templ_t* templ,
ulint col_no)
{
- if (dict_col_is_virtual(col)) {
- templ->is_virtual = true;
- templ->col_no = col_no;
+ templ->col_no = col_no;
+ templ->is_virtual = col->is_virtual();
+
+ if (templ->is_virtual) {
templ->clust_rec_field_no = ULINT_UNDEFINED;
templ->rec_field_no = col->ind;
} else {
- templ->is_virtual = false;
- templ->col_no = col_no;
templ->clust_rec_field_no = dict_col_get_clust_pos(
col, clust_index);
ut_a(templ->clust_rec_field_no != ULINT_UNDEFINED);
@@ -7524,7 +7465,11 @@ build_template_field(
ut_ad(clust_index->table == index->table);
templ = prebuilt->mysql_template + prebuilt->n_template++;
- UNIV_MEM_INVALID(templ, sizeof *templ);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(templ, sizeof *templ);
+#endif /* HAVE_valgrind_or_MSAN */
+ templ->rec_field_is_prefix = FALSE;
+ templ->rec_prefix_field_no = ULINT_UNDEFINED;
templ->is_virtual = !field->stored_in_db();
if (!templ->is_virtual) {
@@ -7586,8 +7531,6 @@ build_template_field(
<< " query "
<< innobase_get_stmt_unsafe(current_thd, &size);
}
- templ->rec_field_is_prefix = FALSE;
- templ->rec_prefix_field_no = ULINT_UNDEFINED;
if (dict_index_is_clust(index)) {
templ->rec_field_no = templ->clust_rec_field_no;
@@ -7605,7 +7548,6 @@ build_template_field(
DBUG_ASSERT(!ha_innobase::omits_virtual_cols(*table->s));
col = &dict_table_get_nth_v_col(index->table, v_no)->m_col;
templ->clust_rec_field_no = v_no;
- templ->rec_prefix_field_no = ULINT_UNDEFINED;
if (dict_index_is_clust(index)) {
templ->rec_field_no = templ->clust_rec_field_no;
@@ -8140,7 +8082,7 @@ ha_innobase::write_row(
{
dberr_t error;
#ifdef WITH_WSREP
- ibool auto_inc_inserted= FALSE; /* if NULL was inserted */
+ bool wsrep_auto_inc_inserted= false;
#endif
int error_result = 0;
bool auto_inc_used = false;
@@ -8153,8 +8095,7 @@ ha_innobase::write_row(
if (high_level_read_only) {
ib_senderrf(ha_thd(), IB_LOG_LEVEL_WARN, ER_READ_ONLY_MODE);
DBUG_RETURN(HA_ERR_TABLE_READONLY);
- } else if (m_prebuilt->trx != trx) {
-
+ } else if (UNIV_UNLIKELY(m_prebuilt->trx != trx)) {
ib::error() << "The transaction object for the table handle is"
" at " << static_cast<const void*>(m_prebuilt->trx)
<< ", but for the current thread it is at "
@@ -8171,7 +8112,7 @@ ha_innobase::write_row(
}
#ifdef WITH_WSREP
- if (wsrep_is_load_multi_commit(m_user_thd))
+ if (trx->is_wsrep() && wsrep_is_load_multi_commit(m_user_thd))
{
/* Note that this transaction is still active. */
trx_register_for_2pc(m_prebuilt->trx);
@@ -8188,7 +8129,9 @@ ha_innobase::write_row(
m_prebuilt->autoinc_error = DB_SUCCESS;
#ifdef WITH_WSREP
- auto_inc_inserted= (table->next_number_field->val_int() == 0);
+ wsrep_auto_inc_inserted = trx->is_wsrep()
+ && wsrep_drupal_282555_workaround
+ && table->next_number_field->val_int() == 0;
#endif
if ((error_result = update_auto_increment())) {
@@ -8282,18 +8225,14 @@ ha_innobase::write_row(
m_prebuilt->autoinc_offset,
m_prebuilt->autoinc_increment);
- if (wsrep_on(m_user_thd) &&
- auto_inc_inserted &&
- wsrep_drupal_282555_workaround &&
+ if (wsrep_auto_inc_inserted &&
wsrep_thd_retry_counter(m_user_thd) == 0 &&
!thd_test_options(m_user_thd,
OPTION_NOT_AUTOCOMMIT |
OPTION_BEGIN)) {
WSREP_DEBUG(
"retrying insert: %s",
- (*wsrep_thd_query(m_user_thd)) ?
- wsrep_thd_query(m_user_thd) :
- (char *)"void");
+ wsrep_thd_query(m_user_thd));
error= DB_SUCCESS;
wsrep_thd_set_conflict_state(
m_user_thd, MUST_ABORT);
@@ -8333,7 +8272,7 @@ set_max_autoinc:
m_prebuilt autoinc values don't get
properly assigned. Fetch values from
server side. */
- if (wsrep_on(m_user_thd) &&
+ if (trx->is_wsrep() &&
wsrep_thd_exec_mode(m_user_thd) == REPL_RECV)
{
wsrep_thd_auto_increment_variables(
@@ -8382,8 +8321,7 @@ report_error:
error, m_prebuilt->table->flags, m_user_thd);
#ifdef WITH_WSREP
- if (!error_result
- && wsrep_on(m_user_thd)
+ if (!error_result && trx->is_wsrep()
&& wsrep_thd_exec_mode(m_user_thd) == LOCAL_STATE
&& !wsrep_consistency_check(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd)) {
@@ -8391,10 +8329,9 @@ report_error:
NULL)) {
DBUG_PRINT("wsrep", ("row key failed"));
error_result = HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ goto func_exit;
}
}
-wsrep_error:
#endif /* WITH_WSREP */
if (error_result == HA_FTS_INVALID_DOCID) {
@@ -8649,7 +8586,9 @@ calc_row_difference(
/* The field has changed */
ufield = uvect->fields + n_changed;
- UNIV_MEM_INVALID(ufield, sizeof *ufield);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(ufield, sizeof *ufield);
+#endif /* HAVE_valgrind_or_MSAN */
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */
@@ -9027,7 +8966,7 @@ ha_innobase::update_row(
m_prebuilt autoinc values don't get
properly assigned. Fetch values from
server side. */
- if (wsrep_on(m_user_thd) &&
+ if (trx->is_wsrep() &&
wsrep_thd_exec_mode(m_user_thd) == REPL_RECV)
{
wsrep_thd_auto_increment_variables(
@@ -9078,9 +9017,8 @@ func_exit:
innobase_active_small();
#ifdef WITH_WSREP
- if (error == DB_SUCCESS &&
+ if (error == DB_SUCCESS && trx->is_wsrep() &&
wsrep_thd_exec_mode(m_user_thd) == LOCAL_STATE &&
- wsrep_on(m_user_thd) &&
!wsrep_thd_ignore_table(m_user_thd)) {
DBUG_PRINT("wsrep", ("update row key"));
@@ -9088,14 +9026,11 @@ func_exit:
new_row)) {
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED");
DBUG_PRINT("wsrep", ("row key failed"));
- err = HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
-wsrep_error:
#endif /* WITH_WSREP */
-
DBUG_RETURN(err);
}
@@ -9142,18 +9077,15 @@ ha_innobase::delete_row(
innobase_active_small();
#ifdef WITH_WSREP
- if (error == DB_SUCCESS
+ if (error == DB_SUCCESS && trx->is_wsrep()
&& wsrep_thd_exec_mode(m_user_thd) == LOCAL_STATE
- && wsrep_on(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd)) {
if (wsrep_append_keys(m_user_thd, WSREP_KEY_EXCLUSIVE, record,
NULL)) {
DBUG_PRINT("wsrep", ("delete fail"));
- error = (dberr_t) HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
-wsrep_error:
#endif /* WITH_WSREP */
DBUG_RETURN(convert_error_code_to_mysql(
error, m_prebuilt->table->flags, m_user_thd));
@@ -10025,7 +9957,7 @@ ha_innobase::ft_init_ext(
const CHARSET_INFO* char_set = key->charset();
const char* query = key->ptr();
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
{
ib::info out;
out << "keynr=" << keynr << ", '";
@@ -10347,30 +10279,27 @@ wsrep_append_foreign_key(
wsrep_key_type key_type) /*!< in: access type of this key
(shared, exclusive, semi...) */
{
- ut_a(trx);
- THD* thd = (THD*)trx->mysql_thd;
- ulint rcode = DB_SUCCESS;
- char cache_key[513] = {'\0'};
- int cache_key_len=0;
- bool const copy = true;
+ THD* thd = trx->mysql_thd;
- if (!wsrep_on(trx->mysql_thd) ||
- wsrep_thd_exec_mode(thd) != LOCAL_STATE) {
+ if (!trx->is_wsrep() || wsrep_thd_exec_mode(thd) != LOCAL_STATE) {
return DB_SUCCESS;
}
- if (!thd || !foreign ||
+ if (!foreign ||
(!foreign->referenced_table && !foreign->foreign_table)) {
WSREP_INFO("FK: %s missing in: %s",
- (!thd) ? "thread" :
- ((!foreign) ? "constraint" :
- ((!foreign->referenced_table) ?
+ (!foreign ? "constraint" :
+ (!foreign->referenced_table ?
"referenced table" : "foreign table")),
- (thd && wsrep_thd_query(thd)) ?
- wsrep_thd_query(thd) : "void");
+ wsrep_thd_query(thd));
return DB_ERROR;
}
+ ulint rcode = DB_SUCCESS;
+ char cache_key[513] = {'\0'};
+ int cache_key_len=0;
+ bool const copy = true;
+
if ( !((referenced) ?
foreign->referenced_table : foreign->foreign_table)) {
WSREP_DEBUG("pulling %s table into cache",
@@ -11923,10 +11852,17 @@ innobase_fts_load_stopword(
trx_t* trx, /*!< in: transaction */
THD* thd) /*!< in: current thread */
{
- return(fts_load_stopword(table, trx,
- innobase_server_stopword_table,
- THDVAR(thd, ft_user_stopword_table),
- THDVAR(thd, ft_enable_stopword), FALSE));
+ const char *stopword_table= THDVAR(thd, ft_user_stopword_table);
+ if (!stopword_table)
+ {
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ if (innobase_server_stopword_table)
+ stopword_table= thd_strdup(thd, innobase_server_stopword_table);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ }
+
+ return fts_load_stopword(table, trx, stopword_table,
+ THDVAR(thd, ft_enable_stopword), false);
}
/** Parse the table name into normal name and remote path if needed.
@@ -12742,7 +12678,10 @@ int create_table_info_t::create_table(bool create_fk)
DICT_ERR_IGNORE_NONE);
ut_ad(innobase_table);
- const bool is_acceptable = row_size_is_acceptable(*innobase_table);
+ /* In TRUNCATE TABLE, we will merely warn about the maximum
+ row size being too large. */
+ const bool is_acceptable = row_size_is_acceptable(*innobase_table,
+ create_fk);
dict_table_close(innobase_table, true, false);
@@ -12755,18 +12694,12 @@ int create_table_info_t::create_table(bool create_fk)
}
bool create_table_info_t::row_size_is_acceptable(
- const dict_table_t &table) const
+ const dict_table_t &table, bool strict) const
{
for (dict_index_t *index= dict_table_get_first_index(&table); index;
index= dict_table_get_next_index(index))
- {
-
- if (!row_size_is_acceptable(*index))
- {
+ if (!row_size_is_acceptable(*index, strict))
return false;
- }
- }
-
return true;
}
@@ -12944,7 +12877,7 @@ static void ib_warn_row_too_big(THD *thd, const dict_table_t *table)
}
bool create_table_info_t::row_size_is_acceptable(
- const dict_index_t &index) const
+ const dict_index_t &index, bool strict) const
{
if ((index.type & DICT_FTS) || index.table->is_system_db)
{
@@ -12953,7 +12886,7 @@ bool create_table_info_t::row_size_is_acceptable(
return true;
}
- const bool strict= THDVAR(m_thd, strict_mode);
+ const bool innodb_strict_mode= THDVAR(m_thd, strict_mode);
dict_index_t::record_size_info_t info= index.record_size_info();
if (info.row_is_too_big())
@@ -12964,18 +12897,19 @@ bool create_table_info_t::row_size_is_acceptable(
const size_t idx= info.get_first_overrun_field_index();
const dict_field_t *field= dict_index_get_nth_field(&index, idx);
- ib::error_or_warn(strict)
- << "Cannot add field " << field->name << " in table "
- << index.table->name << " because after adding it, the row size is "
- << info.get_overrun_size()
- << " which is greater than maximum allowed size ("
- << info.max_leaf_size << " bytes) for a record on index leaf page.";
-
- if (strict)
+ if (innodb_strict_mode || global_system_variables.log_warnings > 2)
{
- return false;
+ ib::error_or_warn(strict && innodb_strict_mode)
+ << "Cannot add field " << field->name << " in table "
+ << index.table->name << " because after adding it, the row size is "
+ << info.get_overrun_size()
+ << " which is greater than maximum allowed size ("
+ << info.max_leaf_size << " bytes) for a record on index leaf page.";
}
+ if (strict && innodb_strict_mode)
+ return false;
+
ib_warn_row_too_big(m_thd, index.table);
}
@@ -14784,25 +14718,14 @@ ha_innobase::analyze(
/*****************************************************************//**
Defragment table.
@return error number */
-UNIV_INTERN
-int
-ha_innobase::defragment_table(
-/*==========================*/
- const char* name, /*!< in: table name */
- const char* index_name, /*!< in: index name */
- bool async) /*!< in: whether to wait until finish */
+inline int ha_innobase::defragment_table(const char *name)
{
char norm_name[FN_REFLEN];
dict_table_t* table = NULL;
dict_index_t* index = NULL;
- ibool one_index = (index_name != 0);
int ret = 0;
dberr_t err = DB_SUCCESS;
- if (!srv_defragment) {
- return ER_FEATURE_DISABLED;
- }
-
normalize_table_name(norm_name, name);
table = dict_table_open_on_name(norm_name, FALSE,
@@ -14830,10 +14753,6 @@ ha_innobase::defragment_table(
continue;
}
- if (one_index && strcasecmp(index_name, index->name) != 0) {
- continue;
- }
-
if (btr_defragment_find_index(index)) {
// We borrow this error code. When the same index is
// already in the defragmentation queue, issue another
@@ -14849,7 +14768,7 @@ ha_innobase::defragment_table(
break;
}
- os_event_t event = btr_defragment_add_index(index, async, &err);
+ os_event_t event = btr_defragment_add_index(index, &err);
if (err != DB_SUCCESS) {
push_warning_printf(
@@ -14865,7 +14784,7 @@ ha_innobase::defragment_table(
break;
}
- if (!async && event) {
+ if (event) {
while(os_event_wait_time(event, 1000000)) {
if (thd_killed(current_thd)) {
btr_defragment_remove_index(index);
@@ -14879,19 +14798,9 @@ ha_innobase::defragment_table(
if (ret) {
break;
}
-
- if (one_index) {
- one_index = FALSE;
- break;
- }
}
dict_table_close(table, FALSE, FALSE);
-
- if (ret == 0 && one_index) {
- ret = ER_NO_SUCH_INDEX;
- }
-
return ret;
}
@@ -14916,11 +14825,8 @@ ha_innobase::optimize(
calls to OPTIMIZE, which is undesirable. */
bool try_alter = true;
- /* TODO: Defragment is disabled for now */
- if (srv_defragment) {
- int err;
-
- err = defragment_table(m_prebuilt->table->name.m_name, NULL, false);
+ if (!m_prebuilt->table->is_temporary() && srv_defragment) {
+ int err = defragment_table(m_prebuilt->table->name.m_name);
if (err == 0) {
try_alter = false;
@@ -16005,9 +15911,7 @@ ha_innobase::external_lock(
DBUG_PRINT("enter",("lock_type: %d", lock_type));
update_thd(thd);
-
- trx_t* trx = m_prebuilt->trx;
-
+ trx_t* trx = m_prebuilt->trx;
ut_ad(m_prebuilt->table);
/* Statement based binlogging does not work in isolation level
@@ -16022,26 +15926,21 @@ ha_innobase::external_lock(
&& thd_binlog_format(thd) == BINLOG_FORMAT_STMT
&& thd_binlog_filter_ok(thd)
&& thd_sqlcom_can_generate_row_events(thd)) {
-
- bool skip = false;
-
+ bool skip = false;
+#ifdef WITH_WSREP
+ skip = trx->is_wsrep()
+ && wsrep_thd_exec_mode(thd) != LOCAL_STATE;
+#endif /* WITH_WSREP */
/* used by test case */
DBUG_EXECUTE_IF("no_innodb_binlog_errors", skip = true;);
if (!skip) {
-#ifdef WITH_WSREP
- if (!wsrep_on(thd) || wsrep_thd_exec_mode(thd) == LOCAL_STATE)
- {
-#endif /* WITH_WSREP */
my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
" InnoDB is limited to row-logging when"
" transaction isolation level is"
" READ COMMITTED or READ UNCOMMITTED.");
DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE);
-#ifdef WITH_WSREP
- }
-#endif /* WITH_WSREP */
}
}
@@ -16433,8 +16332,7 @@ struct ShowStatus {
/** Collect the latch metrics. Ignore entries where the
spins and waits are zero.
@param[in] count The latch metrics */
- void operator()(Count* count)
- UNIV_NOTHROW
+ void operator()(Count* count) const UNIV_NOTHROW
{
if (count->m_spins > 0 || count->m_waits > 0) {
@@ -16462,13 +16360,8 @@ struct ShowStatus {
bool operator()(latch_meta_t& latch_meta)
UNIV_NOTHROW
{
- latch_meta_t::CounterType* counter;
-
- counter = latch_meta.get_counter();
-
- GetCount get_count(latch_meta.get_name(), &m_values);
-
- counter->iterate(get_count);
+ latch_meta.get_counter()->iterate(
+ GetCount(latch_meta.get_name(), &m_values));
return(true);
}
@@ -17509,17 +17402,14 @@ innobase_commit_by_xid(
}
}
-/*******************************************************************//**
-This function is used to rollback one X/Open XA distributed transaction
+/** This function is used to rollback one X/Open XA distributed transaction
which is in the prepared state
+
+@param[in] hton InnoDB handlerton
+@param[in] xid X/Open XA transaction identification
+
@return 0 or error number */
-static
-int
-innobase_rollback_by_xid(
-/*=====================*/
- handlerton* hton, /*!< in: InnoDB handlerton */
- XID* xid) /*!< in: X/Open XA transaction
- identification */
+int innobase_rollback_by_xid(handlerton* hton, XID* xid)
{
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -18059,7 +17949,6 @@ innodb_stopword_table_validate(
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
trx_t* trx;
- int ret = 1;
ut_a(save != NULL);
ut_a(value != NULL);
@@ -18072,14 +17961,22 @@ innodb_stopword_table_validate(
/* Validate the stopword table's (if supplied) existence and
of the right format */
- if (!stopword_table_name
- || fts_valid_stopword_table(stopword_table_name)) {
- *static_cast<const char**>(save) = stopword_table_name;
- ret = 0;
- }
+ int ret = stopword_table_name && !fts_valid_stopword_table(
+ stopword_table_name);
row_mysql_unlock_data_dictionary(trx);
+ if (!ret) {
+ if (stopword_table_name == buff) {
+ ut_ad(static_cast<size_t>(len) < sizeof buff);
+ stopword_table_name = thd_strmake(thd,
+ stopword_table_name,
+ len);
+ }
+
+ *static_cast<const char**>(save) = stopword_table_name;
+ }
+
return(ret);
}
@@ -18113,9 +18010,10 @@ innodb_buffer_pool_size_update(
static char* innodb_ft_aux_table;
/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table.
+@param[in,out] thd connection
@param[out] save new value of innodb_ft_aux_table
@param[in] value user-specified value */
-static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
+static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*,
void* save, st_mysql_value* value)
{
char buf[STRING_BUFFER_USUAL_SIZE];
@@ -18129,6 +18027,15 @@ static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
dict_table_close(table, FALSE, FALSE);
if (id) {
innodb_ft_aux_table_id = id;
+ if (table_name == buf) {
+ ut_ad(static_cast<size_t>(len)
+ < sizeof buf);
+ table_name = thd_strmake(thd,
+ table_name,
+ len);
+ }
+
+
*static_cast<const char**>(save) = table_name;
return 0;
}
@@ -18162,7 +18069,7 @@ innodb_adaptive_hash_index_update(
if (*(my_bool*) save) {
btr_search_enable();
} else {
- btr_search_disable(true);
+ btr_search_disable();
}
mysql_mutex_lock(&LOCK_global_system_variables);
}
@@ -18855,51 +18762,43 @@ exit:
return;
}
-#ifdef _WIN32
-/*************************************************************//**
-Validate if passed-in "value" is a valid value for
-innodb_buffer_pool_filename. On Windows, file names with colon (:)
-are not allowed.
-
-@return 0 for valid name */
-static
-int
-innodb_srv_buf_dump_filename_validate(
-/*==================================*/
- THD* thd, /*!< in: thread handle */
- struct st_mysql_sys_var* var, /*!< in: pointer to system
- variable */
- void* save, /*!< out: immediate result
- for update function */
- struct st_mysql_value* value) /*!< in: incoming string */
+/** Validate SET GLOBAL innodb_buffer_pool_filename.
+On Windows, file names with colon (:) are not allowed.
+@param thd connection
+@param save &srv_buf_dump_filename
+@param value new value to be validated
+@return 0 for valid name */
+static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*,
+ void *save,
+ st_mysql_value *value)
{
- char buff[OS_FILE_MAX_PATH];
- int len = sizeof(buff);
-
- ut_a(save != NULL);
- ut_a(value != NULL);
-
- const char* buf_name = value->val_str(value, buff, &len);
+ char buff[OS_FILE_MAX_PATH];
+ int len= sizeof buff;
- if (buf_name != NULL) {
- if (is_filename_allowed(buf_name, len, FALSE)){
- *static_cast<const char**>(save) = buf_name;
- return(0);
- } else {
- push_warning_printf(thd,
- Sql_condition::WARN_LEVEL_WARN,
- ER_WRONG_ARGUMENTS,
- "InnoDB: innodb_buffer_pool_filename"
- " cannot have colon (:) in the file name.");
+ if (const char *buf_name= value->val_str(value, buff, &len))
+ {
+#ifdef _WIN32
+ if (!is_filename_allowed(buf_name, len, FALSE))
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "InnoDB: innodb_buffer_pool_filename "
+ "cannot have colon (:) in the file name.");
+ return 1;
+ }
+#endif /* _WIN32 */
+ if (buf_name == buff)
+ {
+ ut_ad(static_cast<size_t>(len) < sizeof buff);
+ buf_name= thd_strmake(thd, buf_name, len);
+ }
- }
- }
+ *static_cast<const char**>(save)= buf_name;
+ return 0;
+ }
- return(1);
+ return 1;
}
-#else /* _WIN32 */
-# define innodb_srv_buf_dump_filename_validate NULL
-#endif /* _WIN32 */
#ifdef UNIV_DEBUG
static char* srv_buffer_pool_evict;
@@ -18908,10 +18807,7 @@ static char* srv_buffer_pool_evict;
Evict all uncompressed pages of compressed tables from the buffer pool.
Keep the compressed pages in the buffer pool.
@return whether all uncompressed pages were evicted */
-static MY_ATTRIBUTE((warn_unused_result))
-bool
-innodb_buffer_pool_evict_uncompressed(void)
-/*=======================================*/
+static bool innodb_buffer_pool_evict_uncompressed()
{
bool all_evicted = true;
@@ -18932,9 +18828,13 @@ innodb_buffer_pool_evict_uncompressed(void)
if (!buf_LRU_free_page(&block->page, false)) {
all_evicted = false;
+ block = prev_block;
+ } else {
+ /* Because buf_LRU_free_page() may release
+ and reacquire buf_pool_t::mutex, prev_block
+ may be invalid. */
+ block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
}
-
- block = prev_block;
}
buf_pool_mutex_exit(buf_pool);
@@ -19518,11 +19418,14 @@ static
void
innodb_status_output_update(THD*,st_mysql_sys_var*,void*var,const void*save)
{
- *static_cast<my_bool*>(var) = *static_cast<const my_bool*>(save);
- mysql_mutex_unlock(&LOCK_global_system_variables);
- /* Wakeup server monitor thread. */
- os_event_set(srv_monitor_event);
- mysql_mutex_lock(&LOCK_global_system_variables);
+ *static_cast<my_bool*>(var)= *static_cast<const my_bool*>(save);
+ if (srv_monitor_event)
+ {
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ /* Wakeup server monitor thread. */
+ os_event_set(srv_monitor_event);
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ }
}
/** Update the system variable innodb_encryption_threads.
@@ -19588,33 +19491,6 @@ innodb_log_checksums_update(
thd, *static_cast<const my_bool*>(save));
}
-#ifdef UNIV_DEBUG
-static
-void
-innobase_debug_sync_callback(srv_slot_t *slot, const void *value)
-{
- const char *value_str = *static_cast<const char* const*>(value);
- size_t len = strlen(value_str) + 1;
-
-
- // One allocatoin for list node object and value.
- void *buf = ut_malloc_nokey(sizeof(srv_slot_t::debug_sync_t) + len);
- srv_slot_t::debug_sync_t *sync = new(buf) srv_slot_t::debug_sync_t();
- strcpy(reinterpret_cast<char*>(&sync[1]), value_str);
-
- rw_lock_x_lock(&slot->debug_sync_lock);
- UT_LIST_ADD_LAST(slot->debug_sync, sync);
- rw_lock_x_unlock(&slot->debug_sync_lock);
-}
-static
-void
-innobase_debug_sync_set(THD *thd, st_mysql_sys_var*, void *, const void *value)
-{
- srv_for_each_thread(SRV_WORKER, innobase_debug_sync_callback, value);
- srv_for_each_thread(SRV_PURGE, innobase_debug_sync_callback, value);
-}
-#endif
-
static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG}
@@ -20018,7 +19894,7 @@ static MYSQL_SYSVAR_ENUM(checksum_algorithm, srv_checksum_algorithm,
static MYSQL_SYSVAR_BOOL(log_checksums, innodb_log_checksums,
PLUGIN_VAR_RQCMDARG,
- "Whether to compute and require checksums for InnoDB redo log blocks",
+ "DEPRECATED. Whether to require checksums for InnoDB redo log blocks.",
NULL, innodb_log_checksums_update, TRUE);
static MYSQL_SYSVAR_BOOL(checksums, innobase_use_checksums,
@@ -20369,10 +20245,10 @@ static MYSQL_SYSVAR_BOOL(log_compressed_pages, page_zip_log_pages,
static MYSQL_SYSVAR_BOOL(log_optimize_ddl, innodb_log_optimize_ddl,
PLUGIN_VAR_OPCMDARG,
- "Reduce redo logging when natively creating indexes or rebuilding tables."
- " Setting this OFF avoids delay due to page flushing and"
- " allows concurrent backup.",
- NULL, NULL, TRUE);
+ "DEPRECATED. Ignored in MariaDB 10.5."
+ " Reduce redo logging when natively creating indexes or rebuilding tables."
+ " Enabling this may slow down backup and cause delay due to page flushing.",
+ NULL, NULL, FALSE);
static MYSQL_SYSVAR_ULONG(autoextend_increment,
sys_tablespace_auto_extend_increment,
@@ -20713,8 +20589,8 @@ static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
static MYSQL_SYSVAR_UINT(spin_wait_delay, srv_spin_wait_delay,
PLUGIN_VAR_OPCMDARG,
- "Maximum delay between polling for a spin lock (6 by default)",
- NULL, NULL, 6, 0, 6000, 0);
+ "Maximum delay between polling for a spin lock (4 by default)",
+ NULL, NULL, 4, 0, 6000, 0);
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
PLUGIN_VAR_RQCMDARG,
@@ -21026,7 +20902,7 @@ static MYSQL_SYSVAR_UINT(data_file_size_debug,
srv_sys_space_size_debug,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"InnoDB system tablespace size to be set in recovery.",
- NULL, NULL, 0, 0, UINT_MAX32, 0);
+ NULL, NULL, 0, 0, 256U << 20, 0);
static MYSQL_SYSVAR_ULONG(fil_make_page_dirty_debug,
srv_fil_make_page_dirty_debug, PLUGIN_VAR_OPCMDARG,
@@ -21091,7 +20967,7 @@ static TYPELIB page_compression_algorithms_typelib=
};
static MYSQL_SYSVAR_ENUM(compression_algorithm, innodb_compression_algorithm,
PLUGIN_VAR_OPCMDARG,
- "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2",
+ "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, bzip2, or snappy",
innodb_compression_algorithm_validate, NULL,
/* We use here the largest number of supported compression method to
enable all those methods that are available. Availability of compression
@@ -21142,7 +21018,7 @@ static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,
"scrubbing",
NULL,
innodb_encryption_threads_update,
- srv_n_fil_crypt_threads, 0, UINT_MAX32, 0);
+ 0, 0, 255, 0);
static MYSQL_SYSVAR_UINT(encryption_rotate_key_age,
srv_fil_crypt_rotate_key_age,
@@ -21227,16 +21103,6 @@ static MYSQL_SYSVAR_BOOL(debug_force_scrubbing,
0,
"Perform extra scrubbing to increase test exposure",
NULL, NULL, FALSE);
-
-char *innobase_debug_sync;
-static MYSQL_SYSVAR_STR(debug_sync, innobase_debug_sync,
- PLUGIN_VAR_NOCMDARG,
- "debug_sync for innodb purge threads. "
- "Use it to set up sync points for all purge threads "
- "at once. The commands will be applied sequentially at "
- "the beginning of purging the next undo record.",
- NULL,
- innobase_debug_sync_set, NULL);
#endif /* UNIV_DEBUG */
static MYSQL_SYSVAR_BOOL(instrument_semaphores, innodb_instrument_semaphores,
@@ -21460,7 +21326,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(background_scrub_data_check_interval),
#ifdef UNIV_DEBUG
MYSQL_SYSVAR(debug_force_scrubbing),
- MYSQL_SYSVAR(debug_sync),
#endif
MYSQL_SYSVAR(instrument_semaphores),
MYSQL_SYSVAR(buf_dump_status_frequency),
@@ -21934,64 +21799,53 @@ innobase_get_field_from_update_vector(
Allocate a heap and record for calculating virtual fields
Used mainly for virtual fields in indexes
-@param[in] thd MariaDB THD
-@param[in] index Index in use
-@param[out] heap Heap that holds temporary row
-@param[in,out] table MariaDB table
-@param[out] record Pointer to allocated MariaDB record
-@param[out] storage Internal storage for blobs etc
+@param[in] thd MariaDB THD
+@param[in] index Index in use
+@param[out] heap Heap that holds temporary row
+@param[in,out] table MariaDB table
+@param[out] record Pointer to allocated MariaDB record
+@param[out] storage Internal storage for blobs etc
-@retval false on success
-@retval true on malloc failure or failed to open the maria table
+@retval true on success
+@retval false on malloc failure or failed to open the maria table
for purge thread.
*/
-bool innobase_allocate_row_for_vcol(
- THD * thd,
- dict_index_t* index,
- mem_heap_t** heap,
- TABLE** table,
- byte** record,
- VCOL_STORAGE** storage)
-{
- TABLE *maria_table;
- String *blob_value_storage;
- if (!*table)
- *table= innodb_find_table_for_vc(thd, index->table);
-
- /* For purge thread, there is a possiblity that table could have
- dropped, corrupted or unaccessible. */
- if (!*table)
- return true;
- maria_table= *table;
- if (!*heap && !(*heap= mem_heap_create(srv_page_size)))
- {
- *storage= 0;
- return TRUE;
- }
- *record= static_cast<byte*>(mem_heap_alloc(*heap,
- maria_table->s->reclength));
- *storage= static_cast<VCOL_STORAGE*>
- (mem_heap_alloc(*heap, sizeof(**storage)));
- blob_value_storage= static_cast<String*>
- (mem_heap_alloc(*heap,
- maria_table->s->virtual_not_stored_blob_fields *
- sizeof(String)));
- if (!*record || !*storage || !blob_value_storage)
- {
- *storage= 0;
- return TRUE;
- }
- (*storage)->maria_table= maria_table;
- (*storage)->innobase_record= *record;
- (*storage)->maria_record= maria_table->field[0]->record_ptr();
- (*storage)->blob_value_storage= blob_value_storage;
+bool innobase_allocate_row_for_vcol(THD *thd, dict_index_t *index,
+ mem_heap_t **heap, TABLE **table,
+ VCOL_STORAGE *storage)
+{
+ TABLE *maria_table;
+ String *blob_value_storage;
+ if (!*table)
+ *table = innodb_find_table_for_vc(thd, index->table);
+
+ /* For purge thread, there is a possiblity that table could have
+ dropped, corrupted or unaccessible. */
+ if (!*table)
+ return false;
+ maria_table = *table;
+ if (!*heap && !(*heap = mem_heap_create(srv_page_size)))
+ return false;
+
+ uchar *record = static_cast<byte *>(mem_heap_alloc(*heap,
+ maria_table->s->reclength));
- maria_table->move_fields(maria_table->field, *record,
- (*storage)->maria_record);
- maria_table->remember_blob_values(blob_value_storage);
+ size_t len = maria_table->s->virtual_not_stored_blob_fields * sizeof(String);
+ blob_value_storage = static_cast<String *>(mem_heap_alloc(*heap, len));
+
+ if (!record || !blob_value_storage)
+ return false;
- return FALSE;
+ storage->maria_table = maria_table;
+ storage->innobase_record = record;
+ storage->maria_record = maria_table->field[0]->record_ptr();
+ storage->blob_value_storage = blob_value_storage;
+
+ maria_table->move_fields(maria_table->field, record, storage->maria_record);
+ maria_table->remember_blob_values(blob_value_storage);
+
+ return true;
}
@@ -22006,6 +21860,13 @@ void innobase_free_row_for_vcol(VCOL_STORAGE *storage)
}
+void innobase_report_computed_value_failed(dtuple_t *row)
+{
+ ib::error() << "Compute virtual column values failed for "
+ << rec_printer(row).str();
+}
+
+
/** Get the computed value by supplying the base column values.
@param[in,out] row the data row
@param[in] col virtual column
@@ -22133,13 +21994,6 @@ innobase_get_computed_value(
dbug_tmp_restore_column_map(mysql_table->write_set, old_write_set);
if (ret != 0) {
- // FIXME: Why this error message is macro-hidden?
-#ifdef INNODB_VIRTUAL_DEBUG
- ib::warn() << "Compute virtual column values failed ";
- fputs("InnoDB: Cannot compute value for following record ",
- stderr);
- dtuple_print(stderr, row);
-#endif /* INNODB_VIRTUAL_DEBUG */
DBUG_RETURN(NULL);
}
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 312da6451f0..a02c897f7ae 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -219,8 +219,7 @@ public:
int delete_table(const char *name);
int rename_table(const char* from, const char* to);
- int defragment_table(const char* name, const char* index_name,
- bool async);
+ inline int defragment_table(const char* name);
int check(THD* thd, HA_CHECK_OPT* check_opt);
char* update_table_comment(const char* comment);
@@ -508,8 +507,6 @@ size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen);
extern "C" {
-struct charset_info_st *thd_charset(MYSQL_THD thd);
-
/** Check if a user thread is a replication slave thread
@param thd user thread
@retval 0 the user thread is not a replication slave thread
@@ -680,9 +677,11 @@ public:
void allocate_trx();
/** Checks that every index have sane size. Depends on strict mode */
- bool row_size_is_acceptable(const dict_table_t& table) const;
+ bool row_size_is_acceptable(const dict_table_t& table,
+ bool strict) const;
/** Checks that given index have sane size. Depends on strict mode */
- bool row_size_is_acceptable(const dict_index_t& index) const;
+ bool row_size_is_acceptable(const dict_index_t& index,
+ bool strict) const;
/** Determines InnoDB table flags.
If strict_mode=OFF, this will adjust the flags to what should be assumed.
@@ -968,3 +967,15 @@ ib_push_frm_error(
@return true if index column length exceeds limit */
MY_ATTRIBUTE((warn_unused_result))
bool too_big_key_part_length(size_t max_field_len, const KEY& key);
+
+/** This function is used to rollback one X/Open XA distributed transaction
+which is in the prepared state
+
+@param[in] hton InnoDB handlerton
+@param[in] xid X/Open XA transaction identification
+
+@return 0 or error number */
+int innobase_rollback_by_xid(handlerton* hton, XID* xid);
+
+/** Free tablespace resources allocated. */
+void innobase_space_shutdown();
diff --git a/storage/innobase/handler/ha_xtradb.h b/storage/innobase/handler/ha_xtradb.h
index 9e898818a01..b049905613c 100644
--- a/storage/innobase/handler/ha_xtradb.h
+++ b/storage/innobase/handler/ha_xtradb.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Copyright (c) 2009, Percona Inc.
Portions of this file contain modifications contributed and copyrighted
@@ -507,18 +507,6 @@ set_log_checksum_algorithm(THD* thd, st_mysql_sys_var*, void*, const void* save)
ER_WARN_DEPRECATED_SYNTAX,
innodb_deprecated_msg,
"innodb_log_checksum_algorithm");
- log_mutex_enter();
- srv_log_checksum_algorithm = *static_cast<const ulong*>(save);
- if (srv_log_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_NONE) {
- ib::info() << "Setting innodb_log_checksums = false";
- innodb_log_checksums = false;
- log_checksum_algorithm_ptr = log_block_calc_checksum_none;
- } else {
- ib::info() << "Setting innodb_log_checksums = true";
- innodb_log_checksums = true;
- log_checksum_algorithm_ptr = log_block_calc_checksum_crc32;
- }
- log_mutex_exit();
}
static MYSQL_SYSVAR_ENUM(log_checksum_algorithm, srv_log_checksum_algorithm,
PLUGIN_VAR_RQCMDARG,
@@ -869,15 +857,6 @@ innodb_check_deprecated(void)
if (srv_log_checksum_algorithm != SRV_CHECKSUM_ALGORITHM_DEPRECATED) {
innodb_print_deprecation("innodb-log-checksum-algorithm");
- if (srv_log_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_NONE) {
- ib::info() << "Setting innodb_log_checksums = false";
- innodb_log_checksums = false;
- log_checksum_algorithm_ptr = log_block_calc_checksum_none;
- } else {
- ib::info() << "Setting innodb_log_checksums = true";
- innodb_log_checksums = true;
- log_checksum_algorithm_ptr = log_block_calc_checksum_crc32;
- }
}
if (srv_max_changed_pages) {
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index bae93e399e9..b766cac5dd5 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -101,19 +101,23 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_FOREIGN_OPERATIONS
= Alter_inplace_info::DROP_FOREIGN_KEY
| Alter_inplace_info::ADD_FOREIGN_KEY;
-/** Operations that InnoDB cares about and can perform without rebuild */
-static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD
- = INNOBASE_ONLINE_CREATE
- | INNOBASE_FOREIGN_OPERATIONS
+/** Operations that InnoDB cares about and can perform without validation */
+static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOVALIDATE
+ = INNOBASE_FOREIGN_OPERATIONS
| Alter_inplace_info::DROP_INDEX
| Alter_inplace_info::DROP_UNIQUE_INDEX
| Alter_inplace_info::ALTER_COLUMN_NAME
- | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH
//| Alter_inplace_info::ALTER_INDEX_COMMENT
- | Alter_inplace_info::ADD_VIRTUAL_COLUMN
| Alter_inplace_info::DROP_VIRTUAL_COLUMN
| Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER;
+/** Operations that InnoDB cares about and can perform without rebuild */
+static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD
+ = INNOBASE_ALTER_NOVALIDATE
+ | INNOBASE_ONLINE_CREATE
+ | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH
+ | Alter_inplace_info::ADD_VIRTUAL_COLUMN;
+
struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
{
/** Dummy query graph */
@@ -244,15 +248,12 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
@return whether the table will be rebuilt */
bool need_rebuild () const { return(old_table != new_table); }
- /** Clear uncommmitted added indexes after a failed operation. */
- void clear_added_indexes()
- {
- for (ulint i = 0; i < num_to_add_index; i++) {
- if (!add_index[i]->is_committed()) {
- add_index[i]->detach_columns();
- }
- }
- }
+ /** Clear uncommmitted added indexes after a failed operation. */
+ void clear_added_indexes()
+ {
+ for (ulint i= 0; i < num_to_add_index; i++)
+ add_index[i]->detach_columns(true);
+ }
/** Share context between partitions.
@param[in] ctx context from another partition of the table */
@@ -1801,7 +1802,7 @@ innobase_rec_to_mysql(
struct TABLE* table, /*!< in/out: MySQL table */
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: index */
- const ulint* offsets)/*!< in: rec_get_offsets(
+ const rec_offs* offsets)/*!< in: rec_get_offsets(
rec, index, ...) */
{
uint n_fields = table->s->fields;
@@ -3361,7 +3362,11 @@ innobase_pk_order_preserved(
if (old_pk_column) {
new_field_order = old_field;
} else if (innobase_pk_col_is_existing(new_col_no, col_map,
- old_n_cols)) {
+ old_n_cols)
+ || new_clust_index->table->persistent_autoinc
+ == new_field + 1) {
+ /* Adding an existing column or an AUTO_INCREMENT
+ column may change the existing ordering. */
new_field_order = old_n_uniq + existing_field_count++;
} else {
/* Skip newly added column. */
@@ -4403,6 +4408,7 @@ prepare_inplace_alter_table_dict(
create_table_info_t info(ctx->prebuilt->trx->mysql_thd, altered_table,
ha_alter_info->create_info, NULL, NULL,
srv_file_per_table);
+ ut_d(bool stats_wait = false);
if (num_fts_index > 1) {
my_error(ER_INNODB_FT_LIMIT, MYF(0));
@@ -4476,6 +4482,7 @@ prepare_inplace_alter_table_dict(
XXX what may happen if bg stats opens the table after we
have unlocked data dictionary below? */
dict_stats_wait_bg_to_stop_using_table(user_table, ctx->trx);
+ ut_d(stats_wait = true);
online_retry_drop_indexes_low(ctx->new_table, ctx->trx);
@@ -4844,7 +4851,14 @@ index_created:
goto error_handling;
}
- if (!info.row_size_is_acceptable(*ctx->add_index[a])) {
+ /* For ALTER TABLE...FORCE or OPTIMIZE TABLE, we may
+ only issue warnings, because there will be no schema change. */
+ if (!info.row_size_is_acceptable(
+ *ctx->add_index[a],
+ !!(ha_alter_info->handler_flags
+ & ~(INNOBASE_INPLACE_IGNORE
+ | INNOBASE_ALTER_NOVALIDATE
+ | Alter_inplace_info::RECREATE_TABLE)))) {
error = DB_TOO_BIG_RECORD;
goto error_handling;
}
@@ -4903,12 +4917,6 @@ index_created:
user_table);
dict_index_t* new_clust_index = dict_table_get_first_index(
ctx->new_table);
- ctx->skip_pk_sort = innobase_pk_order_preserved(
- ctx->col_map, clust_index, new_clust_index);
-
- DBUG_EXECUTE_IF("innodb_alter_table_pk_assert_no_sort",
- DBUG_ASSERT(ctx->skip_pk_sort););
-
DBUG_ASSERT(!ctx->new_table->persistent_autoinc);
if (const Field* ai = altered_table->found_next_number_field) {
const unsigned col_no = innodb_col_no(ai);
@@ -4927,6 +4935,12 @@ index_created:
}
}
+ ctx->skip_pk_sort = innobase_pk_order_preserved(
+ ctx->col_map, clust_index, new_clust_index);
+
+ DBUG_EXECUTE_IF("innodb_alter_table_pk_assert_no_sort",
+ DBUG_ASSERT(ctx->skip_pk_sort););
+
if (ctx->online) {
/* Allocate a log for online table rebuild. */
rw_lock_x_lock(&clust_index->lock);
@@ -5108,7 +5122,8 @@ error_handled:
/* n_ref_count must be 1, because purge cannot
be executing on this very table as we are
holding dict_operation_lock X-latch. */
- DBUG_ASSERT(user_table->get_ref_count() == 1 || ctx->online);
+ ut_ad(!stats_wait || ctx->online
+ || user_table->get_ref_count() == 1);
online_retry_drop_indexes_with_trx(user_table, ctx->trx);
} else {
@@ -5133,6 +5148,12 @@ err_exit:
trx_free_for_mysql(ctx->trx);
trx_commit_for_mysql(ctx->prebuilt->trx);
+ for (uint i = 0; i < ctx->num_to_add_fk; i++) {
+ if (ctx->add_fk[i]) {
+ dict_foreign_free(ctx->add_fk[i]);
+ }
+ }
+
delete ctx;
ha_alter_info->handler_ctx = NULL;
@@ -7911,6 +7932,7 @@ commit_cache_norebuild(
dict_index_remove_from_cache(index->table, index);
}
+ fts_clear_all(ctx->old_table, trx);
trx_commit_for_mysql(trx);
}
@@ -8395,9 +8417,15 @@ ha_innobase::commit_inplace_alter_table(
= static_cast<ha_innobase_inplace_ctx*>(*pctx);
DBUG_ASSERT(new_clustered == ctx->need_rebuild());
-
- fail = commit_set_autoinc(ha_alter_info, ctx, altered_table,
- table);
+ if (ctx->need_rebuild()
+ && dict_table_is_discarded(ctx->old_table)) {
+ my_error(ER_TABLESPACE_DISCARDED, MYF(0),
+ table->s->table_name.str);
+ fail = true;
+ } else {
+ fail = commit_set_autoinc(ha_alter_info, ctx,
+ altered_table, table);
+ }
if (fail) {
} else if (ctx->need_rebuild()) {
@@ -8678,25 +8706,18 @@ foreign_fail:
}
if (ctx0->num_to_drop_vcol || ctx0->num_to_add_vcol) {
+ /* FIXME: this workaround does not seem to work with
+ partitioned tables */
DBUG_ASSERT(ctx0->old_table->get_ref_count() == 1);
trx_commit_for_mysql(m_prebuilt->trx);
-#ifdef BTR_CUR_HASH_ADAPT
- if (btr_search_enabled) {
- btr_search_disable(false);
- btr_search_enable();
- }
-#endif /* BTR_CUR_HASH_ADAPT */
-
- char tb_name[FN_REFLEN];
- ut_strcpy(tb_name, m_prebuilt->table->name.m_name);
-
- tb_name[strlen(m_prebuilt->table->name.m_name)] = 0;
+ char tb_name[NAME_LEN * 2 + 1 + 1];
+ strcpy(tb_name, m_prebuilt->table->name.m_name);
dict_table_close(m_prebuilt->table, true, false);
dict_table_remove_from_cache(m_prebuilt->table);
m_prebuilt->table = dict_table_open_on_name(
- tb_name, TRUE, TRUE, DICT_ERR_IGNORE_NONE);
+ tb_name, TRUE, TRUE, DICT_ERR_IGNORE_FK_NOKEY);
/* Drop outdated table stats. */
char errstr[1024];
@@ -8822,7 +8843,7 @@ foreign_fail:
trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
dberr_t error = row_merge_drop_table(trx, ctx->old_table);
- if (error != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
ib::error() << "Inplace alter table " << ctx->old_table->name
<< " dropping copy of the old table failed error "
<< error
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index fae634630fd..1140b8b252a 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -2508,7 +2508,7 @@ i_s_metrics_fill(
time_diff = 0;
}
- /* Unless MONITOR__NO_AVERAGE is marked, we will need
+ /* Unless MONITOR_NO_AVERAGE is set, we must
to calculate the average value. If this is a monitor set
owner marked by MONITOR_SET_OWNER, divide
the value by another counter (number of calls) designated
@@ -2516,8 +2516,9 @@ i_s_metrics_fill(
Otherwise average the counter value by the time between the
time that the counter is enabled and time it is disabled
or time it is sampled. */
- if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
- && (monitor_info->monitor_type & MONITOR_SET_OWNER)
+ if ((monitor_info->monitor_type
+ & (MONITOR_NO_AVERAGE | MONITOR_SET_OWNER))
+ == MONITOR_SET_OWNER
&& monitor_info->monitor_related_id) {
mon_type_t value_start
= MONITOR_VALUE_SINCE_START(
@@ -2533,18 +2534,18 @@ i_s_metrics_fill(
fields[METRIC_AVG_VALUE_START]->set_null();
}
- if (MONITOR_VALUE(monitor_info->monitor_related_id)) {
- OK(fields[METRIC_AVG_VALUE_RESET]->store(
- MONITOR_VALUE(count)
- / MONITOR_VALUE(
- monitor_info->monitor_related_id),
- FALSE));
+ if (mon_type_t related_value =
+ MONITOR_VALUE(monitor_info->monitor_related_id)) {
+ OK(fields[METRIC_AVG_VALUE_RESET]
+ ->store(MONITOR_VALUE(count)
+ / related_value, false));
+ fields[METRIC_AVG_VALUE_RESET]->set_notnull();
} else {
fields[METRIC_AVG_VALUE_RESET]->set_null();
}
- } else if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
- && !(monitor_info->monitor_type
- & MONITOR_DISPLAY_CURRENT)) {
+ } else if (!(monitor_info->monitor_type
+ & (MONITOR_NO_AVERAGE
+ | MONITOR_DISPLAY_CURRENT))) {
if (time_diff != 0) {
OK(fields[METRIC_AVG_VALUE_START]->store(
(double) MONITOR_VALUE_SINCE_START(
@@ -3326,6 +3327,8 @@ no_fts:
conv_str.f_len = sizeof word;
conv_str.f_str = word;
+ rw_lock_s_lock(&cache->lock);
+
for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) {
fts_index_cache_t* index_cache;
@@ -3336,6 +3339,7 @@ no_fts:
index_cache, thd, &conv_str, tables));
}
+ rw_lock_s_unlock(&cache->lock);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
@@ -3474,7 +3478,7 @@ i_s_fts_index_table_fill_selected(
for (;;) {
error = fts_eval_sql(trx, graph);
- if (error == DB_SUCCESS) {
+ if (UNIV_LIKELY(error == DB_SUCCESS)) {
fts_sql_commit(trx);
break;
@@ -3488,7 +3492,7 @@ i_s_fts_index_table_fill_selected(
trx->error_state = DB_SUCCESS;
} else {
ib::error() << "Error occurred while reading"
- " FTS index: " << ut_strerr(error);
+ " FTS index: " << error;
break;
}
}
@@ -8057,31 +8061,24 @@ i_s_dict_fill_sys_tablespaces(
OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store(
page_size.physical(), true));
- char* filepath = NULL;
- if (FSP_FLAGS_HAS_DATA_DIR(cflags)) {
- mutex_enter(&dict_sys->mutex);
- filepath = dict_get_first_path(space);
- mutex_exit(&dict_sys->mutex);
- }
-
- if (filepath == NULL) {
- filepath = fil_make_filepath(NULL, name, IBD, false);
- }
-
os_file_stat_t stat;
os_file_size_t file;
memset(&file, 0xff, sizeof(file));
memset(&stat, 0x0, sizeof(stat));
- if (filepath != NULL) {
+ if (fil_space_t* s = fil_space_acquire_silent(space)) {
+ const char *filepath = s->chain.start
+ ? s->chain.start->name : NULL;
+ if (!filepath) {
+ goto file_done;
+ }
file = os_file_get_size(filepath);
/* Get the file system (or Volume) block size. */
- dberr_t err = os_file_get_status(filepath, &stat, false, false);
-
- switch(err) {
+ switch (dberr_t err = os_file_get_status(filepath, &stat,
+ false, false)) {
case DB_FAIL:
ib::warn()
<< "File '" << filepath << "', failed to get "
@@ -8093,13 +8090,12 @@ i_s_dict_fill_sys_tablespaces(
break;
default:
- ib::error()
- << "File '" << filepath << "' "
- << ut_strerr(err);
+ ib::error() << "File '" << filepath << "' " << err;
break;
}
- ut_free(filepath);
+file_done:
+ fil_space_release(s);
}
if (file.m_total_size == static_cast<os_offset_t>(~0)) {
@@ -8627,7 +8623,7 @@ i_s_tablespaces_encryption_fill_table(
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
/* deny access to user without PROCESS_ACL privilege */
- if (check_global_access(thd, SUPER_ACL)) {
+ if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
@@ -9101,6 +9097,8 @@ i_s_innodb_mutexes_fill_table(
~Locking() { mutex_exit(&rw_lock_list_mutex); }
} locking;
+ char lock_name[sizeof "buf0dump.cc:12345"];
+
for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL;
lock = UT_LIST_GET_NEXT(list, lock)) {
if (lock->count_os_wait == 0) {
@@ -9113,11 +9111,16 @@ i_s_innodb_mutexes_fill_table(
continue;
}
- //OK(field_store_string(fields[MUTEXES_NAME],
- // lock->lock_name));
- OK(field_store_string(
- fields[MUTEXES_CREATE_FILE],
- innobase_basename(lock->cfile_name)));
+ const char* basename = innobase_basename(
+ lock->cfile_name);
+
+ snprintf(lock_name, sizeof lock_name, "%s:%u",
+ basename, lock->cline);
+
+ OK(field_store_string(fields[MUTEXES_NAME],
+ lock_name));
+ OK(field_store_string(fields[MUTEXES_CREATE_FILE],
+ basename));
OK(fields[MUTEXES_CREATE_LINE]->store(lock->cline,
true));
fields[MUTEXES_CREATE_LINE]->set_notnull();
@@ -9133,8 +9136,8 @@ i_s_innodb_mutexes_fill_table(
snprintf(buf1, sizeof buf1, "combined %s",
innobase_basename(block_lock->cfile_name));
- //OK(field_store_string(fields[MUTEXES_NAME],
- // block_lock->lock_name));
+ OK(field_store_string(fields[MUTEXES_NAME],
+ "buf_block_t::lock"));
OK(field_store_string(fields[MUTEXES_CREATE_FILE],
buf1));
OK(fields[MUTEXES_CREATE_LINE]->store(block_lock->cline,
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 7bf00eaa7c8..37666cdf372 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -28,6 +28,8 @@ Created 7/19/1997 Heikki Tuuri
#include "sync0sync.h"
#include "btr0sea.h"
+using st_::span;
+
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
my_bool srv_ibuf_disable_background_merge;
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
@@ -1445,7 +1447,7 @@ ibuf_dummy_index_create(
table = dict_mem_table_create("IBUF_DUMMY",
DICT_HDR_SPACE, n, 0,
- comp ? DICT_TF_COMPACT : 0, 0);
+ comp ? DICT_TF_COMPACT : 0, 0, false);
index = dict_mem_index_create("IBUF_DUMMY", "IBUF_DUMMY",
DICT_HDR_SPACE, 0, n);
@@ -1982,7 +1984,7 @@ ibuf_add_free_page(void)
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
- mtr_x_lock(&space->latch, &mtr);
+ mtr.x_lock_space(space, __FILE__, __LINE__);
header_page = ibuf_header_page_get(&mtr);
/* Allocate a new page: NOTE that if the page has been a part of a
@@ -2066,7 +2068,7 @@ ibuf_remove_free_page(void)
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
- mtr_x_lock(&space->latch, &mtr);
+ mtr.x_lock_space(space, __FILE__, __LINE__);
header_page = ibuf_header_page_get(&mtr);
/* Prevent pessimistic inserts to insert buffer trees for a while */
@@ -2107,7 +2109,7 @@ ibuf_remove_free_page(void)
page from it. */
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
- IBUF_SPACE_ID, page_no, false, &mtr);
+ IBUF_SPACE_ID, page_no, &mtr);
const page_id_t page_id(IBUF_SPACE_ID, page_no);
@@ -2612,7 +2614,7 @@ ibuf_merge(
when a slow shutdown is being executed. During a slow
shutdown, the insert buffer merge must be completed. */
- if (ibuf->empty && !srv_shutdown_state) {
+ if (ibuf->empty && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
return(0);
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
} else if (ibuf_debug) {
@@ -2744,42 +2746,28 @@ ibuf_contract_after_insert(
} while (size > 0 && sum_sizes < entry_size);
}
-/*********************************************************************//**
-Determine if an insert buffer record has been encountered already.
-@return TRUE if a new record, FALSE if possible duplicate */
-static
-ibool
-ibuf_get_volume_buffered_hash(
-/*==========================*/
- const rec_t* rec, /*!< in: ibuf record in post-4.1 format */
- const byte* types, /*!< in: fields */
- const byte* data, /*!< in: start of user record data */
- ulint comp, /*!< in: 0=ROW_FORMAT=REDUNDANT,
- nonzero=ROW_FORMAT=COMPACT */
- ulint* hash, /*!< in/out: hash array */
- ulint size) /*!< in: number of elements in hash array */
+/** Determine if a change buffer record has been encountered already.
+@param rec change buffer record in the MySQL 5.5 format
+@param hash hash table of encountered records
+@param size number of elements in hash
+@retval true if a distinct record
+@retval false if this may be duplicating an earlier record */
+static bool ibuf_get_volume_buffered_hash(const rec_t *rec, ulint *hash,
+ ulint size)
{
- ulint len;
- ulint fold;
- ulint bitmask;
-
- len = ibuf_rec_get_size(
- rec, types,
- rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER, comp);
- fold = ut_fold_binary(data, len);
-
- hash += (fold / (CHAR_BIT * sizeof *hash)) % size;
- bitmask = static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
-
- if (*hash & bitmask) {
-
- return(FALSE);
- }
-
- /* We have not seen this record yet. Insert it. */
- *hash |= bitmask;
-
- return(TRUE);
+ ut_ad(rec_get_n_fields_old(rec) > IBUF_REC_FIELD_USER);
+ const ulint start= rec_get_field_start_offs(rec, IBUF_REC_FIELD_USER);
+ const ulint len= rec_get_data_size_old(rec) - start;
+ const uint32_t fold= ut_crc32(rec + start, len);
+ hash+= (fold / (CHAR_BIT * sizeof *hash)) % size;
+ ulint bitmask= static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
+
+ if (*hash & bitmask)
+ return false;
+
+ /* We have not seen this record yet. Remember it. */
+ *hash|= bitmask;
+ return true;
}
#ifdef UNIV_DEBUG
@@ -2872,11 +2860,7 @@ ibuf_get_volume_buffered_count_func(
case IBUF_OP_DELETE_MARK:
/* There must be a record to delete-mark.
See if this record has been already buffered. */
- if (n_recs && ibuf_get_volume_buffered_hash(
- rec, types + IBUF_REC_INFO_SIZE,
- types + len,
- types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT,
- hash, size)) {
+ if (n_recs && ibuf_get_volume_buffered_hash(rec, hash, size)) {
(*n_recs)++;
}
@@ -3319,7 +3303,7 @@ ibuf_insert_low(
dtuple_t* ibuf_entry;
mem_heap_t* offsets_heap = NULL;
mem_heap_t* heap;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
ulint buffered;
lint min_n_recs;
rec_t* ins_rec;
@@ -3784,7 +3768,7 @@ ibuf_insert_to_index_page_low(
buf_block_t* block, /*!< in/out: index page where the buffered
entry should be placed */
dict_index_t* index, /*!< in: record descriptor */
- ulint** offsets,/*!< out: offsets on *rec */
+ rec_offs** offsets,/*!< out: offsets on *rec */
mem_heap_t* heap, /*!< in/out: memory heap */
mtr_t* mtr, /*!< in/out: mtr */
page_cur_t* page_cur)/*!< in/out: cursor positioned on the record
@@ -3864,7 +3848,7 @@ ibuf_insert_to_index_page(
ulint low_match;
page_t* page = buf_block_get_frame(block);
rec_t* rec;
- ulint* offsets;
+ rec_offs* offsets;
mem_heap_t* heap;
DBUG_ENTER("ibuf_insert_to_index_page");
@@ -4121,8 +4105,8 @@ ibuf_delete(
/* TODO: the below should probably be a separate function,
it's a bastardized version of btr_cur_optimistic_delete. */
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
mem_heap_t* heap = NULL;
ulint max_ins_size = 0;
@@ -4488,7 +4472,10 @@ ibuf_merge_or_delete_for_page(
fil_space_release(space);
if (UNIV_UNLIKELY(srv_shutdown_state)
- && !srv_fast_shutdown) {
+ && !srv_fast_shutdown
+ && (!block
+ || btr_page_get_index_id(block->frame)
+ != DICT_IBUF_ID_MIN + IBUF_SPACE_ID)) {
/* Prevent an infinite loop on slow
shutdown, in case the bitmap bits are
wrongly clear even though buffered
@@ -4574,8 +4561,7 @@ loop:
}
if (!btr_pcur_is_on_user_rec(&pcur)) {
- ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr));
-
+ ut_ad(btr_pcur_is_after_last_on_page(&pcur));
goto reset_bit;
}
@@ -4805,8 +4791,7 @@ loop:
&pcur, &mtr);
if (!btr_pcur_is_on_user_rec(&pcur)) {
- ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr));
-
+ ut_ad(btr_pcur_is_after_last_on_page(&pcur));
goto leave_loop;
}
@@ -4972,7 +4957,8 @@ ibuf_check_bitmap_on_import(
bitmap_page = ibuf_bitmap_get_map_page(
page_id_t(space_id, page_no), page_size, &mtr);
- if (buf_page_is_zeroes(bitmap_page, page_size.physical())) {
+ if (buf_is_zeroes(span<const byte>(bitmap_page,
+ page_size.physical()))) {
/* This means we got all-zero page instead of
ibuf bitmap page. The subsequent page should be
all-zero pages. */
@@ -4985,8 +4971,8 @@ ibuf_check_bitmap_on_import(
page_size,
RW_S_LATCH, &mtr);
page_t* page = buf_block_get_frame(block);
- ut_ad(buf_page_is_zeroes(
- page, page_size.physical()));
+ ut_ad(buf_is_zeroes(span<const byte>(
+ page, page_size.physical())));
}
#endif /* UNIV_DEBUG */
ibuf_exit(&mtr);
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index ee4e522cf49..5bc0b70714c 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -30,6 +30,7 @@ Created 6/2/1994 Heikki Tuuri
#include "dict0dict.h"
#include "data0data.h"
+#include "rem0types.h"
#include "page0cur.h"
#include "btr0types.h"
#include "gis0type.h"
@@ -305,7 +306,7 @@ ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
const rec_t* rec, /*!< in: node pointer record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/** Create the root node for a new index tree.
@@ -392,7 +393,7 @@ btr_root_raise_and_insert(
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
- ulint** offsets,/*!< out: offsets on inserted record */
+ rec_offs** offsets,/*!< out: offsets on inserted record */
mem_heap_t** heap, /*!< in/out: pointer to memory heap
that can be emptied, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
@@ -475,7 +476,7 @@ btr_page_split_and_insert(
btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
- ulint** offsets,/*!< out: offsets on inserted record */
+ rec_offs** offsets,/*!< out: offsets on inserted record */
mem_heap_t** heap, /*!< in/out: pointer to memory heap
that can be emptied, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic
index f4fcd9f4194..878e414a039 100644
--- a/storage/innobase/include/btr0btr.ic
+++ b/storage/innobase/include/btr0btr.ic
@@ -218,7 +218,7 @@ ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
const rec_t* rec, /*!< in: node pointer record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
const byte* field;
ulint len;
diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h
index a65f6901ce9..854414d504d 100644
--- a/storage/innobase/include/btr0bulk.h
+++ b/storage/innobase/include/btr0bulk.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, MariaDB Corporation.
+Copyright (c) 2019, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -28,6 +28,7 @@ Created 03/11/2014 Shaohua Wang
#define btr0bulk_h
#include "dict0dict.h"
+#include "rem0types.h"
#include "page0cur.h"
#include <vector>
@@ -103,12 +104,15 @@ public:
/** Insert a record in the page.
@param[in] rec record
@param[in] offsets record offsets */
- void insert(const rec_t* rec, ulint* offsets);
+ void insert(const rec_t* rec, rec_offs* offsets);
/** Mark end of insertion to the page. Scan all records to set page
dirs, and set page header members. */
void finish();
+ /** @return whether finish() actually needs to do something */
+ inline bool needs_finish() const;
+
/** Commit mtr for a page
@param[in] success Flag whether all inserts succeed. */
void commit(bool success);
@@ -127,7 +131,7 @@ public:
@param[in] big_rec external recrod
@param[in] offsets record offsets
@return error code */
- dberr_t storeExt(const big_rec_t* big_rec, ulint* offsets);
+ dberr_t storeExt(const big_rec_t* big_rec, rec_offs* offsets);
/** Get node pointer
@return node pointer */
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 4d67833db70..f70fe687182 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -30,6 +30,7 @@ Created 10/16/1994 Heikki Tuuri
#include "dict0dict.h"
#include "page0cur.h"
#include "btr0types.h"
+#include "rem0types.h"
#include "gis0type.h"
/** Mode flags for btr_cur operations; these can be ORed */
@@ -153,8 +154,7 @@ Note that if mode is PAGE_CUR_LE, which is used in inserts, then
cursor->up_match and cursor->low_match both will have sensible values.
If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
dberr_t
-btr_cur_search_to_nth_level(
-/*========================*/
+btr_cur_search_to_nth_level_func(
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: the tree level of search */
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
@@ -180,16 +180,24 @@ btr_cur_search_to_nth_level(
to protect the record! */
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
+#ifdef BTR_CUR_HASH_ADAPT
ulint has_search_latch,
/*!< in: latch mode the caller
currently has on search system:
RW_S_LATCH, or 0 */
+#endif /* BTR_CUR_HASH_ADAPT */
const char* file, /*!< in: file name */
unsigned line, /*!< in: line where called */
mtr_t* mtr, /*!< in/out: mini-transaction */
- ib_uint64_t autoinc = 0);
+ ib_uint64_t autoinc);
/*!< in: PAGE_ROOT_AUTO_INC to be written
(0 if none) */
+#ifdef BTR_CUR_HASH_ADAPT
+# define btr_cur_search_to_nth_level btr_cur_search_to_nth_level_func
+#else /* BTR_CUR_HASH_ADAPT */
+# define btr_cur_search_to_nth_level(ix,lv,t,md,l,cur,has,file,line,m,ai) \
+ btr_cur_search_to_nth_level_func(ix,lv,t,md,l,cur,file,line,m,ai)
+#endif /* BTR_CUR_HASH_ADAPT */
/*****************************************************************//**
Opens a cursor at either end of an index.
@@ -242,7 +250,7 @@ btr_cur_optimistic_insert(
specified */
btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
- ulint** offsets,/*!< out: offsets on *rec */
+ rec_offs** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
@@ -278,7 +286,7 @@ btr_cur_pessimistic_insert(
insertion will certainly succeed */
btr_cur_t* cursor, /*!< in: cursor after which to insert;
cursor stays valid */
- ulint** offsets,/*!< out: offsets on *rec */
+ rec_offs** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap
that can be emptied */
dtuple_t* entry, /*!< in/out: entry to insert */
@@ -312,7 +320,7 @@ btr_cur_update_alloc_zip_func(
page_cur_t* cursor, /*!< in/out: B-tree page cursor */
dict_index_t* index, /*!< in: the index corresponding to cursor */
#ifdef UNIV_DEBUG
- ulint* offsets,/*!< in/out: offsets of the cursor record */
+ rec_offs* offsets,/*!< in/out: offsets of the cursor record */
#endif /* UNIV_DEBUG */
ulint length, /*!< in: size needed */
bool create, /*!< in: true=delete-and-insert,
@@ -339,7 +347,7 @@ btr_cur_update_in_place(
btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- ulint* offsets,/*!< in/out: offsets on cursor->page_cur.rec */
+ rec_offs* offsets,/*!< in/out: offsets on cursor->page_cur.rec */
const upd_t* update, /*!< in: update vector */
ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
@@ -381,7 +389,7 @@ btr_cur_optimistic_update(
btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
+ rec_offs** offsets,/*!< out: offsets on cursor->page_cur.rec */
mem_heap_t** heap, /*!< in/out: pointer to NULL or memory heap */
const upd_t* update, /*!< in: update vector; this must also
contain trx id and roll ptr fields */
@@ -408,7 +416,7 @@ btr_cur_pessimistic_update(
btr_cur_t* cursor, /*!< in/out: cursor on the record to update;
cursor may become invalid if *big_rec == NULL
|| !(flags & BTR_KEEP_POS_FLAG) */
- ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
+ rec_offs** offsets,/*!< out: offsets on cursor->page_cur.rec */
mem_heap_t** offsets_heap,
/*!< in/out: pointer to memory heap
that can be emptied */
@@ -440,7 +448,7 @@ btr_cur_del_mark_set_clust_rec(
buf_block_t* block, /*!< in/out: buffer block of the record */
rec_t* rec, /*!< in/out: record */
dict_index_t* index, /*!< in: clustered index of the record */
- const ulint* offsets,/*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec) */
que_thr_t* thr, /*!< in: query thread */
const dtuple_t* entry, /*!< in: dtuple for the deleting record */
mtr_t* mtr) /*!< in/out: mini-transaction */
@@ -607,7 +615,7 @@ btr_estimate_number_of_different_key_vals(
ulint
btr_rec_get_externally_stored_len(
const rec_t* rec,
- const ulint* offsets);
+ const rec_offs* offsets);
/*******************************************************************//**
Marks non-updated off-page fields as disowned by this record. The ownership
@@ -621,7 +629,7 @@ btr_cur_disown_inherited_fields(
part will be updated, or NULL */
rec_t* rec, /*!< in/out: record in a clustered index */
dict_index_t* index, /*!< in: index of the page */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */
mtr_t* mtr) /*!< in/out: mini-transaction */
MY_ATTRIBUTE((nonnull(2,3,4,5,6)));
@@ -660,7 +668,7 @@ btr_store_big_rec_extern_fields(
btr_pcur_t* pcur, /*!< in/out: a persistent cursor. if
btr_mtr is restarted, then this can
be repositioned. */
- ulint* offsets, /*!< in/out: rec_get_offsets() on
+ rec_offs* offsets, /*!< in/out: rec_get_offsets() on
pcur. the "external storage" flags
in offsets will correctly correspond
to rec when this function returns */
@@ -691,7 +699,7 @@ btr_free_externally_stored_field(
byte* field_ref, /*!< in/out: field reference */
const rec_t* rec, /*!< in: record containing field_ref, for
page_zip_write_blob_ptr(), or NULL */
- const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec, index),
or NULL */
page_zip_des_t* page_zip, /*!< in: compressed page corresponding
to rec, or NULL if rec == NULL */
@@ -748,24 +756,12 @@ protected by a lock or a page latch
byte*
btr_rec_copy_externally_stored_field(
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
const page_size_t& page_size,
ulint no,
ulint* len,
mem_heap_t* heap);
-/*******************************************************************//**
-Flags the data tuple fields that are marked as extern storage in the
-update vector. We use this function to remember which fields we must
-mark as extern storage in a record inserted for an update.
-@return number of flagged external columns */
-ulint
-btr_push_update_extern_fields(
-/*==========================*/
- dtuple_t* tuple, /*!< in/out: data tuple */
- const upd_t* update, /*!< in: update vector */
- mem_heap_t* heap) /*!< in: memory heap */
- MY_ATTRIBUTE((nonnull));
/***********************************************************//**
Sets a secondary index record's delete mark to the given value. This
function is only used by the insert buffer merge mechanism. */
diff --git a/storage/innobase/include/btr0defragment.h b/storage/innobase/include/btr0defragment.h
index 57f8c2f3811..d622c3c7c39 100644
--- a/storage/innobase/include/btr0defragment.h
+++ b/storage/innobase/include/btr0defragment.h
@@ -64,8 +64,6 @@ is a synchronized defragmentation. */
os_event_t
btr_defragment_add_index(
dict_index_t* index, /*!< index to be added */
- bool async, /*!< whether this is an async
- defragmentation */
dberr_t* err); /*!< out: error code */
/******************************************************************//**
When table is dropped, this function is called to mark a table as removed in
diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h
index b79260e5ab6..26c7ebcee6d 100644
--- a/storage/innobase/include/btr0pcur.h
+++ b/storage/innobase/include/btr0pcur.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -136,15 +136,22 @@ btr_pcur_open_with_no_init_func(
page, but assume that the caller uses his
btr search latch to protect the record! */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+#ifdef BTR_CUR_HASH_ADAPT
ulint has_search_latch,
/*!< in: latch mode the caller
currently has on search system:
RW_S_LATCH, or 0 */
+#endif /* BTR_CUR_HASH_ADAPT */
const char* file, /*!< in: file name */
unsigned line, /*!< in: line where called */
mtr_t* mtr); /*!< in: mtr */
-#define btr_pcur_open_with_no_init(ix,t,md,l,cur,has,m) \
+#ifdef BTR_CUR_HASH_ADAPT
+# define btr_pcur_open_with_no_init(ix,t,md,l,cur,has,m) \
btr_pcur_open_with_no_init_func(ix,t,md,l,cur,has,__FILE__,__LINE__,m)
+#else /* BTR_CUR_HASH_ADAPT */
+# define btr_pcur_open_with_no_init(ix,t,md,l,cur,has,m) \
+ btr_pcur_open_with_no_init_func(ix,t,md,l,cur,__FILE__,__LINE__,m)
+#endif /* BTR_CUR_HASH_ADAPT */
/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic
index 8b0da666250..6bc5b356dab 100644
--- a/storage/innobase/include/btr0pcur.ic
+++ b/storage/innobase/include/btr0pcur.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -458,7 +458,7 @@ btr_pcur_open_low(
index, level, tuple, mode, latch_mode,
btr_cursor, 0, file, line, mtr, autoinc);
- if (err != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::warn() << " Error code: " << err
<< " btr_pcur_open_low "
<< " level: " << level
@@ -496,10 +496,12 @@ btr_pcur_open_with_no_init_func(
page, but assume that the caller uses his
btr search latch to protect the record! */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+#ifdef BTR_CUR_HASH_ADAPT
ulint has_search_latch,
/*!< in: latch mode the caller
currently has on search system:
RW_S_LATCH, or 0 */
+#endif /* BTR_CUR_HASH_ADAPT */
const char* file, /*!< in: file name */
unsigned line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
@@ -516,7 +518,7 @@ btr_pcur_open_with_no_init_func(
err = btr_cur_search_to_nth_level(
index, 0, tuple, mode, latch_mode, btr_cursor,
- has_search_latch, file, line, mtr);
+ has_search_latch, file, line, mtr, 0);
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
index 645b3689ff6..f2e208df6eb 100644
--- a/storage/innobase/include/btr0sea.h
+++ b/storage/innobase/include/btr0sea.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -36,32 +36,17 @@ Created 2/17/1996 Heikki Tuuri
void
btr_search_sys_create(ulint hash_size);
-/** Resize hash index hash table.
-@param[in] hash_size hash index hash table size */
-void
-btr_search_sys_resize(ulint hash_size);
-
/** Frees the adaptive search system at a database shutdown. */
void
btr_search_sys_free();
-/** Disable the adaptive hash search system and empty the index.
-@param need_mutex need to acquire dict_sys->mutex */
-void
-btr_search_disable(
- bool need_mutex);
-/** Enable the adaptive hash search system. */
+/** Disable the adaptive hash search system and empty the index. */
+void btr_search_disable();
+
+/** Enable the adaptive hash search system.
+@param[in] resize Flag to indicate call during buf_pool_resize() */
void
-btr_search_enable();
-
-/** Returns the value of ref_count. The value is protected by latch.
-@param[in] info search info
-@param[in] index index identifier
-@return ref_count value. */
-ulint
-btr_search_info_get_ref_count(
- btr_search_t* info,
- dict_index_t* index);
+btr_search_enable(bool resize=false);
/*********************************************************************//**
Updates the search info. */
@@ -156,18 +141,6 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor);
bool
btr_search_validate();
-/** X-Lock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_x_lock(const dict_index_t* index);
-
-/** X-Unlock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_x_unlock(const dict_index_t* index);
-
/** Lock all search latches in exclusive mode. */
UNIV_INLINE
void
@@ -178,18 +151,6 @@ UNIV_INLINE
void
btr_search_x_unlock_all();
-/** S-Lock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_s_lock(const dict_index_t* index);
-
-/** S-Unlock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_s_unlock(const dict_index_t* index);
-
/** Lock all search latches in shared mode. */
UNIV_INLINE
void
@@ -236,17 +197,12 @@ btr_get_search_table(const dict_index_t* index);
#else /* BTR_CUR_HASH_ADAPT */
# define btr_search_sys_create(size)
# define btr_search_drop_page_hash_index(block)
-# define btr_search_s_lock(index)
-# define btr_search_s_unlock(index)
# define btr_search_s_lock_all(index)
# define btr_search_s_unlock_all(index)
-# define btr_search_x_lock(index)
-# define btr_search_x_unlock(index)
# define btr_search_info_update(index, cursor)
# define btr_search_move_or_delete_hash_entries(new_block, block, index)
# define btr_search_update_hash_on_insert(cursor)
# define btr_search_update_hash_on_delete(cursor)
-# define btr_search_sys_resize(hash_size)
#endif /* BTR_CUR_HASH_ADAPT */
#ifdef BTR_CUR_ADAPT
@@ -327,6 +283,18 @@ struct btr_search_t{
};
#ifdef BTR_CUR_HASH_ADAPT
+/** @return number of leaf pages pointed to by the adaptive hash index */
+inline ulint dict_index_t::n_ahi_pages() const
+{
+ if (!btr_search_enabled)
+ return 0;
+ rw_lock_t *latch = btr_get_search_latch(this);
+ rw_lock_s_lock(latch);
+ ulint ref_count= search_info->ref_count;
+ rw_lock_s_unlock(latch);
+ return ref_count;
+}
+
/** The hash index system */
struct btr_search_sys_t{
hash_table_t** hash_tables; /*!< the adaptive hash tables,
diff --git a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0sea.ic
index 4972de16064..90877d23192 100644
--- a/storage/innobase/include/btr0sea.ic
+++ b/storage/innobase/include/btr0sea.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -62,8 +63,8 @@ btr_search_info_update(
dict_index_t* index, /*!< in: index of the cursor */
btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
+ ut_ad(!rw_lock_own_flagged(btr_get_search_latch(index),
+ RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
if (dict_index_is_spatial(index) || !btr_search_enabled) {
return;
@@ -87,24 +88,6 @@ btr_search_info_update(
btr_search_info_update_slow(info, cursor);
}
-/** X-Lock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_x_lock(const dict_index_t* index)
-{
- rw_lock_x_lock(btr_get_search_latch(index));
-}
-
-/** X-Unlock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_x_unlock(const dict_index_t* index)
-{
- rw_lock_x_unlock(btr_get_search_latch(index));
-}
-
/** Lock all search latches in exclusive mode. */
UNIV_INLINE
void
@@ -125,24 +108,6 @@ btr_search_x_unlock_all()
}
}
-/** S-Lock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_s_lock(const dict_index_t* index)
-{
- rw_lock_s_lock(btr_get_search_latch(index));
-}
-
-/** S-Unlock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_s_unlock(const dict_index_t* index)
-{
- rw_lock_s_unlock(btr_get_search_latch(index));
-}
-
/** Lock all search latches in shared mode. */
UNIV_INLINE
void
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index af2a7d90101..5f390d2761d 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -33,6 +33,7 @@ Created 11/5/1995 Heikki Tuuri
#include "fil0fil.h"
#include "mtr0types.h"
#include "buf0types.h"
+#include "span.h"
#ifndef UNIV_INNOCHECKSUM
#include "hash0hash.h"
#include "ut0byte.h"
@@ -70,11 +71,13 @@ struct fil_addr_t;
/* @} */
/** @name Modes for buf_page_get_known_nowait */
/* @{ */
-#define BUF_MAKE_YOUNG 51 /*!< Move the block to the
+#ifdef BTR_CUR_HASH_ADAPT
+# define BUF_MAKE_YOUNG 51 /*!< Move the block to the
start of the LRU list if there
is a danger that the block
would drift out of the buffer
pool*/
+#endif /* BTR_CUR_HASH_ADAPT */
#define BUF_KEEP_OLD 52 /*!< Preserve the current LRU
position of the block. */
/* @} */
@@ -281,12 +284,6 @@ extern "C"
os_thread_ret_t
DECLARE_THREAD(buf_resize_thread)(void*);
-#ifdef BTR_CUR_HASH_ADAPT
-/** Clear the adaptive hash index on all pages in the buffer pool. */
-void
-buf_pool_clear_hash_index();
-#endif /* BTR_CUR_HASH_ADAPT */
-
/*********************************************************************//**
Gets the current size of buffer buf_pool in bytes.
@return size in bytes */
@@ -435,6 +432,7 @@ buf_page_get_zip(
const page_size_t& page_size);
/** This is the general function used to get access to a database page.
+It does page initialization and applies the buffered redo logs.
@param[in] page_id page id
@param[in] rw_latch RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH
@param[in] guess guessed block or NULL
@@ -457,6 +455,29 @@ buf_page_get_gen(
mtr_t* mtr,
dberr_t* err);
+/** This is the low level function used to get access to a database page.
+@param[in] page_id page id
+@param[in] rw_latch RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH
+@param[in] guess guessed block or NULL
+@param[in] mode BUF_GET, BUF_GET_IF_IN_POOL,
+BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or BUF_GET_IF_IN_POOL_OR_WATCH
+@param[in] file file name
+@param[in] line line where called
+@param[in] mtr mini-transaction
+@param[out] err DB_SUCCESS or error code
+@return pointer to the block or NULL */
+buf_block_t*
+buf_page_get_low(
+ const page_id_t page_id,
+ const page_size_t& page_size,
+ ulint rw_latch,
+ buf_block_t* guess,
+ ulint mode,
+ const char* file,
+ unsigned line,
+ mtr_t* mtr,
+ dberr_t* err);
+
/** Initializes a page to the buffer buf_pool. The page is usually not read
from a file even if it cannot be found in the buffer buf_pool. This is one
of the functions which perform to a block a state transition NOT_USED =>
@@ -646,11 +667,10 @@ buf_block_unfix(buf_block_t* block);
# endif /* UNIV_DEBUG */
#endif /* !UNIV_INNOCHECKSUM */
-/** Check if a page is all zeroes.
-@param[in] read_buf database page
-@param[in] page_size page frame size
-@return whether the page is all zeroes */
-bool buf_page_is_zeroes(const void* read_buf, size_t page_size);
+/** Check if a buffer is all zeroes.
+@param[in] buf data to check
+@return whether the buffer is all zeroes */
+bool buf_is_zeroes(st_::span<const byte> buf);
/** Checks if the page is in crc32 checksum format.
@param[in] read_buf database page
@@ -706,6 +726,27 @@ buf_page_is_corrupted(
#endif
MY_ATTRIBUTE((warn_unused_result));
+inline void *aligned_malloc(size_t size, size_t align)
+{
+#ifdef _MSC_VER
+ return _aligned_malloc(size, align);
+#else
+ void *result;
+ if (posix_memalign(&result, align, size))
+ result= NULL;
+ return result;
+#endif
+}
+
+inline void aligned_free(void *ptr)
+{
+#ifdef _MSC_VER
+ _aligned_free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
#ifndef UNIV_INNOCHECKSUM
/**********************************************************************//**
Gets the space id, page offset, and byte offset within page of a
@@ -1379,7 +1420,7 @@ buf_page_encrypt_before_write(
NOTE! The definition appears here only for other modules of this
directory (buf) to see it. Do not use from outside! */
-typedef struct {
+struct buf_tmp_buffer_t {
private:
int32 reserved; /*!< true if this slot is reserved
*/
@@ -1409,7 +1450,7 @@ public:
return !my_atomic_fas32_explicit(&reserved, true,
MY_MEMORY_ORDER_RELAXED);
}
-} buf_tmp_buffer_t;
+};
/** The common buffer control block structure
for compressed and uncompressed frames */
@@ -1463,11 +1504,6 @@ public:
zip.data == NULL means an active
buf_pool->watch */
- ulint write_size; /* Write size is set when this
- page is first time written and then
- if written again we check is TRIM
- operation needed. */
-
ulint real_size; /*!< Real size of the page
Normal pages == UNIV_PAGE_SIZE
page compressed pages, payload
@@ -1701,7 +1737,7 @@ struct buf_block_t{
# define assert_block_ahi_empty(block) \
ut_a(my_atomic_addlint(&(block)->n_pointers, 0) == 0)
# define assert_block_ahi_empty_on_init(block) do { \
- UNIV_MEM_VALID(&(block)->n_pointers, sizeof (block)->n_pointers); \
+ MEM_MAKE_DEFINED(&(block)->n_pointers, sizeof (block)->n_pointers); \
assert_block_ahi_empty(block); \
} while (0)
# define assert_block_ahi_valid(block) \
@@ -1732,9 +1768,6 @@ struct buf_block_t{
# define assert_block_ahi_empty_on_init(block) /* nothing */
# define assert_block_ahi_valid(block) /* nothing */
#endif /* BTR_CUR_HASH_ADAPT */
- bool skip_flush_check;
- /*!< Skip check in buf_dblwr_check_block
- during bulk load, protected by lock.*/
# ifdef UNIV_DEBUG
/** @name Debug fields */
/* @{ */
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
index 98026159b8a..3df17e8a978 100644
--- a/storage/innobase/include/buf0buf.ic
+++ b/storage/innobase/include/buf0buf.ic
@@ -113,7 +113,17 @@ ulint
buf_pool_get_n_pages(void)
/*======================*/
{
- return(buf_pool_get_curr_size() / UNIV_PAGE_SIZE);
+ if (!buf_pool_ptr)
+ return buf_pool_get_curr_size() >> srv_page_size_shift;
+
+ ulint chunk_size= 0;
+ for (uint i= 0; i < srv_buf_pool_instances; i++)
+ {
+ buf_pool_t* buf_pool = buf_pool_from_array(i);
+ for (uint j= 0; j < buf_pool->n_chunks; j++)
+ chunk_size+= buf_pool->chunks[j].size;
+ }
+ return chunk_size;
}
/********************************************************************//**
@@ -814,7 +824,7 @@ buf_page_alloc_descriptor(void)
bpage = (buf_page_t*) ut_zalloc_nokey(sizeof *bpage);
ut_ad(bpage);
- UNIV_MEM_ALLOC(bpage, sizeof *bpage);
+ MEM_UNDEFINED(bpage, sizeof *bpage);
return(bpage);
}
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index 1efbb1f03ef..a72d98395af 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -49,17 +49,6 @@ These are low-level functions
/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
-#ifdef BTR_CUR_HASH_ADAPT
-struct dict_table_t;
-/** Try to drop the adaptive hash index for a tablespace.
-@param[in,out] table table
-@return whether anything was dropped */
-bool buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table)
- MY_ATTRIBUTE((warn_unused_result,nonnull));
-#else
-# define buf_LRU_drop_page_hash_for_tablespace(table)
-#endif /* BTR_CUR_HASH_ADAPT */
-
/** Empty the flush list for all pages belonging to a tablespace.
@param[in] id tablespace identifier
@param[in,out] observer flush observer,
diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h
index 33d03c8a2c9..fdf1a14feee 100644
--- a/storage/innobase/include/data0data.h
+++ b/storage/innobase/include/data0data.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2019, 2020 MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -32,6 +32,7 @@ Created 5/30/1994 Heikki Tuuri
#include "mem0mem.h"
#include "dict0types.h"
#include "btr0types.h"
+#include <vector>
#include <ostream>
@@ -510,9 +511,6 @@ struct dtuple_t {
dfield_t* fields; /*!< fields */
ulint n_v_fields; /*!< number of virtual fields */
dfield_t* v_fields; /*!< fields on virtual column */
- UT_LIST_NODE_T(dtuple_t) tuple_list;
- /*!< data tuples can be linked into a
- list using this field */
#ifdef UNIV_DEBUG
ulint magic_n; /*!< magic number, used in
debug assertions */
diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic
index 295c786a583..9b7a3132873 100644
--- a/storage/innobase/include/data0data.ic
+++ b/storage/innobase/include/data0data.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -50,10 +50,6 @@ dfield_set_len(
dfield_t* field, /*!< in: field */
ulint len) /*!< in: length or UNIV_SQL_NULL */
{
-#ifdef UNIV_VALGRIND_DEBUG
- if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(field->data, len);
-#endif /* UNIV_VALGRIND_DEBUG */
-
field->ext = 0;
field->len = static_cast<unsigned int>(len);
}
@@ -96,9 +92,6 @@ dfield_set_data(
const void* data, /*!< in: data */
ulint len) /*!< in: length or UNIV_SQL_NULL */
{
-#ifdef UNIV_VALGRIND_DEBUG
- if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
-#endif /* UNIV_VALGRIND_DEBUG */
field->data = (void*) data;
field->ext = 0;
field->len = static_cast<unsigned int>(len);
@@ -113,9 +106,7 @@ dfield_write_mbr(
dfield_t* field, /*!< in: field */
const double* mbr) /*!< in: data */
{
-#ifdef UNIV_VALGRIND_DEBUG
- if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
-#endif /* UNIV_VALGRIND_DEBUG */
+ MEM_CHECK_DEFINED(mbr, sizeof *mbr);
field->ext = 0;
for (unsigned i = 0; i < SPDIMS * 2; i++) {
@@ -177,7 +168,7 @@ dfield_dup(
mem_heap_t* heap) /*!< in: memory heap where allocated */
{
if (!dfield_is_null(field)) {
- UNIV_MEM_ASSERT_RW(field->data, field->len);
+ MEM_CHECK_DEFINED(field->data, field->len);
field->data = mem_heap_dup(heap, field->data, field->len);
}
}
@@ -334,8 +325,9 @@ dtuple_create_from_mem(
}
}
#endif
- UNIV_MEM_ASSERT_W(tuple->fields, n_t_fields * sizeof *tuple->fields);
- UNIV_MEM_INVALID(tuple->fields, n_t_fields * sizeof *tuple->fields);
+ MEM_CHECK_ADDRESSABLE(tuple->fields, n_t_fields
+ * sizeof *tuple->fields);
+ MEM_UNDEFINED(tuple->fields, n_t_fields * sizeof *tuple->fields);
return(tuple);
}
diff --git a/storage/innobase/include/dict0crea.h b/storage/innobase/include/dict0crea.h
index 7d87686e010..359d9f556e5 100644
--- a/storage/innobase/include/dict0crea.h
+++ b/storage/innobase/include/dict0crea.h
@@ -238,16 +238,6 @@ dict_replace_tablespace_in_dictionary(
const char* path,
trx_t* trx);
-/** Delete records from SYS_TABLESPACES and SYS_DATAFILES associated
-with a particular tablespace ID.
-@param[in] space Tablespace ID
-@param[in,out] trx Current transaction
-@return DB_SUCCESS if OK, dberr_t if the operation failed */
-dberr_t
-dict_delete_tablespace_and_datafiles(
- ulint space,
- trx_t* trx);
-
/********************************************************************//**
Add a foreign key definition to the data dictionary tables.
@return error code or DB_SUCCESS */
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 565ea77374d..49e884d064d 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -302,7 +302,7 @@ UNIV_INLINE
void
dict_table_autoinc_initialize(dict_table_t* table, ib_uint64_t value)
{
- ut_ad(dict_table_autoinc_own(table));
+ mysql_mutex_assert_owner(&table->autoinc_mutex);
table->autoinc = value;
}
@@ -315,7 +315,7 @@ UNIV_INLINE
ib_uint64_t
dict_table_autoinc_read(const dict_table_t* table)
{
- ut_ad(dict_table_autoinc_own(table));
+ mysql_mutex_assert_owner(&table->autoinc_mutex);
return(table->autoinc);
}
@@ -329,7 +329,7 @@ UNIV_INLINE
bool
dict_table_autoinc_update_if_greater(dict_table_t* table, ib_uint64_t value)
{
- ut_ad(dict_table_autoinc_own(table));
+ mysql_mutex_assert_owner(&table->autoinc_mutex);
if (value > table->autoinc) {
@@ -1524,25 +1524,6 @@ void
dict_mutex_exit_for_mysql(void);
/*===========================*/
-/** Create a dict_table_t's stats latch or delay for lazy creation.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to create
-@param[in] enabled if false then the latch is disabled
-and dict_table_stats_lock()/unlock() become noop on this table. */
-void
-dict_table_stats_latch_create(
- dict_table_t* table,
- bool enabled);
-
-/** Destroy a dict_table_t's stats latch.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to destroy */
-void
-dict_table_stats_latch_destroy(
- dict_table_t* table);
-
/** Lock the appropriate latch to protect a given table's statistics.
@param[in] table table whose stats to lock
@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index bb77bb7e6e6..3b68e113aa5 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -862,16 +862,18 @@ dict_table_x_lock_indexes(
/*======================*/
dict_table_t* table) /*!< in: table */
{
- dict_index_t* index;
-
ut_ad(mutex_own(&dict_sys->mutex));
+ dict_index_t* clust_index = dict_table_get_first_index(table);
+
/* Loop through each index of the table and lock them */
- for (index = dict_table_get_first_index(table);
+ for (dict_index_t* index = dict_table_get_next_index(clust_index);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
}
+
+ rw_lock_x_lock(dict_index_get_lock(clust_index));
}
/*********************************************************************//**
diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
index 79440533ab2..b288c0b337a 100644
--- a/storage/innobase/include/dict0load.h
+++ b/storage/innobase/include/dict0load.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -88,14 +88,6 @@ dict_get_first_table_name_in_db(
/*============================*/
const char* name); /*!< in: database name which ends to '/' */
-/** Get the first filepath from SYS_DATAFILES for a given space_id.
-@param[in] space_id Tablespace ID
-@return First filepath (caller must invoke ut_free() on it)
-@retval NULL if no SYS_DATAFILES entry was found. */
-char*
-dict_get_first_path(
- ulint space_id);
-
/** Make sure the data_file_name is saved in dict_table_t if needed.
Try to read it from the fil_system first, then from SYS_DATAFILES.
@param[in] table Table object
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 0f96cd4e3ba..3c7913d7f39 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -44,7 +44,6 @@ Created 1/8/1996 Heikki Tuuri
#include "fts0fts.h"
#include "buf0buf.h"
#include "gis0type.h"
-#include "os0once.h"
#include "fil0fil.h"
#include <my_crypt.h>
#include "fil0crypt.h"
@@ -299,29 +298,27 @@ parent table will fail, and user has to drop excessive foreign constraint
before proceeds. */
#define FK_MAX_CASCADE_DEL 15
-/**********************************************************************//**
-Creates a table memory object.
+/** Creates a table memory object.
+@param[in] name table name
+@param[in] space space where the clustered index
+ of the table is placed
+@param[in] n_cols total number of columns including
+ virtual and non-virtual columns
+@param[in] n_v_cols number of virtual columns
+@param[in] flags table flags
+@param[in] flags2 table flags2
+@param[in] init_stats_latch whether to init the stats latch
@return own: table object */
dict_table_t*
dict_mem_table_create(
-/*==================*/
- const char* name, /*!< in: table name */
- ulint space, /*!< in: space where the clustered index
- of the table is placed */
- ulint n_cols, /*!< in: total number of columns
- including virtual and non-virtual
- columns */
- ulint n_v_cols, /*!< in: number of virtual columns */
- ulint flags, /*!< in: table flags */
- ulint flags2); /*!< in: table flags2 */
-/**********************************************************************//**
-Determines if a table belongs to a system database
-@return */
-UNIV_INTERN
-bool
-dict_mem_table_is_system(
-/*==================*/
- char *name); /*!< in: table name */
+ const char* name,
+ ulint space,
+ ulint n_cols,
+ ulint n_v_cols,
+ ulint flags,
+ ulint flags2,
+ bool init_stats_latch=true);
+
/****************************************************************//**
Free a table memory object. */
void
@@ -634,12 +631,12 @@ struct dict_col_t{
this column. Our current max limit is
3072 for Barracuda table */
- /** @return whether this is a virtual column */
- bool is_virtual() const { return prtype & DATA_VIRTUAL; }
+ /** @return whether this is a virtual column */
+ bool is_virtual() const { return prtype & DATA_VIRTUAL; }
- /** Detach the column from an index.
- @param[in] index index to be detached from */
- inline void detach(const dict_index_t& index);
+ /** Detach a virtual column from an index.
+ @param index being-freed index */
+ inline void detach(const dict_index_t &index);
};
/** Index information put in a list of virtual column structure. Index
@@ -800,7 +797,7 @@ extern ulong zip_pad_max;
an uncompressed page should be left as padding to avoid compression
failures. This estimate is based on a self-adapting heuristic. */
struct zip_pad_info_t {
- SysMutex* mutex; /*!< mutex protecting the info */
+ mysql_mutex_t mutex; /*!< mutex protecting the info */
ulint pad; /*!< number of bytes used as pad */
ulint success;/*!< successful compression ops during
current round */
@@ -808,9 +805,6 @@ struct zip_pad_info_t {
current round */
ulint n_rounds;/*!< number of currently successful
rounds */
- volatile os_once::state_t
- mutex_created;
- /*!< Creation state of mutex member */
};
/** Number of samples of data size kept when page compression fails for
@@ -821,10 +815,6 @@ a certain index.*/
system clustered index when there is no primary key. */
const char innobase_index_reserve_name[] = "GEN_CLUST_INDEX";
-/* Estimated number of offsets in records (based on columns)
-to start with. */
-#define OFFS_IN_REC_NORMAL_SIZE 100
-
/** Data structure for an index. Most fields will be
initialized to 0, NULL or FALSE in dict_mem_index_create(). */
struct dict_index_t{
@@ -835,6 +825,9 @@ struct dict_index_t{
dict_table_t* table; /*!< back pointer to table */
unsigned space:32;
/*!< space where the index tree is placed */
+ /** root page number, or FIL_NULL if the index has been detached
+ from storage (DISCARD TABLESPACE or similar),
+ or 1 if the index is in table->freed_indexes */
unsigned page:32;/*!< index tree root page number */
unsigned merge_threshold:6;
/*!< In the pessimistic delete, if the page
@@ -968,7 +961,8 @@ struct dict_index_t{
/* in which slot the next sample should be
saved. */
/* @} */
- rtr_ssn_t rtr_ssn;/*!< Node sequence number for RTree */
+ /** R-tree split sequence number */
+ volatile int32 rtr_ssn;
rtr_info_track_t*
rtr_track;/*!< tracking all R-Tree search cursors */
trx_id_t trx_id; /*!< id of the transaction that created this
@@ -1014,20 +1008,61 @@ struct dict_index_t{
/** @return whether the index includes virtual columns */
bool has_virtual() const { return type & DICT_VIRTUAL; }
+ /** @return the position of DB_TRX_ID */
+ uint16_t db_trx_id() const {
+ DBUG_ASSERT(is_primary());
+ DBUG_ASSERT(n_uniq);
+ return n_uniq;
+ }
+ /** @return the position of DB_ROLL_PTR */
+ uint16_t db_roll_ptr() const
+ {
+ return static_cast<uint16_t>(db_trx_id() + 1);
+ }
+
+ /** @return the offset of the metadata BLOB field,
+ or the first user field after the PRIMARY KEY,DB_TRX_ID,DB_ROLL_PTR */
+ uint16_t first_user_field() const
+ {
+ return static_cast<uint16_t>(db_trx_id() + 2);
+ }
+
/** @return whether the index is corrupted */
inline bool is_corrupted() const;
- /** Detach the columns from the index that is to be freed. */
- void detach_columns()
- {
- if (has_virtual()) {
- for (unsigned i = 0; i < n_fields; i++) {
- fields[i].col->detach(*this);
- }
+ /** Detach the virtual columns from the index that is to be removed.
+ @param whether to reset fields[].col */
+ void detach_columns(bool clear= false)
+ {
+ if (!has_virtual())
+ return;
+ for (unsigned i= 0; i < n_fields; i++)
+ {
+ dict_col_t* col= fields[i].col;
+ if (!col || !col->is_virtual())
+ continue;
+ col->detach(*this);
+ if (clear)
+ fields[i].col= NULL;
+ }
+ }
+
+ /** @return whether this is the change buffer */
+ bool is_ibuf() const { return UNIV_UNLIKELY(type & DICT_IBUF); }
- n_fields = 0;
- }
- }
+#ifdef BTR_CUR_HASH_ADAPT
+ /** @return a clone of this */
+ dict_index_t* clone() const;
+ /** Clone this index for lazy dropping of the adaptive hash index.
+ @return this or a clone */
+ dict_index_t* clone_if_needed();
+ /** @return number of leaf pages pointed to by the adaptive hash index */
+ inline ulint n_ahi_pages() const;
+ /** @return whether mark_freed() had been invoked */
+ bool freed() const { return UNIV_UNLIKELY(page == 1); }
+ /** Note that the index is waiting for btr_search_lazy_free() */
+ void set_freed() { ut_ad(!freed()); page= 1; }
+#endif /* BTR_CUR_HASH_ADAPT */
/** This ad-hoc class is used by record_size_info only. */
class record_size_info_t {
@@ -1090,24 +1125,24 @@ struct dict_index_t{
inline record_size_info_t record_size_info() const;
};
-/** Detach a column from an index.
-@param[in] index index to be detached from */
-inline void dict_col_t::detach(const dict_index_t& index)
+/** Detach a virtual column from an index.
+@param index being-freed index */
+inline void dict_col_t::detach(const dict_index_t &index)
{
- if (!is_virtual()) {
- return;
- }
-
- if (dict_v_idx_list* v_indexes = reinterpret_cast<const dict_v_col_t*>
- (this)->v_indexes) {
- for (dict_v_idx_list::iterator i = v_indexes->begin();
- i != v_indexes->end(); i++) {
- if (i->index == &index) {
- v_indexes->erase(i);
- return;
- }
- }
- }
+ ut_ad(is_virtual());
+
+ if (dict_v_idx_list *v_indexes= reinterpret_cast<const dict_v_col_t*>(this)
+ ->v_indexes)
+ {
+ for (dict_v_idx_list::iterator i= v_indexes->begin();
+ i != v_indexes->end(); i++)
+ {
+ if (i->index == &index) {
+ v_indexes->erase(i);
+ return;
+ }
+ }
+ }
}
/** The status of online index creation */
@@ -1173,6 +1208,10 @@ struct dict_foreign_t{
dict_vcol_set* v_cols; /*!< set of virtual columns affected
by foreign key constraint. */
+
+ /** Check whether the fulltext index gets affected by
+ foreign key constraint */
+ bool affects_fulltext() const;
};
std::ostream&
@@ -1608,6 +1647,11 @@ struct dict_table_t {
/** List of indexes of the table. */
UT_LIST_BASE_NODE_T(dict_index_t) indexes;
+#ifdef BTR_CUR_HASH_ADAPT
+ /** List of detached indexes that are waiting to be freed along with
+ the last adaptive hash index entry */
+ UT_LIST_BASE_NODE_T(dict_index_t) freed_indexes;
+#endif /* BTR_CUR_HASH_ADAPT */
/** List of foreign key constraints in the table. These refer to
columns in other tables. */
@@ -1650,7 +1694,7 @@ struct dict_table_t {
/** Statistics for query optimization. @{ */
/** Creation state of 'stats_latch'. */
- volatile os_once::state_t stats_latch_created;
+ bool stats_latch_inited;
/** This latch protects:
dict_table_t::stat_initialized,
@@ -1663,7 +1707,7 @@ struct dict_table_t {
dict_table_t::indexes*::stat_n_leaf_pages.
(*) Those are not always protected for
performance reasons. */
- rw_lock_t* stats_latch;
+ rw_lock_t stats_latch;
/** TRUE if statistics have been calculated the first time after
database startup or table creation. */
@@ -1787,11 +1831,8 @@ struct dict_table_t {
from a select. */
lock_t* autoinc_lock;
- /** Creation state of autoinc_mutex member */
- volatile os_once::state_t autoinc_mutex_created;
-
/** Mutex protecting the autoincrement counter. */
- ib_mutex_t* autoinc_mutex;
+ mysql_mutex_t autoinc_mutex;
/** Autoinc counter value to give to the next inserted row. */
ib_uint64_t autoinc;
@@ -1885,64 +1926,6 @@ struct dict_foreign_add_to_referenced_table {
}
};
-/** Destroy the autoinc latch of the given table.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to destroy */
-inline
-void
-dict_table_autoinc_destroy(
- dict_table_t* table)
-{
- if (table->autoinc_mutex_created == os_once::DONE
- && table->autoinc_mutex != NULL) {
- mutex_free(table->autoinc_mutex);
- UT_DELETE(table->autoinc_mutex);
- }
-}
-
-/** Request for lazy creation of the autoinc latch of a given table.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose autoinc latch is to be created. */
-inline
-void
-dict_table_autoinc_create_lazy(
- dict_table_t* table)
-{
- table->autoinc_mutex = NULL;
- table->autoinc_mutex_created = os_once::NEVER_DONE;
-}
-
-/** Request a lazy creation of dict_index_t::zip_pad::mutex.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] index index whose zip_pad mutex is to be created */
-inline
-void
-dict_index_zip_pad_mutex_create_lazy(
- dict_index_t* index)
-{
- index->zip_pad.mutex = NULL;
- index->zip_pad.mutex_created = os_once::NEVER_DONE;
-}
-
-/** Destroy the zip_pad_mutex of the given index.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to destroy */
-inline
-void
-dict_index_zip_pad_mutex_destroy(
- dict_index_t* index)
-{
- if (index->zip_pad.mutex_created == os_once::DONE
- && index->zip_pad.mutex != NULL) {
- mutex_free(index->zip_pad.mutex);
- UT_DELETE(index->zip_pad.mutex);
- }
-}
-
/** Release the zip_pad_mutex of a given index.
@param[in,out] index index whose zip_pad_mutex is to be released */
inline
@@ -1950,22 +1933,9 @@ void
dict_index_zip_pad_unlock(
dict_index_t* index)
{
- mutex_exit(index->zip_pad.mutex);
+ mysql_mutex_unlock(&index->zip_pad.mutex);
}
-#ifdef UNIV_DEBUG
-/** Check if the current thread owns the autoinc_mutex of a given table.
-@param[in] table the autoinc_mutex belongs to this table
-@return true, if the current thread owns the autoinc_mutex, false otherwise.*/
-inline
-bool
-dict_table_autoinc_own(
- const dict_table_t* table)
-{
- return(mutex_own(table->autoinc_mutex));
-}
-#endif /* UNIV_DEBUG */
-
/** Check whether the col is used in spatial index or regular index.
@param[in] col column to check
@return spatial status */
diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h
index 98956412ae2..00ac6eb4745 100644
--- a/storage/innobase/include/dict0stats.h
+++ b/storage/innobase/include/dict0stats.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2009, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -115,16 +115,16 @@ dict_stats_deinit(
/** Update the table modification counter and if necessary,
schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table
-@param[in] thd current session */
-void dict_stats_update_if_needed(dict_table_t* table, THD* thd)
- MY_ATTRIBUTE((nonnull(1)));
+@param[in] trx transaction */
+void dict_stats_update_if_needed(dict_table_t *table, const trx_t &trx)
+ MY_ATTRIBUTE((nonnull));
#else
/** Update the table modification counter and if necessary,
schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table */
-void dict_stats_update_if_needed_func(dict_table_t* table)
+void dict_stats_update_if_needed_func(dict_table_t *table)
MY_ATTRIBUTE((nonnull));
-# define dict_stats_update_if_needed(t,thd) dict_stats_update_if_needed_func(t)
+# define dict_stats_update_if_needed(t,trx) dict_stats_update_if_needed_func(t)
#endif
/*********************************************************************//**
diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic
index 31065d15c45..98024935e16 100644
--- a/storage/innobase/include/dict0stats.ic
+++ b/storage/innobase/include/dict0stats.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -187,41 +187,40 @@ dict_stats_deinit(
table->stat_initialized = FALSE;
-#ifdef UNIV_DEBUG_VALGRIND
- UNIV_MEM_INVALID(&table->stat_n_rows,
- sizeof(table->stat_n_rows));
- UNIV_MEM_INVALID(&table->stat_clustered_index_size,
- sizeof(table->stat_clustered_index_size));
- UNIV_MEM_INVALID(&table->stat_sum_of_other_index_sizes,
- sizeof(table->stat_sum_of_other_index_sizes));
- UNIV_MEM_INVALID(&table->stat_modified_counter,
- sizeof(table->stat_modified_counter));
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&table->stat_n_rows, sizeof table->stat_n_rows);
+ MEM_UNDEFINED(&table->stat_clustered_index_size,
+ sizeof table->stat_clustered_index_size);
+ MEM_UNDEFINED(&table->stat_sum_of_other_index_sizes,
+ sizeof table->stat_sum_of_other_index_sizes);
+ MEM_UNDEFINED(&table->stat_modified_counter,
+ sizeof table->stat_modified_counter);
dict_index_t* index;
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
-
- ulint n_uniq = dict_index_get_n_unique(index);
-
- UNIV_MEM_INVALID(
+ MEM_UNDEFINED(
index->stat_n_diff_key_vals,
- n_uniq * sizeof(index->stat_n_diff_key_vals[0]));
- UNIV_MEM_INVALID(
+ index->n_uniq
+ * sizeof(index->stat_n_diff_key_vals[0]));
+ MEM_UNDEFINED(
index->stat_n_sample_sizes,
- n_uniq * sizeof(index->stat_n_sample_sizes[0]));
- UNIV_MEM_INVALID(
+ index->n_uniq
+ * sizeof(index->stat_n_sample_sizes[0]));
+ MEM_UNDEFINED(
index->stat_n_non_null_key_vals,
- n_uniq * sizeof(index->stat_n_non_null_key_vals[0]));
- UNIV_MEM_INVALID(
+ index->n_uniq
+ * sizeof(index->stat_n_non_null_key_vals[0]));
+ MEM_UNDEFINED(
&index->stat_index_size,
sizeof(index->stat_index_size));
- UNIV_MEM_INVALID(
+ MEM_UNDEFINED(
&index->stat_n_leaf_pages,
sizeof(index->stat_n_leaf_pages));
}
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
dict_table_stats_unlock(table, RW_X_LATCH);
}
diff --git a/storage/innobase/include/dyn0buf.h b/storage/innobase/include/dyn0buf.h
index a7a8e1dea1e..b3302409e5f 100644
--- a/storage/innobase/include/dyn0buf.h
+++ b/storage/innobase/include/dyn0buf.h
@@ -29,7 +29,8 @@ Created 2013-03-16 Sunny Bains
#include "mem0mem.h"
#include "dyn0types.h"
-#include "ut0lst.h"
+#include "ilist.h"
+
/** Class that manages dynamic buffers. It uses a UT_LIST of
dyn_buf_t::block_t instances. We don't use STL containers in
@@ -42,12 +43,7 @@ template <size_t SIZE = DYN_ARRAY_DATA_SIZE>
class dyn_buf_t {
public:
- class block_t;
-
- typedef UT_LIST_NODE_T(block_t) block_node_t;
- typedef UT_LIST_BASE_NODE_T(block_t) block_list_t;
-
- class block_t {
+ class block_t : public ilist_node<> {
public:
block_t()
@@ -157,16 +153,13 @@ public:
/** SIZE - sizeof(m_node) + sizeof(m_used) */
enum {
MAX_DATA_SIZE = SIZE
- - sizeof(block_node_t)
+ - sizeof(ilist_node<>)
+ sizeof(ib_uint32_t)
};
/** Storage */
byte m_data[MAX_DATA_SIZE];
- /** Doubly linked list node. */
- block_node_t m_node;
-
/** number of data bytes used in this block;
DYN_BLOCK_FULL_FLAG is set when the block becomes full */
ib_uint32_t m_used;
@@ -174,6 +167,8 @@ public:
friend class dyn_buf_t;
};
+ typedef sized_ilist<block_t> list_t;
+
enum { MAX_DATA_SIZE = block_t::MAX_DATA_SIZE};
/** Default constructor */
@@ -182,7 +177,6 @@ public:
m_heap(),
m_size()
{
- UT_LIST_INIT(m_list, &block_t::m_node);
push_back(&m_first_block);
}
@@ -200,11 +194,11 @@ public:
m_heap = NULL;
/* Initialise the list and add the first block. */
- UT_LIST_INIT(m_list, &block_t::m_node);
- push_back(&m_first_block);
+ m_list.clear();
+ m_list.push_back(m_first_block);
} else {
m_first_block.init();
- ut_ad(UT_LIST_GET_LEN(m_list) == 1);
+ ut_ad(m_list.size() == 1);
}
m_size = 0;
@@ -236,7 +230,7 @@ public:
@param ptr end of used space */
void close(const byte* ptr)
{
- ut_ad(UT_LIST_GET_LEN(m_list) > 0);
+ ut_ad(!m_list.empty());
block_t* block = back();
m_size -= block->used();
@@ -324,11 +318,10 @@ public:
#ifdef UNIV_DEBUG
ulint total_size = 0;
- for (const block_t* block = UT_LIST_GET_FIRST(m_list);
- block != NULL;
- block = UT_LIST_GET_NEXT(m_node, block)) {
-
- total_size += block->used();
+ for (typename list_t::iterator it = m_list.begin(),
+ end = m_list.end();
+ it != end; ++it) {
+ total_size += it->used();
}
ut_ad(total_size == m_size);
@@ -342,12 +335,12 @@ public:
template <typename Functor>
bool for_each_block(Functor& functor) const
{
- for (const block_t* block = UT_LIST_GET_FIRST(m_list);
- block != NULL;
- block = UT_LIST_GET_NEXT(m_node, block)) {
+ for (typename list_t::iterator it = m_list.begin(),
+ end = m_list.end();
+ it != end; ++it) {
- if (!functor(block)) {
- return(false);
+ if (!functor(&*it)) {
+ return false;
}
}
@@ -360,12 +353,12 @@ public:
template <typename Functor>
bool for_each_block_in_reverse(Functor& functor) const
{
- for (block_t* block = UT_LIST_GET_LAST(m_list);
- block != NULL;
- block = UT_LIST_GET_PREV(m_node, block)) {
+ for (typename list_t::reverse_iterator it = m_list.rbegin(),
+ end = m_list.rend();
+ it != end; ++it) {
- if (!functor(block)) {
- return(false);
+ if (!functor(&*it)) {
+ return false;
}
}
@@ -378,12 +371,12 @@ public:
template <typename Functor>
bool for_each_block_in_reverse(const Functor& functor) const
{
- for (block_t* block = UT_LIST_GET_LAST(m_list);
- block != NULL;
- block = UT_LIST_GET_PREV(m_node, block)) {
+ for (typename list_t::reverse_iterator it = m_list.rbegin(),
+ end = m_list.rend();
+ it != end; ++it) {
- if (!functor(block)) {
- return(false);
+ if (!functor(&*it)) {
+ return false;
}
}
@@ -395,8 +388,7 @@ public:
block_t* front()
MY_ATTRIBUTE((warn_unused_result))
{
- ut_ad(UT_LIST_GET_LEN(m_list) > 0);
- return(UT_LIST_GET_FIRST(m_list));
+ return &m_list.front();
}
/**
@@ -417,14 +409,13 @@ private:
void push_back(block_t* block)
{
block->init();
-
- UT_LIST_ADD_LAST(m_list, block);
+ m_list.push_back(*block);
}
/** @return the last block in the list */
block_t* back()
{
- return(UT_LIST_GET_LAST(m_list));
+ return &m_list.back();
}
/*
@@ -447,25 +438,22 @@ private:
@return the block containing the pos. */
block_t* find(ulint& pos)
{
- block_t* block;
+ ut_ad(!m_list.empty());
- ut_ad(UT_LIST_GET_LEN(m_list) > 0);
+ for (typename list_t::iterator it = m_list.begin(),
+ end = m_list.end();
+ it != end; ++it) {
- for (block = UT_LIST_GET_FIRST(m_list);
- block != NULL;
- block = UT_LIST_GET_NEXT(m_node, block)) {
+ if (pos < it->used()) {
+ ut_ad(it->used() >= pos);
- if (pos < block->used()) {
- break;
+ return &*it;
}
- pos -= block->used();
+ pos -= it->used();
}
- ut_ad(block != NULL);
- ut_ad(block->used() >= pos);
-
- return(block);
+ return NULL;
}
/**
@@ -491,7 +479,7 @@ private:
mem_heap_t* m_heap;
/** Allocated blocks */
- block_list_t m_list;
+ list_t m_list;
/** Total size used by all blocks */
ulint m_size;
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 386f574a59f..65457b414ca 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -33,9 +33,13 @@ Created 10/25/1995 Heikki Tuuri
#include "dict0types.h"
#include "page0size.h"
#include "ibuf0types.h"
+#include "ilist.h"
#include <list>
+struct unflushed_spaces_tag_t;
+struct rotation_list_tag_t;
+
// Forward declaration
extern ibool srv_use_doublewrite_buf;
extern struct buf_dblwr_t* buf_dblwr;
@@ -78,7 +82,9 @@ fil_type_is_data(
struct fil_node_t;
/** Tablespace or log data space */
-struct fil_space_t {
+struct fil_space_t : ilist_node<unflushed_spaces_tag_t>,
+ ilist_node<rotation_list_tag_t>
+{
ulint id; /*!< space id */
hash_node_t hash; /*!< hash chain node */
char* name; /*!< Tablespace name */
@@ -129,6 +135,8 @@ struct fil_space_t {
/*!< recovered tablespace size in pages;
0 if no size change was read from the redo log,
or if the size change was implemented */
+ /** the committed size of the tablespace in pages */
+ ulint committed_size;
ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
see fsp0types.h,
fsp_flags_is_valid(),
@@ -156,26 +164,21 @@ struct fil_space_t {
ulint n_pending_ios;
rw_lock_t latch; /*!< latch protecting the file space storage
allocation */
- UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
- /*!< list of spaces with at least one unflushed
- file we have written to */
UT_LIST_NODE_T(fil_space_t) named_spaces;
/*!< list of spaces for which MLOG_FILE_NAME
records have been issued */
- /** Checks that this tablespace in a list of unflushed tablespaces.
- @return true if in a list */
- bool is_in_unflushed_spaces() const;
UT_LIST_NODE_T(fil_space_t) space_list;
/*!< list of all spaces */
- /** other tablespaces needing key rotation */
- UT_LIST_NODE_T(fil_space_t) rotation_list;
- /** Checks that this tablespace needs key rotation.
- @return true if in a rotation list */
- bool is_in_rotation_list() const;
/** MariaDB encryption data */
fil_space_crypt_t* crypt_data;
+ /** Checks that this tablespace in a list of unflushed tablespaces. */
+ bool is_in_unflushed_spaces;
+
+ /** Checks that this tablespace needs key rotation. */
+ bool is_in_rotation_list;
+
/** True if the device this filespace is on supports atomic writes */
bool atomic_write_supported;
@@ -192,6 +195,15 @@ struct fil_space_t {
/** @return whether the tablespace is about to be dropped */
bool is_stopping() const { return stop_new_ops; }
+ /** Clamp a page number for batched I/O, such as read-ahead.
+ @param offset page number limit
+ @return offset clamped to the tablespace size */
+ ulint max_page_number_for_io(ulint offset) const
+ {
+ const ulint limit= committed_size;
+ return limit > offset ? offset : limit;
+ }
+
/** @return whether doublewrite buffering is needed */
bool use_doublewrite() const
{
@@ -484,6 +496,11 @@ fil_space_get(
data space) is stored here; below we talk about tablespaces, but also
the ib_logfiles form a 'space' and it is handled here */
struct fil_system_t {
+ fil_system_t()
+ : n_open(0), max_assigned_id(0), space_id_reuse_warned(false)
+ {
+ }
+
ib_mutex_t mutex; /*!< The mutex protecting the cache */
hash_table_t* spaces; /*!< The hash table of spaces in the
system; they are hashed on the space
@@ -501,8 +518,8 @@ struct fil_system_t {
not put to this list: they are opened
after the startup, and kept open until
shutdown */
- UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
- /*!< base node for the list of those
+ sized_ilist<fil_space_t, unflushed_spaces_tag_t> unflushed_spaces;
+ /*!< list of those
tablespaces whose files contain
unflushed writes; those spaces have
at least one file node where
@@ -524,11 +541,11 @@ struct fil_system_t {
record has been written since
the latest redo log checkpoint.
Protected only by log_sys->mutex. */
- UT_LIST_BASE_NODE_T(fil_space_t) rotation_list;
+ ilist<fil_space_t, rotation_list_tag_t> rotation_list;
/*!< list of all file spaces needing
key rotation.*/
- ibool space_id_reuse_warned;
+ bool space_id_reuse_warned;
/* !< TRUE if fil_space_create()
has issued a warning about
potential space_id reuse */
@@ -539,24 +556,15 @@ struct fil_system_t {
@retval NULL if the tablespace does not exist or cannot be read */
fil_space_t* read_page0(ulint id);
- /** Return the next fil_space_t from key rotation list.
- Once started, the caller must keep calling this until it returns NULL.
- fil_space_acquire() and fil_space_release() are invoked here which
- blocks a concurrent operation from dropping the tablespace.
- @param[in] prev_space Previous tablespace or NULL to start
- from beginning of fil_system->rotation
- list
- @param[in] recheck recheck of the tablespace is needed or
- still encryption thread does write page0
- for it
- @param[in] key_version key version of the key state thread
- If NULL, use the first fil_space_t on fil_system->space_list.
- @return pointer to the next fil_space_t.
- @retval NULL if this was the last */
- fil_space_t* keyrotate_next(
- fil_space_t* prev_space,
- bool remove,
- uint key_version);
+ /** Return the next tablespace from rotation_list.
+ @param space previous tablespace (NULL to start from the start)
+ @param recheck whether the removal condition needs to be rechecked after
+ the encryption parameters were changed
+ @param encrypt expected state of innodb_encrypt_tables
+ @return the next tablespace to process (n_pending_ops incremented)
+ @retval NULL if this was the last */
+ inline fil_space_t* keyrotate_next(fil_space_t *space, bool recheck,
+ bool encrypt);
};
/** The tablespace memory cache. This variable is NULL before the module is
@@ -565,15 +573,6 @@ extern fil_system_t* fil_system;
#include "fil0crypt.h"
-/** Returns the latch of a file space.
-@param[in] id space id
-@param[out] flags tablespace flags
-@return latch protecting storage allocation */
-rw_lock_t*
-fil_space_get_latch(
- ulint id,
- ulint* flags);
-
/** Gets the type of a file space.
@param[in] id tablespace identifier
@return file type */
@@ -795,34 +794,6 @@ fil_space_acquire_for_io(ulint id);
void
fil_space_release_for_io(fil_space_t* space);
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last */
-fil_space_t*
-fil_space_next(
- fil_space_t* prev_space)
- MY_ATTRIBUTE((warn_unused_result));
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Previous tablespace or NULL to start
- from beginning of fil_system->rotation list
-@param[in] remove Whether to remove the previous tablespace from
- the rotation list
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-fil_space_t*
-fil_space_keyrotate_next(fil_space_t* prev_space, bool remove)
- MY_ATTRIBUTE((warn_unused_result));
-
/** Wrapper with reference-counting for a fil_space_t. */
class FilSpace
{
@@ -958,14 +929,9 @@ bool fil_table_accessible(const dict_table_t* table)
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
+@param[in] if_exists whether to ignore missing tablespace
@return DB_SUCCESS or error */
-dberr_t
-fil_delete_tablespace(
- ulint id
-#ifdef BTR_CUR_HASH_ADAPT
- , bool drop_ahi = false /*!< whether to drop the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
- );
+dberr_t fil_delete_tablespace(ulint id, bool if_exists= false);
/** Prepare to truncate an undo tablespace.
@param[in] space_id undo tablespace id
@@ -1383,18 +1349,6 @@ ulint
fil_space_get_id_by_name(
const char* tablespace);
-/**
-Iterate over all the spaces in the space list and fetch the
-tablespace names. It will return a copy of the name that must be
-freed by the caller using: delete[].
-@return DB_SUCCESS if all OK. */
-dberr_t
-fil_get_space_names(
-/*================*/
- space_name_list_t& space_name_list)
- /*!< in/out: Vector for collecting the names. */
- MY_ATTRIBUTE((warn_unused_result));
-
/** Generate redo log for swapping two .ibd files
@param[in] old_table old table
@param[in] new_table new table
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index a4e3b84b55e..a50be6f8998 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -407,42 +407,52 @@ fsp_header_inc_size(
ulint space_id, /*!< in: space id */
ulint size_inc, /*!< in: size increment in pages */
mtr_t* mtr); /*!< in/out: mini-transaction */
-/**********************************************************************//**
-Creates a new segment.
+
+/** Creates a new segment.
+@param[in] space space id
+@param[in] byte_offset byte offset of the created segment header
+ on the page
+@param[in,out] mtr mini-transaction
+@param[in,out] block block where segment header is placed;
+ If it is null then new page will be
+ allocated and it will belong to
+ the created segment
@return the block where the segment header is placed, x-latched, NULL
if could not create segment because of lack of space */
buf_block_t*
fseg_create(
-/*========*/
- ulint space_id,/*!< in: space id */
- ulint page, /*!< in: page where the segment header is placed: if
- this is != 0, the page must belong to another segment,
- if this is 0, a new page will be allocated and it
- will belong to the created segment */
- ulint byte_offset, /*!< in: byte offset of the created segment header
- on the page */
- mtr_t* mtr); /*!< in/out: mini-transaction */
-/**********************************************************************//**
-Creates a new segment.
+ ulint space,
+ ulint byte_offset,
+ mtr_t* mtr,
+ buf_block_t* block=NULL);
+
+/** Creates a new segment.
+@param[in] space_id space_id
+@param[in] byte_offset byte offset of the created segment
+ header on the page
+@param[in] has_done_reservation TRUE if the caller has already
+ done the reservation for the pages
+ with fsp_reserve_free_externts
+ (at least 2 extents: one for
+ the inode and the other for the
+ segment) then there is no need to do
+ the check for this individual
+ operation
+@param[in,out] mtr mini-transaction
+@param[in] block block where the segment header is
+ placed. If it is null then new page
+ will be allocated and it will belong
+ to the created segment
@return the block where the segment header is placed, x-latched, NULL
if could not create segment because of lack of space */
buf_block_t*
fseg_create_general(
-/*================*/
- ulint space_id,/*!< in: space id */
- ulint page, /*!< in: page where the segment header is placed: if
- this is != 0, the page must belong to another segment,
- if this is 0, a new page will be allocated and it
- will belong to the created segment */
- ulint byte_offset, /*!< in: byte offset of the created segment header
- on the page */
- ibool has_done_reservation, /*!< in: TRUE if the caller has already
- done the reservation for the pages with
- fsp_reserve_free_extents (at least 2 extents: one for
- the inode and the other for the segment) then there is
- no need to do the check for this individual
- operation */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+ ulint space_id,
+ ulint byte_offset,
+ ibool has_done_reservation,
+ mtr_t* mtr,
+ buf_block_t* block);
+
/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
currently used.
@@ -568,22 +578,11 @@ fsp_get_available_space_in_free_extents(
/**********************************************************************//**
Frees a single page of a segment. */
void
-fseg_free_page_func(
+fseg_free_page(
fseg_header_t* seg_header, /*!< in: segment header */
ulint space_id, /*!< in: space id */
ulint page, /*!< in: page offset */
-#ifdef BTR_CUR_HASH_ADAPT
- bool ahi, /*!< in: whether we may need to drop
- the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr); /*!< in/out: mini-transaction */
-#ifdef BTR_CUR_HASH_ADAPT
-# define fseg_free_page(header, space_id, page, ahi, mtr) \
- fseg_free_page_func(header, space_id, page, ahi, mtr)
-#else /* BTR_CUR_HASH_ADAPT */
-# define fseg_free_page(header, space_id, page, ahi, mtr) \
- fseg_free_page_func(header, space_id, page, mtr)
-#endif /* BTR_CUR_HASH_ADAPT */
/** Determine whether a page is free.
@param[in,out] space tablespace
@param[in] page page number
@@ -596,45 +595,25 @@ Frees part of a segment. This function can be used to free a segment
by repeatedly calling this function in different mini-transactions.
Doing the freeing in a single mini-transaction might result in
too big a mini-transaction.
-@return TRUE if freeing completed */
-ibool
-fseg_free_step_func(
+@return whether the freeing was completed */
+bool
+fseg_free_step(
fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
resides on the first page of the frag list
of the segment, this pointer becomes obsolete
after the last freeing step */
-#ifdef BTR_CUR_HASH_ADAPT
- bool ahi, /*!< in: whether we may need to drop
- the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr) /*!< in/out: mini-transaction */
MY_ATTRIBUTE((warn_unused_result));
-#ifdef BTR_CUR_HASH_ADAPT
-# define fseg_free_step(header, ahi, mtr) fseg_free_step_func(header, ahi, mtr)
-#else /* BTR_CUR_HASH_ADAPT */
-# define fseg_free_step(header, ahi, mtr) fseg_free_step_func(header, mtr)
-#endif /* BTR_CUR_HASH_ADAPT */
/**********************************************************************//**
Frees part of a segment. Differs from fseg_free_step because this function
leaves the header page unfreed.
-@return TRUE if freeing completed, except the header page */
-ibool
-fseg_free_step_not_header_func(
+@return whether the freeing was completed, except for the header page */
+bool
+fseg_free_step_not_header(
fseg_header_t* header, /*!< in: segment header which must reside on
the first fragment page of the segment */
-#ifdef BTR_CUR_HASH_ADAPT
- bool ahi, /*!< in: whether we may need to drop
- the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr) /*!< in/out: mini-transaction */
MY_ATTRIBUTE((warn_unused_result));
-#ifdef BTR_CUR_HASH_ADAPT
-# define fseg_free_step_not_header(header, ahi, mtr) \
- fseg_free_step_not_header_func(header, ahi, mtr)
-#else /* BTR_CUR_HASH_ADAPT */
-# define fseg_free_step_not_header(header, ahi, mtr) \
- fseg_free_step_not_header_func(header, mtr)
-#endif /* BTR_CUR_HASH_ADAPT */
/** Reset the page type.
Data files created before MySQL 5.1.48 may contain garbage in FIL_PAGE_TYPE.
diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h
index bad040fdcda..5799776c32d 100644
--- a/storage/innobase/include/fts0ast.h
+++ b/storage/innobase/include/fts0ast.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index e8a91b0ef55..84d8ccd26ef 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -317,19 +317,11 @@ public:
/** fts_t destructor. */
~fts_t();
- /** Mutex protecting bg_threads* and fts_add_wq. */
- ib_mutex_t bg_threads_mutex;
-
- /** Whether the ADDED table record sync-ed after
- crash recovery; protected by bg_threads_mutex */
+ /** Whether the ADDED table record sync-ed after crash recovery */
unsigned added_synced:1;
- /** Whether the table holds dict_sys->mutex;
- protected by bg_threads_mutex */
+ /** Whether the table holds dict_sys->mutex */
unsigned dict_locked:1;
- /** Number of background threads accessing this table. */
- ulint bg_threads;
-
/** Work queue for scheduling jobs for the FTS 'Add' thread, or NULL
if the thread has not yet been created. Each work item is a
fts_trx_doc_ids_t*. */
@@ -735,12 +727,9 @@ fts_savepoint_rollback_last_stmt(
/*=============================*/
trx_t* trx); /*!< in: transaction */
-/***********************************************************************//**
-Drop all orphaned FTS auxiliary tables, those that don't have a parent
+/** Drop all orphaned FTS auxiliary tables, those that don't have a parent
table or FTS index defined on them. */
-void
-fts_drop_orphaned_tables(void);
-/*==========================*/
+void fts_drop_orphaned_tables();
/** Run SYNC on the table, i.e., write out data from the cache to the
FTS auxiliary INDEX table and clear the cache at the end.
@@ -774,15 +763,6 @@ fts_init_doc_id(
/*============*/
const dict_table_t* table); /*!< in: table */
-/* Get parent table name if it's a fts aux table
-@param[in] aux_table_name aux table name
-@param[in] aux_table_len aux table length
-@return parent table name, or NULL */
-char*
-fts_get_parent_table_name(
- const char* aux_table_name,
- ulint aux_table_len);
-
/******************************************************************//**
compare two character string according to their charset. */
extern
@@ -877,20 +857,18 @@ fts_valid_stopword_table(
name */
/****************************************************************//**
This function loads specified stopword into FTS cache
-@return TRUE if success */
-ibool
+@return true if success */
+bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transaction */
- const char* global_stopword_table, /*!< in: Global stopword table
- name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
- ibool stopword_is_on, /*!< in: Whether stopword
+ bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
- ibool reload); /*!< in: Whether it is during
+ bool reload); /*!< in: Whether it is during
reload of FTS table */
/****************************************************************//**
@@ -985,4 +963,20 @@ fts_trx_t*
fts_trx_create(
trx_t* trx);
+/** Clear all fts resources when there is no internal DOC_ID
+and there are no new fts index to add.
+@param[in,out] table table where fts is to be freed
+@param[in] trx transaction to drop all fts tables */
+void fts_clear_all(dict_table_t *table, trx_t *trx);
+
+/** Check whether the given name is fts auxiliary table
+and fetch the parent table id and index id
+@param[in] name table name
+@param[in,out] table_id parent table id
+@param[in,out] index_id index id
+@return true if it is auxilary table */
+bool fts_check_aux_table(const char *name,
+ table_id_t *table_id,
+ index_id_t *index_id);
+
#endif /*!< fts0fts.h */
diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h
index dd724aa12d4..2b7f31dfe54 100644
--- a/storage/innobase/include/fts0priv.h
+++ b/storage/innobase/include/fts0priv.h
@@ -239,7 +239,7 @@ Do a binary search for a doc id in the array
int
fts_bsearch(
/*========*/
- fts_update_t* array, /*!< in: array to sort */
+ doc_id_t* array, /*!< in: array to sort */
int lower, /*!< in: lower bound of array*/
int upper, /*!< in: upper bound of array*/
doc_id_t doc_id) /*!< in: doc id to lookup */
@@ -462,11 +462,7 @@ int
fts_write_object_id(
/*================*/
ib_id_t id, /*!< in: a table/index id */
- char* str, /*!< in: buffer to write the id to */
- bool hex_format MY_ATTRIBUTE((unused)))
- /*!< in: true for fixed hex format,
- false for old ambiguous format */
- MY_ATTRIBUTE((nonnull));
+ char* str); /*!< in: buffer to write the id to */
/******************************************************************//**
Read the table id from the string generated by fts_write_object_id().
@return TRUE if parse successful */
diff --git a/storage/innobase/include/fts0priv.ic b/storage/innobase/include/fts0priv.ic
index ed737e520d6..da14cfcb013 100644
--- a/storage/innobase/include/fts0priv.ic
+++ b/storage/innobase/include/fts0priv.ic
@@ -32,10 +32,7 @@ int
fts_write_object_id(
/*================*/
ib_id_t id, /* in: a table/index id */
- char* str, /* in: buffer to write the id to */
- bool hex_format MY_ATTRIBUTE((unused)))
- /* in: true for fixed hex format,
- false for old ambiguous format */
+ char* str) /* in: buffer to write the id to */
{
#ifdef _WIN32
@@ -60,11 +57,6 @@ fts_write_object_id(
#endif /* _WIN32 */
- /* As above, but this is only for those tables failing to rename. */
- if (!hex_format) {
- return(sprintf(str, "%016llu", (ulonglong) id));
- }
-
return(sprintf(str, "%016llx", (ulonglong) id));
}
diff --git a/storage/innobase/include/fts0types.h b/storage/innobase/include/fts0types.h
index a08a60b9e95..f5760a16c0e 100644
--- a/storage/innobase/include/fts0types.h
+++ b/storage/innobase/include/fts0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -80,20 +80,6 @@ struct fts_index_cache_t {
CHARSET_INFO* charset; /*!< charset */
};
-/** For supporting the tracking of updates on multiple FTS indexes we need
-to track which FTS indexes need to be updated. For INSERT and DELETE we
-update all fts indexes. */
-struct fts_update_t {
- doc_id_t doc_id; /*!< The doc id affected */
-
- ib_vector_t* fts_indexes; /*!< The FTS indexes that need to be
- updated. A NULL value means all
- indexes need to be updated. This
- vector is not allocated on the heap
- and so must be freed explicitly,
- when we are done with it */
-};
-
/** Stop word control infotmation. */
struct fts_stopword_t {
ulint status; /*!< Status of the stopword tree */
@@ -145,8 +131,6 @@ struct fts_cache_t {
intialization, it has different
SYNC level as above cache lock */
- ib_mutex_t optimize_lock; /*!< Lock for OPTIMIZE */
-
ib_mutex_t deleted_lock; /*!< Lock covering deleted_doc_ids */
ib_mutex_t doc_id_lock; /*!< Lock covering Doc ID */
@@ -319,10 +303,9 @@ fts_ranking_doc_id_cmp(
const void* p2); /*!< in: id2 */
/******************************************************************//**
-Compare two fts_update_t instances doc_ids. */
+Compare two doc_ids. */
UNIV_INLINE
-int
-fts_update_doc_id_cmp(
+int fts_doc_id_cmp(
/*==================*/
/*!< out:
< 0 if n1 < n2,
diff --git a/storage/innobase/include/fts0types.ic b/storage/innobase/include/fts0types.ic
index e388d6257f6..cf5cf35c48e 100644
--- a/storage/innobase/include/fts0types.ic
+++ b/storage/innobase/include/fts0types.ic
@@ -79,19 +79,18 @@ fts_ranking_doc_id_cmp(
}
/******************************************************************//**
-Compare two fts_update_t doc_ids.
+Compare two doc_ids.
@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */
UNIV_INLINE
-int
-fts_update_doc_id_cmp(
+int fts_doc_id_cmp(
/*==================*/
const void* p1, /*!< in: id1 */
const void* p2) /*!< in: id2 */
{
- const fts_update_t* up1 = (const fts_update_t*) p1;
- const fts_update_t* up2 = (const fts_update_t*) p2;
+ const doc_id_t* up1 = static_cast<const doc_id_t*>(p1);
+ const doc_id_t* up2 = static_cast<const doc_id_t*>(p2);
- return((int)(up1->doc_id - up2->doc_id));
+ return static_cast<int>(*up1 - *up2);
}
/******************************************************************//**
diff --git a/storage/innobase/include/gis0geo.h b/storage/innobase/include/gis0geo.h
index 3b71815d0fe..dea6d63f4e0 100644
--- a/storage/innobase/include/gis0geo.h
+++ b/storage/innobase/include/gis0geo.h
@@ -54,19 +54,6 @@ enum wkbByteOrder
wkbNDR = 1 /* Little Endian */
};
-/** Get the wkb of default POINT value, which represents POINT(0 0)
-if it's of dimension 2, etc.
-@param[in] n_dims dimensions
-@param[out] wkb wkb buffer for default POINT
-@param[in] len length of wkb buffer
-@return non-0 indicate the length of wkb of the default POINT,
-0 if the buffer is too small */
-uint
-get_wkb_of_default_point(
- uint n_dims,
- uchar* wkb,
- uint len);
-
/*************************************************************//**
Calculate minimal bounding rectangle (mbr) of the spatial object
stored in "well-known binary representation" (wkb) format.
diff --git a/storage/innobase/include/gis0rtree.h b/storage/innobase/include/gis0rtree.h
index e5942b71c64..5e812d10451 100644
--- a/storage/innobase/include/gis0rtree.h
+++ b/storage/innobase/include/gis0rtree.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -28,6 +28,7 @@ Created 2013/03/27 Jimmy Yang and Allen Lai
#define gis0rtree_h
#include "btr0cur.h"
+#include "rem0types.h"
/* Whether MBR 'a' contains 'b' */
#define MBR_CONTAIN_CMP(a, b) \
@@ -90,7 +91,7 @@ rtr_page_split_and_insert(
btr_cur_t* cursor, /*!< in/out: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
- ulint** offsets,/*!< out: offsets on inserted record */
+ rec_offs** offsets,/*!< out: offsets on inserted record */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
@@ -152,7 +153,7 @@ rtr_rec_cal_increase(
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
double* area); /*!< out: increased area */
/****************************************************************//**
@@ -165,22 +166,6 @@ rtr_ins_enlarge_mbr(
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr); /*!< in: mtr */
-/********************************************************************//**
-*/
-void
-rtr_get_father_node(
-/*================*/
- dict_index_t* index, /*!< in: index */
- ulint level, /*!< in: the tree level of search */
- const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
- tuple must be set so that it cannot get
- compared to the node ptr page number field! */
- btr_cur_t* sea_cur,/*!< in: search cursor */
- btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
- s- or x-latched */
- ulint page_no,/*!< in: current page no */
- mtr_t* mtr); /*!< in: mtr */
-
/**************************************************************//**
push a nonleaf index node to the search path */
UNIV_INLINE
@@ -276,7 +261,7 @@ void
rtr_get_mbr_from_rec(
/*=================*/
const rec_t* rec, /*!< in: data tuple */
- const ulint* offsets,/*!< in: offsets array */
+ const rec_offs* offsets,/*!< in: offsets array */
rtr_mbr_t* mbr); /*!< out MBR */
/****************************************************************//**
@@ -308,10 +293,10 @@ rtr_page_get_father(
Returns the father block to a page. It is assumed that mtr holds
an X or SX latch on the tree.
@return rec_get_offsets() of the node pointer record */
-ulint*
+rec_offs*
rtr_page_get_father_block(
/*======================*/
- ulint* offsets,/*!< in: work area for the return value */
+ rec_offs* offsets,/*!< in: work area for the return value */
mem_heap_t* heap, /*!< in: memory heap to use */
dict_index_t* index, /*!< in: b-tree index */
buf_block_t* block, /*!< in: child page in the index */
@@ -418,8 +403,8 @@ rtr_merge_and_update_mbr(
/*=====================*/
btr_cur_t* cursor, /*!< in/out: cursor */
btr_cur_t* cursor2, /*!< in: the other cursor */
- ulint* offsets, /*!< in: rec offsets */
- ulint* offsets2, /*!< in: rec offsets */
+ rec_offs* offsets, /*!< in: rec offsets */
+ rec_offs* offsets2, /*!< in: rec offsets */
page_t* child_page, /*!< in: the child page. */
buf_block_t* merge_block, /*!< in: page to merge */
buf_block_t* block, /*!< in: page be merged */
@@ -444,8 +429,8 @@ rtr_merge_mbr_changed(
/*==================*/
btr_cur_t* cursor, /*!< in: cursor */
btr_cur_t* cursor2, /*!< in: the other cursor */
- ulint* offsets, /*!< in: rec offsets */
- ulint* offsets2, /*!< in: rec offsets */
+ rec_offs* offsets, /*!< in: rec offsets */
+ rec_offs* offsets2, /*!< in: rec offsets */
rtr_mbr_t* new_mbr, /*!< out: MBR to update */
buf_block_t* merge_block, /*!< in: page to merge */
buf_block_t* block, /*!< in: page be merged */
@@ -459,7 +444,7 @@ bool
rtr_update_mbr_field(
/*=================*/
btr_cur_t* cursor, /*!< in: cursor pointed to rec.*/
- ulint* offsets, /*!< in: offsets on rec. */
+ rec_offs* offsets, /*!< in: offsets on rec. */
btr_cur_t* cursor2, /*!< in/out: cursor pointed to rec
that should be deleted.
this cursor is for btr_compress to
diff --git a/storage/innobase/include/gis0rtree.ic b/storage/innobase/include/gis0rtree.ic
index b9ab2ea57e8..696aa1e2f5f 100644
--- a/storage/innobase/include/gis0rtree.ic
+++ b/storage/innobase/include/gis0rtree.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -40,7 +40,7 @@ rtr_page_cal_mbr(
rec_t* rec;
byte* field;
ulint len;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
double bmin, bmax;
double* amin;
double* amax;
@@ -132,13 +132,9 @@ rtr_get_new_ssn_id(
/*===============*/
dict_index_t* index) /*!< in/out: the index struct */
{
- node_seq_t ssn;
-
- mutex_enter(&(index->rtr_ssn.mutex));
- ssn = ++index->rtr_ssn.seq_no;
- mutex_exit(&(index->rtr_ssn.mutex));
-
- return(ssn);
+ node_seq_t ssn= my_atomic_add32_explicit(&index->rtr_ssn, 1,
+ MY_MEMORY_ORDER_RELAXED);
+ return ssn + 1;
}
/*****************************************************************//**
Get the current Split Sequence Number.
@@ -149,13 +145,7 @@ rtr_get_current_ssn_id(
/*===================*/
dict_index_t* index) /*!< in: index struct */
{
- node_seq_t ssn;
-
- mutex_enter(&(index->rtr_ssn.mutex));
- ssn = index->rtr_ssn.seq_no;
- mutex_exit(&(index->rtr_ssn.mutex));
-
- return(ssn);
+ return my_atomic_load32_explicit(&index->rtr_ssn, MY_MEMORY_ORDER_RELAXED);
}
/*********************************************************************//**
diff --git a/storage/innobase/include/gis0type.h b/storage/innobase/include/gis0type.h
index ee350ea56ce..c5ea817c6bf 100644
--- a/storage/innobase/include/gis0type.h
+++ b/storage/innobase/include/gis0type.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -143,12 +143,6 @@ typedef struct rtr_info_track {
rtr_active */
} rtr_info_track_t;
-/* Node Sequence Number and mutex protects it. */
-typedef struct rtree_ssn {
- ib_mutex_t mutex; /*!< mutex protect the seq num */
- node_seq_t seq_no; /*!< the SSN (node sequence number) */
-} rtr_ssn_t;
-
/* This is to record the record movement between pages. Used for corresponding
lock movement */
typedef struct rtr_rec_move {
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index 693dcd15163..05dc3f57df7 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -244,13 +244,7 @@ int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
unsigned int buf_length);
#endif /* WITH_WSREP */
-/**********************************************************************//**
-Determines the connection character set.
-@return connection character set */
-CHARSET_INFO*
-innobase_get_charset(
-/*=================*/
- THD* thd); /*!< in: MySQL thread handle */
+extern "C" struct charset_info_st *thd_charset(THD *thd);
/** Determines the current SQL statement.
Thread unsafe, can only be called from the thread owning the THD.
@@ -262,19 +256,6 @@ innobase_get_stmt_unsafe(
THD* thd,
size_t* length);
-/** Determines the current SQL statement.
-Thread safe, can be called from any thread as the string is copied
-into the provided buffer.
-@param[in] thd MySQL thread handle
-@param[out] buf Buffer containing SQL statement
-@param[in] buflen Length of provided buffer
-@return Length of the SQL statement */
-size_t
-innobase_get_stmt_safe(
- THD* thd,
- char* buf,
- size_t buflen);
-
/******************************************************************//**
This function is used to find the storage length in bytes of the first n
characters for prefix indexes using a multibyte character set. The function
diff --git a/storage/innobase/include/handler0alter.h b/storage/innobase/include/handler0alter.h
index 16616e3fc9c..35a04163f43 100644
--- a/storage/innobase/include/handler0alter.h
+++ b/storage/innobase/include/handler0alter.h
@@ -22,6 +22,8 @@ this program; if not, write to the Free Software Foundation, Inc.,
Smart ALTER TABLE
*******************************************************/
+#include "rem0types.h"
+
/*************************************************************//**
Copies an InnoDB record to table->record[0]. */
void
@@ -30,7 +32,7 @@ innobase_rec_to_mysql(
struct TABLE* table, /*!< in/out: MySQL table */
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: index */
- const ulint* offsets)/*!< in: rec_get_offsets(
+ const rec_offs* offsets)/*!< in: rec_get_offsets(
rec, index, ...) */
MY_ATTRIBUTE((nonnull));
diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h
index 5d317a23d4e..4f55b051d80 100644
--- a/storage/innobase/include/hash0hash.h
+++ b/storage/innobase/include/hash0hash.h
@@ -184,6 +184,18 @@ do {\
HASH_INVALIDATE(DATA, NAME);\
} while (0)
+#define HASH_REPLACE(TYPE, NAME, TABLE, FOLD, DATA_OLD, DATA_NEW) \
+ do { \
+ (DATA_NEW)->NAME = (DATA_OLD)->NAME; \
+ \
+ hash_cell_t& cell3333 \
+ = TABLE->array[hash_calc_hash(FOLD, TABLE)]; \
+ TYPE** struct3333 = (TYPE**)&cell3333.node; \
+ while (*struct3333 != DATA_OLD) { \
+ struct3333 = &((*struct3333)->NAME); \
+ } \
+ *struct3333 = DATA_NEW; \
+ } while (0)
/*******************************************************************//**
Gets the first struct in a hash chain, NULL if none. */
diff --git a/storage/innobase/include/ib0mutex.h b/storage/innobase/include/ib0mutex.h
index e7f5ca2b44f..a7289777e00 100644
--- a/storage/innobase/include/ib0mutex.h
+++ b/storage/innobase/include/ib0mutex.h
@@ -225,7 +225,7 @@ struct TTASFutexMutex {
return;
}
- ut_delay(ut_rnd_interval(0, max_delay));
+ ut_delay(max_delay);
}
for (n_waits= 0;; n_waits++) {
@@ -362,7 +362,7 @@ struct TTASMutex {
uint32_t n_spins = 0;
while (!try_lock()) {
- ut_delay(ut_rnd_interval(0, max_delay));
+ ut_delay(max_delay);
if (++n_spins == max_spins) {
os_thread_yield();
max_spins+= step;
@@ -516,7 +516,7 @@ struct TTASEventMutex {
sync_array_wait_event(sync_arr, cell);
}
} else {
- ut_delay(ut_rnd_interval(0, max_delay));
+ ut_delay(max_delay);
}
}
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 8369db8b879..edde6bf516e 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -317,7 +317,7 @@ lock_clust_rec_modify_check_and_lock(
const rec_t* rec, /*!< in: record which should be
modified */
dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
@@ -355,7 +355,7 @@ lock_sec_rec_read_check_and_lock(
be read or passed over by a
read cursor */
dict_index_t* index, /*!< in: secondary index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
@@ -383,7 +383,7 @@ lock_clust_rec_read_check_and_lock(
be read or passed over by a
read cursor */
dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
@@ -432,7 +432,7 @@ lock_clust_rec_cons_read_sees(
const rec_t* rec, /*!< in: user record which should be read or
passed over by a read cursor */
dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ReadView* view); /*!< in: consistent read view */
/*********************************************************************//**
Checks that a non-clustered index record is seen in a consistent read.
@@ -571,13 +571,14 @@ lock_has_to_wait(
locks are record locks */
/*********************************************************************//**
Reports that a transaction id is insensible, i.e., in the future. */
+ATTRIBUTE_COLD
void
lock_report_trx_id_insanity(
/*========================*/
trx_id_t trx_id, /*!< in: trx id */
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec, index) */
trx_id_t max_trx_id); /*!< in: trx_sys_get_max_trx_id() */
/*********************************************************************//**
Prints info of locks for all transactions.
@@ -803,7 +804,7 @@ lock_check_trx_id_sanity(
trx_id_t trx_id, /*!< in: trx id */
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets) /*!< in: rec_get_offsets(rec, index) */
MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Check if the transaction holds any locks on the sys tables
@@ -1045,10 +1046,6 @@ std::string
lock_get_info(
const lock_t*);
-/*******************************************************************//**
-@return whether wsrep_on is true on trx->mysql_thd*/
-#define wsrep_on_trx(trx) ((trx)->mysql_thd && wsrep_on((trx)->mysql_thd))
-
#endif /* WITH_WSREP */
#include "lock0lock.ic"
diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h
index 9b80f593e30..1a950ac1cfa 100644
--- a/storage/innobase/include/lock0priv.h
+++ b/storage/innobase/include/lock0priv.h
@@ -35,6 +35,7 @@ those functions in lock/ */
#endif
#include "hash0hash.h"
+#include "rem0types.h"
#include "trx0trx.h"
#ifndef UINT32_MAX
@@ -468,7 +469,7 @@ lock_clust_rec_some_has_impl(
/*=========================*/
const rec_t* rec, /*!< in: user record */
const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
diff --git a/storage/innobase/include/lock0priv.ic b/storage/innobase/include/lock0priv.ic
index 80a63271256..8bb145e41fc 100644
--- a/storage/innobase/include/lock0priv.ic
+++ b/storage/innobase/include/lock0priv.ic
@@ -59,7 +59,7 @@ lock_clust_rec_some_has_impl(
/*=========================*/
const rec_t* rec, /*!< in: user record */
const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ut_ad(dict_index_is_clust(index));
ut_ad(page_rec_is_user_rec(rec));
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 0fd983a1a10..612a27976e7 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Google Inc.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -56,12 +56,6 @@ step which modifies the database, is started */
#define LOG_CHECKPOINT_FREE_PER_THREAD (4 * UNIV_PAGE_SIZE)
#define LOG_CHECKPOINT_EXTRA_FREE (8 * UNIV_PAGE_SIZE)
-typedef ulint (*log_checksum_func_t)(const byte* log_block);
-
-/** Pointer to the log checksum calculation function. Protected with
-log_sys->mutex. */
-extern log_checksum_func_t log_checksum_algorithm_ptr;
-
/** Append a string to the log.
@param[in] str string
@param[in] len string length
@@ -295,14 +289,6 @@ log_block_set_data_len(
/*===================*/
byte* log_block, /*!< in/out: log block */
ulint len); /*!< in: data length */
-/************************************************************//**
-Calculates the checksum for a log block.
-@return checksum */
-UNIV_INLINE
-ulint
-log_block_calc_checksum(
-/*====================*/
- const byte* block); /*!< in: log block */
/** Calculates the checksum for a log block using the CRC32 algorithm.
@param[in] block log block
@@ -312,13 +298,6 @@ ulint
log_block_calc_checksum_crc32(
const byte* block);
-/** Calculates the checksum for a log block using the "no-op" algorithm.
-@param[in] block the redo log block
-@return the calculated checksum value */
-UNIV_INLINE
-ulint
-log_block_calc_checksum_none(const byte* block);
-
/************************************************************//**
Gets a log block checksum field value.
@return checksum */
@@ -403,7 +382,7 @@ log_group_close_all(void);
void
log_shutdown();
-/** Whether to generate and require checksums on the redo log pages */
+/** Whether to require checksums on the redo log pages */
extern my_bool innodb_log_checksums;
/* Values used as flags */
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index 36caaedfaa2..c366affcdef 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -190,18 +190,6 @@ log_block_convert_lsn_to_no(
0xFUL, 0x3FFFFFFFUL)) + 1);
}
-/************************************************************//**
-Calculates the checksum for a log block.
-@return checksum */
-UNIV_INLINE
-ulint
-log_block_calc_checksum(
-/*====================*/
- const byte* block) /*!< in: log block */
-{
- return(log_checksum_algorithm_ptr(block));
-}
-
/** Calculate the checksum for a log block using the pre-5.7.9 algorithm.
@param[in] block log block
@return checksum */
@@ -242,17 +230,6 @@ log_block_calc_checksum_crc32(
return(ut_crc32(block, OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE));
}
-/** Calculates the checksum for a log block using the "no-op" algorithm.
-@param[in] block log block
-@return checksum */
-UNIV_INLINE
-ulint
-log_block_calc_checksum_none(
- const byte* block)
-{
- return(LOG_NO_CHECKSUM_MAGIC);
-}
-
/************************************************************//**
Gets a log block checksum field value.
@return checksum */
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index 74aa4fcb517..6425e3c6c37 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -133,14 +133,19 @@ bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn);
/** Parse log records from a buffer and optionally store them to a
hash table to wait merging to file pages.
-@param[in] checkpoint_lsn the LSN of the latest checkpoint
-@param[in] store whether to store page operations
-@param[in] apply whether to apply the records
+@param[in] checkpoint_lsn the LSN of the latest checkpoint
+@param[in] store whether to store page operations
+@param[in] available_memory memory to read the redo logs
+@param[in] apply whether to apply the records
@return whether MLOG_CHECKPOINT record was seen the first time,
or corruption was noticed */
-bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply);
+bool recv_parse_log_recs(
+ lsn_t checkpoint_lsn,
+ store_t* store,
+ ulint available_memory,
+ bool apply);
-/** Moves the parsing buffer data left to the buffer start. */
+/** Moves the parsing buffer data left to the buffer start */
void recv_sys_justify_left_parsing_buf();
/** Report optimized DDL operation (without redo log),
@@ -190,23 +195,35 @@ struct recv_t{
rec_list;/*!< list of log records for this page */
};
-struct recv_dblwr_t {
- /** Add a page frame to the doublewrite recovery buffer. */
- void add(byte* page) {
- pages.push_back(page);
- }
-
- /** Find a doublewrite copy of a page.
- @param[in] space_id tablespace identifier
- @param[in] page_no page number
- @return page frame
- @retval NULL if no page was found */
- const byte* find_page(ulint space_id, ulint page_no);
-
- typedef std::list<byte*, ut_allocator<byte*> > list;
-
- /** Recovered doublewrite buffer page frames */
- list pages;
+struct recv_dblwr_t
+{
+ /** Add a page frame to the doublewrite recovery buffer. */
+ void add(byte *page) { pages.push_back(page); }
+
+ /** Validate the page.
+ @param page_id page identifier
+ @param page page contents
+ @param space the tablespace of the page (not available for page 0)
+ @param tmp_buf 2*srv_page_size for decrypting and decompressing any
+ page_compressed or encrypted pages
+ @return whether the page is valid */
+ bool validate_page(const page_id_t page_id, const byte *page,
+ const fil_space_t *space, byte *tmp_buf);
+
+ /** Find a doublewrite copy of a page.
+ @param page_id page identifier
+ @param space tablespace (not available for page_id.page_no()==0)
+ @param tmp_buf 2*srv_page_size for decrypting and decompressing any
+ page_compressed or encrypted pages
+ @return page frame
+ @retval NULL if no valid page for page_id was found */
+ byte* find_page(const page_id_t page_id, const fil_space_t *space= NULL,
+ byte *tmp_buf= NULL);
+
+ typedef std::list<byte*, ut_allocator<byte*> > list;
+
+ /** Recovered doublewrite buffer page frames */
+ list pages;
};
/** Recovery system data structure */
@@ -337,10 +354,22 @@ times! */
roll-forward */
#define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE)
-/** This many frames must be left free in the buffer pool when we scan
-the log and store the scanned log records in the buffer pool: we will
-use these free frames to read in pages when we start applying the
-log records to the database. */
-extern ulint recv_n_pool_free_frames;
+/** This is a low level function for the recovery system
+to create a page which has buffered intialized redo log records.
+@param[in] page_id page to be created using redo logs
+@return whether the page creation successfully */
+buf_block_t* recv_recovery_create_page_low(const page_id_t page_id);
+
+/** Recovery system creates a page which has buffered intialized
+redo log records.
+@param[in] page_id page to be created using redo logs
+@return block which contains page was initialized */
+inline buf_block_t* recv_recovery_create_page(const page_id_t page_id)
+{
+ if (UNIV_LIKELY(!recv_recovery_on))
+ return NULL;
+
+ return recv_recovery_create_page_low(page_id);
+}
#endif
diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h
index 22c0a04e170..0cd15ebb261 100644
--- a/storage/innobase/include/mem0mem.h
+++ b/storage/innobase/include/mem0mem.h
@@ -287,13 +287,6 @@ mem_heap_printf(
const char* format, /*!< in: format string */
...) MY_ATTRIBUTE ((format (printf, 2, 3)));
-/** Checks that an object is a memory heap (or a block of it)
-@param[in] heap Memory heap to check */
-UNIV_INLINE
-void
-mem_block_validate(
- const mem_heap_t* heap);
-
#ifdef UNIV_DEBUG
/** Validates the contents of a memory heap.
Asserts that the memory heap is consistent
@@ -308,7 +301,6 @@ mem_heap_validate(
/** The info structure stored at the beginning of a heap block */
struct mem_block_info_t {
- ulint magic_n;/* magic number for debugging */
#ifdef UNIV_DEBUG
char file_name[8];/* file name where the mem heap was created */
unsigned line; /*!< line number where the mem heap was created */
@@ -343,9 +335,6 @@ struct mem_block_info_t {
otherwise, this is NULL */
};
-#define MEM_BLOCK_MAGIC_N 764741555
-#define MEM_FREED_BLOCK_MAGIC_N 547711122
-
/* Header size for a memory heap block */
#define MEM_BLOCK_HEADER_SIZE UT_CALC_ALIGN(sizeof(mem_block_info_t),\
UNIV_MEM_ALIGNMENT)
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index a44f2ff45fa..bd0db9bf503 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -144,16 +144,6 @@ mem_block_get_start(mem_block_t* block)
return(block->start);
}
-/** Checks that an object is a memory heap block
-@param[in] block Memory block to check. */
-UNIV_INLINE
-void
-mem_block_validate(
- const mem_block_t* block)
-{
- ut_a(block->magic_n == MEM_BLOCK_MAGIC_N);
-}
-
/** Allocates and zero-fills n bytes of memory from a memory heap.
@param[in] heap memory heap
@param[in] n number of bytes; if the heap is allowed to grow into
@@ -186,8 +176,6 @@ mem_heap_alloc(
byte* buf;
ulint free;
- ut_d(mem_block_validate(heap));
-
block = UT_LIST_GET_LAST(heap->base);
n += REDZONE_SIZE;
@@ -215,7 +203,7 @@ mem_heap_alloc(
mem_block_set_free(block, free + MEM_SPACE_NEEDED(n));
buf = buf + REDZONE_SIZE;
- UNIV_MEM_ALLOC(buf, n - REDZONE_SIZE);
+ MEM_UNDEFINED(buf, n - REDZONE_SIZE);
return(buf);
}
@@ -230,8 +218,6 @@ mem_heap_get_heap_top(
mem_block_t* block;
byte* buf;
- ut_d(mem_block_validate(heap));
-
block = UT_LIST_GET_LAST(heap->base);
buf = (byte*) block + mem_block_get_free(block);
@@ -281,7 +267,7 @@ mem_heap_free_heap_top(
mem_block_set_free(block, old_top - (byte*) block);
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
- UNIV_MEM_FREE(old_top, (byte*) block + block->len - old_top);
+ MEM_NOACCESS(old_top, (byte*) block + block->len - old_top);
/* If free == start, we may free the block if it is not the first
one */
@@ -321,8 +307,6 @@ mem_heap_get_top(
mem_block_t* block;
byte* buf;
- ut_d(mem_block_validate(heap));
-
block = UT_LIST_GET_LAST(heap->base);
buf = (byte*) block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n);
@@ -342,8 +326,6 @@ mem_heap_free_top(
{
mem_block_t* block;
- ut_d(mem_block_validate(heap));
-
n += REDZONE_SIZE;
block = UT_LIST_GET_LAST(heap->base);
@@ -359,7 +341,7 @@ mem_heap_free_top(
== mem_block_get_start(block))) {
mem_heap_block_free(heap, block);
} else {
- UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
+ MEM_NOACCESS((byte*) block + mem_block_get_free(block), n);
}
}
@@ -419,8 +401,6 @@ mem_heap_free(
mem_block_t* block;
mem_block_t* prev_block;
- ut_d(mem_block_validate(heap));
-
block = UT_LIST_GET_LAST(heap->base);
if (heap->free_block) {
@@ -447,11 +427,7 @@ mem_heap_get_size(
/*==============*/
mem_heap_t* heap) /*!< in: heap */
{
- ulint size = 0;
-
- ut_d(mem_block_validate(heap));
-
- size = heap->total_size;
+ ulint size = heap->total_size;
if (heap->free_block) {
size += UNIV_PAGE_SIZE;
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 30d2e937f1f..5270cd671db 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -302,6 +302,12 @@ struct mtr_t {
const char* file,
unsigned line);
+ /** Exclusively aqcuire a tablespace latch.
+ @param space tablespace
+ @param file source code file name of the caller
+ @param line source code line number */
+ void x_lock_space(fil_space_t *space, const char *file, unsigned line);
+
/** Release an object in the memo stack.
@param object object
@param type object type: MTR_MEMO_S_LOCK, ...
@@ -428,6 +434,10 @@ struct mtr_t {
static inline bool is_block_dirtied(const buf_block_t* block)
MY_ATTRIBUTE((warn_unused_result));
+ /** Get the buffer fix count for the block added by this mtr.
+ @param[in] block block to be checked
+ @return number of buffer count added by this mtr */
+ int32_t get_fix_count(buf_block_t *block);
private:
/** Look up the system tablespace. */
void lookup_sys_space();
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index 7175ede0d6a..8d68affb1cb 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -48,7 +48,7 @@ mtr_t::memo_push(void* object, mtr_memo_type_t type)
ut_ad(is_active());
ut_ad(object != NULL);
ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
- ut_ad(type <= MTR_MEMO_SX_LOCK);
+ ut_ad(type <= MTR_MEMO_SPACE_X_LOCK);
ut_ad(ut_is_2pow(type));
/* If this mtr has x-fixed a clean page then we set
diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h
index 985ad7b81ea..2d4cd7b97ac 100644
--- a/storage/innobase/include/mtr0types.h
+++ b/storage/innobase/include/mtr0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -263,7 +263,10 @@ enum mtr_memo_type_t {
MTR_MEMO_X_LOCK = RW_X_LATCH << 5,
- MTR_MEMO_SX_LOCK = RW_SX_LATCH << 5
+ MTR_MEMO_SX_LOCK = RW_SX_LATCH << 5,
+
+ /** acquire X-latch on fil_space_t::latch */
+ MTR_MEMO_SPACE_X_LOCK = MTR_MEMO_SX_LOCK << 1
};
#endif /* !UNIV_CHECKSUM */
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index e85bf74201a..82d1551de6c 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
@@ -161,6 +161,7 @@ static const ulint OS_FILE_NORMAL = 62;
static const ulint OS_DATA_FILE = 100;
static const ulint OS_LOG_FILE = 101;
static const ulint OS_DATA_TEMP_FILE = 102;
+static const ulint OS_DATA_FILE_NO_O_DIRECT = 103;
/* @} */
/** Error codes from os_file_get_last_error @{ */
diff --git a/storage/innobase/include/os0once.h b/storage/innobase/include/os0once.h
deleted file mode 100644
index ad72370eefa..00000000000
--- a/storage/innobase/include/os0once.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/os0once.h
-A class that aids executing a given function exactly once in a multi-threaded
-environment.
-
-Created Feb 20, 2014 Vasil Dimov
-*******************************************************/
-
-#ifndef os0once_h
-#define os0once_h
-
-#include "univ.i"
-#include "ut0ut.h"
-
-/** Execute a given function exactly once in a multi-threaded environment
-or wait for the function to be executed by another thread.
-
-Example usage:
-First the user must create a control variable of type os_once::state_t and
-assign it os_once::NEVER_DONE.
-Then the user must pass this variable, together with a function to be
-executed to os_once::do_or_wait_for_done().
-
-Multiple threads can call os_once::do_or_wait_for_done() simultaneously with
-the same (os_once::state_t) control variable. The provided function will be
-called exactly once and when os_once::do_or_wait_for_done() returns then this
-function has completed execution, by this or another thread. In other words
-os_once::do_or_wait_for_done() will either execute the provided function or
-will wait for its execution to complete if it is already called by another
-thread or will do nothing if the function has already completed its execution
-earlier.
-
-This mimics pthread_once(3), but unfortunatelly pthread_once(3) does not
-support passing arguments to the init_routine() function. We should use
-std::call_once() when we start compiling with C++11 enabled. */
-class os_once {
-public:
- /** Control variables' state type */
- typedef ib_uint32_t state_t;
-
- /** Not yet executed. */
- static const state_t NEVER_DONE = 0;
-
- /** Currently being executed by this or another thread. */
- static const state_t IN_PROGRESS = 1;
-
- /** Finished execution. */
- static const state_t DONE = 2;
-
- /** Call a given function or wait its execution to complete if it is
- already called by another thread.
- @param[in,out] state control variable
- @param[in] do_func function to call
- @param[in,out] do_func_arg an argument to pass to do_func(). */
- static
- void
- do_or_wait_for_done(
- volatile state_t* state,
- void (*do_func)(void*),
- void* do_func_arg)
- {
- int32 oldval = NEVER_DONE;
-
- /* Avoid calling my_atomic_cas32() in the most common case. */
- if (*state == DONE) {
- return;
- }
-
- if (my_atomic_cas32((int32*) state, &oldval, IN_PROGRESS)) {
- /* We are the first. Call the function. */
-
- do_func(do_func_arg);
-
- my_atomic_store32((int32*) state, DONE);
- } else {
- /* The state is not NEVER_DONE, so either it is
- IN_PROGRESS (somebody is calling the function right
- now or DONE (it has already been called and completed).
- Wait for it to become DONE. */
- for (;;) {
- const state_t s = *state;
-
- switch (s) {
- case DONE:
- return;
- case IN_PROGRESS:
- break;
- case NEVER_DONE:
- /* fall through */
- default:
- ut_error;
- }
-
- UT_RELAX_CPU();
- }
- }
- }
-};
-
-#endif /* os0once_h */
diff --git a/storage/innobase/include/page0cur.h b/storage/innobase/include/page0cur.h
index 18cc058ca6d..817902b6404 100644
--- a/storage/innobase/include/page0cur.h
+++ b/storage/innobase/include/page0cur.h
@@ -29,6 +29,7 @@ Created 10/4/1994 Heikki Tuuri
#include "buf0types.h"
#include "page0page.h"
+#include "rem0types.h"
#include "rem0rec.h"
#include "data0data.h"
#include "mtr0mtr.h"
@@ -151,7 +152,7 @@ page_cur_tuple_insert(
page_cur_t* cursor, /*!< in/out: a page cursor */
const dtuple_t* tuple, /*!< in: pointer to a data tuple */
dict_index_t* index, /*!< in: record descriptor */
- ulint** offsets,/*!< out: offsets on *rec */
+ rec_offs** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr, /*!< in: mini-transaction handle, or NULL */
@@ -178,7 +179,7 @@ page_cur_rec_insert(
page_cur_t* cursor, /*!< in/out: a page cursor */
const rec_t* rec, /*!< in: record to insert */
dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(rec, index) */
mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
@@ -192,7 +193,7 @@ page_cur_insert_rec_low(
which the new record is inserted */
dict_index_t* index, /*!< in: record descriptor */
const rec_t* rec, /*!< in: pointer to a physical record */
- ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(rec, index) */
mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
MY_ATTRIBUTE((nonnull(1,2,3,4), warn_unused_result));
@@ -214,7 +215,7 @@ page_cur_insert_rec_zip(
page_cur_t* cursor, /*!< in/out: page cursor */
dict_index_t* index, /*!< in: record descriptor */
const rec_t* rec, /*!< in: pointer to a physical record */
- ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(rec, index) */
mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
MY_ATTRIBUTE((nonnull(1,2,3,4), warn_unused_result));
/*************************************************************//**
@@ -240,7 +241,7 @@ page_cur_delete_rec(
/*================*/
page_cur_t* cursor, /*!< in/out: a page cursor */
const dict_index_t* index, /*!< in: record descriptor */
- const ulint* offsets,/*!< in: rec_get_offsets(
+ const rec_offs* offsets,/*!< in: rec_get_offsets(
cursor->rec, index) */
mtr_t* mtr); /*!< in: mini-transaction handle */
@@ -388,14 +389,14 @@ page_delete_rec(
page_cur_t* pcur, /*!< in/out: page cursor on record
to delete */
page_zip_des_t* page_zip,/*!< in: compressed page descriptor */
- const ulint* offsets);/*!< in: offsets for record */
+ const rec_offs* offsets);/*!< in: offsets for record */
/** Index page cursor */
struct page_cur_t{
const dict_index_t* index;
rec_t* rec; /*!< pointer to a record on page */
- ulint* offsets;
+ rec_offs* offsets;
buf_block_t* block; /*!< pointer to the block containing rec */
};
diff --git a/storage/innobase/include/page0cur.ic b/storage/innobase/include/page0cur.ic
index 7c5737613c4..e57d3f9dee1 100644
--- a/storage/innobase/include/page0cur.ic
+++ b/storage/innobase/include/page0cur.ic
@@ -259,7 +259,7 @@ page_cur_tuple_insert(
page_cur_t* cursor, /*!< in/out: a page cursor */
const dtuple_t* tuple, /*!< in: pointer to a data tuple */
dict_index_t* index, /*!< in: record descriptor */
- ulint** offsets,/*!< out: offsets on *rec */
+ rec_offs** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr, /*!< in: mini-transaction handle, or NULL */
@@ -315,7 +315,7 @@ page_cur_rec_insert(
page_cur_t* cursor, /*!< in/out: a page cursor */
const rec_t* rec, /*!< in: record to insert */
dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(rec, index) */
mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
if (buf_block_get_page_zip(cursor->block)) {
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index 2e3bae2d7ff..a569912b82b 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -32,6 +32,7 @@ Created 2/2/1994 Heikki Tuuri
#include "buf0buf.h"
#include "data0data.h"
#include "dict0dict.h"
+#include "rem0types.h"
#include "rem0rec.h"
#endif /* !UNIV_INNOCHECKSUM*/
#include "fsp0fsp.h"
@@ -813,6 +814,22 @@ page_rec_is_last(
MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
+true if distance between the records (measured in number of times we have to
+move to the next record) is at most the specified value
+@param[in] left_rec lefter record
+@param[in] right_rec righter record
+@param[in] val specified value to compare
+@return true if the distance is smaller than the value */
+UNIV_INLINE
+bool
+page_rec_distance_is_at_most(
+/*=========================*/
+ const rec_t* left_rec,
+ const rec_t* right_rec,
+ ulint val)
+ MY_ATTRIBUTE((warn_unused_result));
+
+/************************************************************//**
true if the record is the second last user record on a page.
@return true if the second last user record */
UNIV_INLINE
@@ -894,20 +911,6 @@ page_mem_alloc_free(
free record list */
ulint need); /*!< in: number of bytes allocated */
/************************************************************//**
-Allocates a block of memory from the heap of an index page.
-@return pointer to start of allocated buffer, or NULL if allocation fails */
-byte*
-page_mem_alloc_heap(
-/*================*/
- page_t* page, /*!< in/out: index page */
- page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
- space available for inserting the record,
- or NULL */
- ulint need, /*!< in: total number of bytes needed */
- ulint* heap_no);/*!< out: this contains the heap number
- of the allocated record
- if allocation succeeds */
-/************************************************************//**
Puts a record to free list. */
UNIV_INLINE
void
@@ -919,7 +922,7 @@ page_mem_free(
rec_t* rec, /*!< in: pointer to the (origin of)
record */
const dict_index_t* index, /*!< in: index of rec */
- const ulint* offsets);/*!< in: array returned by
+ const rec_offs* offsets);/*!< in: array returned by
rec_get_offsets() */
/**********************************************************//**
Create an uncompressed B-tree index page.
@@ -1140,7 +1143,7 @@ void
page_rec_print(
/*===========*/
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets);/*!< in: record descriptor */
+ const rec_offs* offsets);/*!< in: record descriptor */
# ifdef UNIV_BTR_PRINT
/***************************************************************//**
This is used to print the contents of the directory for
@@ -1187,7 +1190,7 @@ ibool
page_rec_validate(
/*==============*/
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets);/*!< in: array returned by rec_get_offsets() */
#ifdef UNIV_DEBUG
/***************************************************************//**
Checks that the first directory slot points to the infimum record and
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index 6c12c43b237..5f69925a41a 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -173,9 +173,6 @@ page_header_set_field(
{
ut_ad(page);
ut_ad(field <= PAGE_N_RECS);
-#if 0 /* FIXME: MDEV-19344 hits this */
- ut_ad(field != PAGE_N_RECS || val);
-#endif
ut_ad(field == PAGE_N_HEAP || val < srv_page_size);
ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < srv_page_size);
@@ -359,6 +356,26 @@ page_rec_is_last(
}
/************************************************************//**
+true if distance between the records (measured in number of times we have to
+move to the next record) is at most the specified value */
+UNIV_INLINE
+bool
+page_rec_distance_is_at_most(
+/*=========================*/
+ const rec_t* left_rec,
+ const rec_t* right_rec,
+ ulint val)
+{
+ for (ulint i = 0; i <= val; i++) {
+ if (left_rec == right_rec) {
+ return (true);
+ }
+ left_rec = page_rec_get_next_const(left_rec);
+ }
+ return (false);
+}
+
+/************************************************************//**
true if the record is the second last user record on a page.
@return true if the second last user record */
UNIV_INLINE
@@ -660,6 +677,7 @@ page_rec_get_next_low(
}
ut_ad(page_rec_is_infimum(rec)
+ || (!page_is_leaf(page) && !page_has_prev(page))
|| !(rec_get_info_bits(page + offs, comp)
& REC_INFO_MIN_REC_FLAG));
@@ -1004,7 +1022,7 @@ page_mem_free(
rec_t* rec, /*!< in: pointer to the
(origin of) record */
const dict_index_t* index, /*!< in: index of rec */
- const ulint* offsets) /*!< in: array returned by
+ const rec_offs* offsets) /*!< in: array returned by
rec_get_offsets() */
{
rec_t* free;
diff --git a/storage/innobase/include/page0size.h b/storage/innobase/include/page0size.h
index eb11db7781d..74fcfb106ea 100644
--- a/storage/innobase/include/page0size.h
+++ b/storage/innobase/include/page0size.h
@@ -34,7 +34,7 @@ Created Nov 14, 2013 Vasil Dimov
/** A BLOB field reference full of zero, for use in assertions and
tests.Initially, BLOB field references are set to zero, in
dtuple_convert_big_rec(). */
-extern const byte field_ref_zero[FIELD_REF_SIZE];
+extern const byte field_ref_zero[UNIV_PAGE_SIZE_MAX];
#define PAGE_SIZE_T_SIZE_BITS 17
diff --git a/storage/innobase/include/page0types.h b/storage/innobase/include/page0types.h
index 02d0cf29ec5..0fcaebd0e43 100644
--- a/storage/innobase/include/page0types.h
+++ b/storage/innobase/include/page0types.h
@@ -28,6 +28,7 @@ Created 2/2/1994 Heikki Tuuri
#include "dict0types.h"
#include "mtr0types.h"
+#include "rem0types.h"
#include <map>
@@ -184,7 +185,7 @@ page_zip_dir_delete(
page_zip_des_t* page_zip,/*!< in/out: compressed page */
byte* rec, /*!< in: deleted record */
dict_index_t* index, /*!< in: index of rec */
- const ulint* offsets,/*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec) */
const byte* free) /*!< in: previous start of the free list */
MY_ATTRIBUTE((nonnull(1,2,3,4)));
diff --git a/storage/innobase/include/page0zip.h b/storage/innobase/include/page0zip.h
index b4d4f0e980b..f411fd0eee9 100644
--- a/storage/innobase/include/page0zip.h
+++ b/storage/innobase/include/page0zip.h
@@ -2,7 +2,7 @@
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -47,6 +47,7 @@ Created June 2005 by Marko Makela
#endif /* !UNIV_INNOCHECKSUM */
#include "buf0types.h"
+#include "rem0types.h"
#ifndef UNIV_INNOCHECKSUM
#include "dict0types.h"
@@ -287,7 +288,7 @@ page_zip_write_rec(
page_zip_des_t* page_zip,/*!< in/out: compressed page */
const byte* rec, /*!< in: record being written */
dict_index_t* index, /*!< in: the index the record belongs to */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint create) /*!< in: nonzero=insert, zero=update */
MY_ATTRIBUTE((nonnull));
@@ -312,7 +313,7 @@ page_zip_write_blob_ptr(
const byte* rec, /*!< in/out: record whose data is being
written */
dict_index_t* index, /*!< in: index of the page */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint n, /*!< in: column index */
mtr_t* mtr); /*!< in: mini-transaction handle,
or NULL if no logging is needed */
@@ -346,7 +347,7 @@ page_zip_write_trx_id_and_roll_ptr(
/*===============================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
byte* rec, /*!< in/out: record */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint trx_id_col,/*!< in: column number of TRX_ID in rec */
trx_id_t trx_id, /*!< in: transaction identifier */
roll_ptr_t roll_ptr)/*!< in: roll_ptr */
@@ -394,7 +395,7 @@ page_zip_dir_delete(
page_zip_des_t* page_zip, /*!< in/out: compressed page */
byte* rec, /*!< in: deleted record */
const dict_index_t* index, /*!< in: index of rec */
- const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec) */
const byte* free) /*!< in: previous start of
the free list */
MY_ATTRIBUTE((nonnull(1,2,3,4)));
@@ -502,15 +503,11 @@ page_zip_calc_checksum(
#endif
);
-/**********************************************************************//**
-Verify a compressed page's checksum.
-@return TRUE if the stored checksum is valid according to the value of
-innodb_checksum_algorithm */
-ibool
-page_zip_verify_checksum(
-/*=====================*/
- const void* data, /*!< in: compressed page */
- ulint size); /*!< in: size of compressed page */
+/** Validate the checksum on a ROW_FORMAT=COMPRESSED page.
+@param data ROW_FORMAT=COMPRESSED page
+@param size size of the page, in bytes
+@return whether the stored checksum matches innodb_checksum_algorithm */
+bool page_zip_verify_checksum(const byte *data, size_t size);
#ifndef UNIV_INNOCHECKSUM
/**********************************************************************//**
diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic
index 5345aa19dd5..5a3b500e2c8 100644
--- a/storage/innobase/include/page0zip.ic
+++ b/storage/innobase/include/page0zip.ic
@@ -231,7 +231,7 @@ page_zip_get_trailer_len(
ulint uncompressed_size;
ut_ad(page_zip_simple_validate(page_zip));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (!page_is_leaf(page_zip->data)) {
uncompressed_size = PAGE_ZIP_DIR_SLOT_SIZE
@@ -356,7 +356,7 @@ page_zip_write_header(
ulint pos;
ut_ad(page_zip_simple_validate(page_zip));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
pos = page_offset(str);
diff --git a/storage/innobase/include/pars0grm.h b/storage/innobase/include/pars0grm.h
index 90a7468bc9a..58d424abfdc 100644
--- a/storage/innobase/include/pars0grm.h
+++ b/storage/innobase/include/pars0grm.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
#ifndef YY_YY_PARS0GRM_TAB_H_INCLUDED
# define YY_YY_PARS0GRM_TAB_H_INCLUDED
/* Debug traces. */
@@ -58,91 +62,71 @@ extern int yydebug;
PARS_NE_TOKEN = 268,
PARS_PROCEDURE_TOKEN = 269,
PARS_IN_TOKEN = 270,
- PARS_OUT_TOKEN = 271,
- PARS_BINARY_TOKEN = 272,
- PARS_BLOB_TOKEN = 273,
- PARS_INT_TOKEN = 274,
- PARS_FLOAT_TOKEN = 275,
- PARS_CHAR_TOKEN = 276,
- PARS_IS_TOKEN = 277,
- PARS_BEGIN_TOKEN = 278,
- PARS_END_TOKEN = 279,
- PARS_IF_TOKEN = 280,
- PARS_THEN_TOKEN = 281,
- PARS_ELSE_TOKEN = 282,
- PARS_ELSIF_TOKEN = 283,
- PARS_LOOP_TOKEN = 284,
- PARS_WHILE_TOKEN = 285,
- PARS_RETURN_TOKEN = 286,
- PARS_SELECT_TOKEN = 287,
- PARS_SUM_TOKEN = 288,
- PARS_COUNT_TOKEN = 289,
- PARS_DISTINCT_TOKEN = 290,
- PARS_FROM_TOKEN = 291,
- PARS_WHERE_TOKEN = 292,
- PARS_FOR_TOKEN = 293,
- PARS_DDOT_TOKEN = 294,
- PARS_READ_TOKEN = 295,
- PARS_ORDER_TOKEN = 296,
- PARS_BY_TOKEN = 297,
- PARS_ASC_TOKEN = 298,
- PARS_DESC_TOKEN = 299,
- PARS_INSERT_TOKEN = 300,
- PARS_INTO_TOKEN = 301,
- PARS_VALUES_TOKEN = 302,
- PARS_UPDATE_TOKEN = 303,
- PARS_SET_TOKEN = 304,
- PARS_DELETE_TOKEN = 305,
- PARS_CURRENT_TOKEN = 306,
- PARS_OF_TOKEN = 307,
- PARS_CREATE_TOKEN = 308,
- PARS_TABLE_TOKEN = 309,
- PARS_INDEX_TOKEN = 310,
- PARS_UNIQUE_TOKEN = 311,
- PARS_CLUSTERED_TOKEN = 312,
- PARS_ON_TOKEN = 313,
- PARS_ASSIGN_TOKEN = 314,
- PARS_DECLARE_TOKEN = 315,
- PARS_CURSOR_TOKEN = 316,
- PARS_SQL_TOKEN = 317,
- PARS_OPEN_TOKEN = 318,
- PARS_FETCH_TOKEN = 319,
- PARS_CLOSE_TOKEN = 320,
- PARS_NOTFOUND_TOKEN = 321,
- PARS_TO_CHAR_TOKEN = 322,
- PARS_TO_NUMBER_TOKEN = 323,
- PARS_TO_BINARY_TOKEN = 324,
- PARS_BINARY_TO_NUMBER_TOKEN = 325,
- PARS_SUBSTR_TOKEN = 326,
- PARS_REPLSTR_TOKEN = 327,
- PARS_CONCAT_TOKEN = 328,
- PARS_INSTR_TOKEN = 329,
- PARS_LENGTH_TOKEN = 330,
- PARS_SYSDATE_TOKEN = 331,
- PARS_PRINTF_TOKEN = 332,
- PARS_ASSERT_TOKEN = 333,
- PARS_RND_TOKEN = 334,
- PARS_RND_STR_TOKEN = 335,
- PARS_ROW_PRINTF_TOKEN = 336,
- PARS_COMMIT_TOKEN = 337,
- PARS_ROLLBACK_TOKEN = 338,
- PARS_WORK_TOKEN = 339,
- PARS_UNSIGNED_TOKEN = 340,
- PARS_EXIT_TOKEN = 341,
- PARS_FUNCTION_TOKEN = 342,
- PARS_LOCK_TOKEN = 343,
- PARS_SHARE_TOKEN = 344,
- PARS_MODE_TOKEN = 345,
- PARS_LIKE_TOKEN = 346,
- PARS_LIKE_TOKEN_EXACT = 347,
- PARS_LIKE_TOKEN_PREFIX = 348,
- PARS_LIKE_TOKEN_SUFFIX = 349,
- PARS_LIKE_TOKEN_SUBSTR = 350,
- PARS_TABLE_NAME_TOKEN = 351,
- PARS_COMPACT_TOKEN = 352,
- PARS_BLOCK_SIZE_TOKEN = 353,
- PARS_BIGINT_TOKEN = 354,
- NEG = 355
+ PARS_INT_TOKEN = 271,
+ PARS_CHAR_TOKEN = 272,
+ PARS_IS_TOKEN = 273,
+ PARS_BEGIN_TOKEN = 274,
+ PARS_END_TOKEN = 275,
+ PARS_IF_TOKEN = 276,
+ PARS_THEN_TOKEN = 277,
+ PARS_ELSE_TOKEN = 278,
+ PARS_ELSIF_TOKEN = 279,
+ PARS_LOOP_TOKEN = 280,
+ PARS_WHILE_TOKEN = 281,
+ PARS_RETURN_TOKEN = 282,
+ PARS_SELECT_TOKEN = 283,
+ PARS_COUNT_TOKEN = 284,
+ PARS_FROM_TOKEN = 285,
+ PARS_WHERE_TOKEN = 286,
+ PARS_FOR_TOKEN = 287,
+ PARS_DDOT_TOKEN = 288,
+ PARS_ORDER_TOKEN = 289,
+ PARS_BY_TOKEN = 290,
+ PARS_ASC_TOKEN = 291,
+ PARS_DESC_TOKEN = 292,
+ PARS_INSERT_TOKEN = 293,
+ PARS_INTO_TOKEN = 294,
+ PARS_VALUES_TOKEN = 295,
+ PARS_UPDATE_TOKEN = 296,
+ PARS_SET_TOKEN = 297,
+ PARS_DELETE_TOKEN = 298,
+ PARS_CURRENT_TOKEN = 299,
+ PARS_OF_TOKEN = 300,
+ PARS_CREATE_TOKEN = 301,
+ PARS_TABLE_TOKEN = 302,
+ PARS_INDEX_TOKEN = 303,
+ PARS_UNIQUE_TOKEN = 304,
+ PARS_CLUSTERED_TOKEN = 305,
+ PARS_ON_TOKEN = 306,
+ PARS_ASSIGN_TOKEN = 307,
+ PARS_DECLARE_TOKEN = 308,
+ PARS_CURSOR_TOKEN = 309,
+ PARS_SQL_TOKEN = 310,
+ PARS_OPEN_TOKEN = 311,
+ PARS_FETCH_TOKEN = 312,
+ PARS_CLOSE_TOKEN = 313,
+ PARS_NOTFOUND_TOKEN = 314,
+ PARS_TO_BINARY_TOKEN = 315,
+ PARS_SUBSTR_TOKEN = 316,
+ PARS_CONCAT_TOKEN = 317,
+ PARS_INSTR_TOKEN = 318,
+ PARS_LENGTH_TOKEN = 319,
+ PARS_COMMIT_TOKEN = 320,
+ PARS_ROLLBACK_TOKEN = 321,
+ PARS_WORK_TOKEN = 322,
+ PARS_EXIT_TOKEN = 323,
+ PARS_FUNCTION_TOKEN = 324,
+ PARS_LOCK_TOKEN = 325,
+ PARS_SHARE_TOKEN = 326,
+ PARS_MODE_TOKEN = 327,
+ PARS_LIKE_TOKEN = 328,
+ PARS_LIKE_TOKEN_EXACT = 329,
+ PARS_LIKE_TOKEN_PREFIX = 330,
+ PARS_LIKE_TOKEN_SUFFIX = 331,
+ PARS_LIKE_TOKEN_SUBSTR = 332,
+ PARS_TABLE_NAME_TOKEN = 333,
+ PARS_BIGINT_TOKEN = 334,
+ NEG = 335
};
#endif
diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h
index f74d3700eca..f54c50e5b85 100644
--- a/storage/innobase/include/pars0pars.h
+++ b/storage/innobase/include/pars0pars.h
@@ -48,29 +48,15 @@ extern int yydebug;
NOT re-entrant */
extern sym_tab_t* pars_sym_tab_global;
-extern pars_res_word_t pars_to_char_token;
-extern pars_res_word_t pars_to_number_token;
extern pars_res_word_t pars_to_binary_token;
-extern pars_res_word_t pars_binary_to_number_token;
extern pars_res_word_t pars_substr_token;
-extern pars_res_word_t pars_replstr_token;
extern pars_res_word_t pars_concat_token;
extern pars_res_word_t pars_length_token;
extern pars_res_word_t pars_instr_token;
-extern pars_res_word_t pars_sysdate_token;
-extern pars_res_word_t pars_printf_token;
-extern pars_res_word_t pars_assert_token;
-extern pars_res_word_t pars_rnd_token;
-extern pars_res_word_t pars_rnd_str_token;
extern pars_res_word_t pars_count_token;
-extern pars_res_word_t pars_sum_token;
-extern pars_res_word_t pars_distinct_token;
-extern pars_res_word_t pars_binary_token;
-extern pars_res_word_t pars_blob_token;
extern pars_res_word_t pars_int_token;
extern pars_res_word_t pars_bigint_token;
extern pars_res_word_t pars_char_token;
-extern pars_res_word_t pars_float_token;
extern pars_res_word_t pars_update_token;
extern pars_res_word_t pars_asc_token;
extern pars_res_word_t pars_desc_token;
@@ -236,17 +222,6 @@ pars_insert_statement(
que_node_t* values_list, /*!< in: value expression list or NULL */
sel_node_t* select); /*!< in: select condition or NULL */
/*********************************************************************//**
-Parses a procedure parameter declaration.
-@return own: symbol table node of type SYM_VAR */
-sym_node_t*
-pars_parameter_declaration(
-/*=======================*/
- sym_node_t* node, /*!< in: symbol table node allocated for the
- id of the parameter */
- ulint param_type,
- /*!< in: PARS_INPUT or PARS_OUTPUT */
- pars_res_word_t* type); /*!< in: pointer to a type token */
-/*********************************************************************//**
Parses an elsif element.
@return elsif node */
elsif_node_t*
@@ -358,8 +333,6 @@ pars_column_def(
pars_res_word_t* type, /*!< in: data type */
sym_node_t* len, /*!< in: length of column, or
NULL */
- void* is_unsigned, /*!< in: if not NULL, column
- is of type UNSIGNED. */
void* is_not_null); /*!< in: if not NULL, column
is of type NOT NULL. */
/*********************************************************************//**
@@ -370,9 +343,7 @@ pars_create_table(
/*==============*/
sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_defs, /*!< in: list of column names */
- sym_node_t* compact, /* in: non-NULL if COMPACT table. */
- sym_node_t* block_size); /* in: block size (can be NULL) */
+ sym_node_t* column_defs); /*!< in: list of column names */
/*********************************************************************//**
Parses an index creation operation.
@return index create subgraph */
@@ -394,7 +365,6 @@ pars_procedure_definition(
/*======================*/
sym_node_t* sym_node, /*!< in: procedure id node in the symbol
table */
- sym_node_t* param_list, /*!< in: parameter declaration list */
que_node_t* stat_list); /*!< in: statement list */
/*************************************************************//**
@@ -672,7 +642,6 @@ struct proc_node_t{
que_common_t common; /*!< type: QUE_NODE_PROC */
sym_node_t* proc_id; /*!< procedure name symbol in the symbol
table of this same procedure */
- sym_node_t* param_list; /*!< input and output parameters */
que_node_t* stat_list; /*!< statement list */
sym_tab_t* sym_tab; /*!< symbol table of this procedure */
};
@@ -747,7 +716,7 @@ struct col_assign_node_t{
#define PARS_FUNC_LOGICAL 2 /*!< AND, OR, NOT */
#define PARS_FUNC_CMP 3 /*!< comparison operators */
#define PARS_FUNC_PREDEFINED 4 /*!< TO_NUMBER, SUBSTR, ... */
-#define PARS_FUNC_AGGREGATE 5 /*!< COUNT, DISTINCT, SUM */
+#define PARS_FUNC_AGGREGATE 5 /*!< COUNT */
#define PARS_FUNC_OTHER 6 /*!< these are not real functions,
e.g., := */
/* @} */
diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
index 8489551e64d..262be4d30a9 100644
--- a/storage/innobase/include/que0que.h
+++ b/storage/innobase/include/que0que.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -35,9 +35,6 @@ Created 5/27/1996 Heikki Tuuri
#include "row0types.h"
#include "pars0types.h"
-/** Mutex protecting the query threads. */
-extern ib_mutex_t que_thr_mutex;
-
/***********************************************************************//**
Creates a query graph fork node.
@return own: fork node */
@@ -169,16 +166,6 @@ trx_t*
thr_get_trx(
/*========*/
que_thr_t* thr); /*!< in: query thread */
-/*******************************************************************//**
-Determines if this thread is rolling back an incomplete transaction
-in crash recovery.
-@return TRUE if thr is rolling back an incomplete transaction in crash
-recovery */
-UNIV_INLINE
-ibool
-thr_is_recv(
-/*========*/
- const que_thr_t* thr); /*!< in: query thread */
/***********************************************************************//**
Gets the type of a graph node. */
UNIV_INLINE
diff --git a/storage/innobase/include/que0que.ic b/storage/innobase/include/que0que.ic
index 5b775820df7..1c3ac242bf2 100644
--- a/storage/innobase/include/que0que.ic
+++ b/storage/innobase/include/que0que.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -36,20 +37,6 @@ thr_get_trx(
return(thr->graph->trx);
}
-/*******************************************************************//**
-Determines if this thread is rolling back an incomplete transaction
-in crash recovery.
-@return TRUE if thr is rolling back an incomplete transaction in crash
-recovery */
-UNIV_INLINE
-ibool
-thr_is_recv(
-/*========*/
- const que_thr_t* thr) /*!< in: query thread */
-{
- return(trx_is_recv(thr->graph->trx));
-}
-
/***********************************************************************//**
Gets the first thr in a fork. */
UNIV_INLINE
diff --git a/storage/innobase/include/rem0cmp.h b/storage/innobase/include/rem0cmp.h
index 9582b0df393..65504d14416 100644
--- a/storage/innobase/include/rem0cmp.h
+++ b/storage/innobase/include/rem0cmp.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -80,7 +80,7 @@ cmp_dfield_dfield(
/** Compare a GIS data tuple to a physical record.
@param[in] dtuple data tuple
-@param[in] rec B-tree record
+@param[in] rec R-tree record
@param[in] offsets rec_get_offsets(rec)
@param[in] mode compare mode
@retval negative if dtuple is less than rec */
@@ -89,7 +89,7 @@ cmp_dtuple_rec_with_gis(
/*====================*/
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
page_cur_mode_t mode)
MY_ATTRIBUTE((nonnull));
@@ -105,7 +105,7 @@ int
cmp_dtuple_rec_with_gis_internal(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets);
+ const rec_offs* offsets);
/** Compare a data tuple to a physical record.
@param[in] dtuple data tuple
@@ -121,7 +121,7 @@ int
cmp_dtuple_rec_with_match_low(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint n_cmp,
ulint* matched_fields)
MY_ATTRIBUTE((nonnull));
@@ -145,7 +145,7 @@ cmp_dtuple_rec_with_match_bytes(
const dtuple_t* dtuple,
const rec_t* rec,
const dict_index_t* index,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint* matched_fields,
ulint* matched_bytes)
MY_ATTRIBUTE((warn_unused_result));
@@ -162,7 +162,7 @@ int
cmp_dtuple_rec(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets);
+ const rec_offs* offsets);
/**************************************************************//**
Checks if a dtuple is a prefix of a record. The last field in dtuple
is allowed to be a prefix of the corresponding field in the record.
@@ -172,7 +172,7 @@ cmp_dtuple_is_prefix_of_rec(
/*========================*/
const dtuple_t* dtuple, /*!< in: data tuple */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets);/*!< in: array returned by rec_get_offsets() */
/** Compare two physical records that contain the same number of columns,
none of which are stored externally.
@retval positive if rec1 (including non-ordering columns) is greater than rec2
@@ -183,58 +183,40 @@ cmp_rec_rec_simple(
/*===============*/
const rec_t* rec1, /*!< in: physical record */
const rec_t* rec2, /*!< in: physical record */
- const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
- const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
+ const rec_offs* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
+ const rec_offs* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
const dict_index_t* index, /*!< in: data dictionary index */
struct TABLE* table) /*!< in: MySQL table, for reporting
duplicate key value if applicable,
or NULL */
MY_ATTRIBUTE((nonnull(1,2,3,4), warn_unused_result));
-/** Compare two B-tree records.
-@param[in] rec1 B-tree record
-@param[in] rec2 B-tree record
-@param[in] offsets1 rec_get_offsets(rec1, index)
-@param[in] offsets2 rec_get_offsets(rec2, index)
-@param[in] index B-tree index
-@param[in] nulls_unequal true if this is for index cardinality
-statistics estimation, and innodb_stats_method=nulls_unequal
-or innodb_stats_method=nulls_ignored
-@param[out] matched_fields number of completely matched fields
-within the first field not completely matched
-@return the comparison result
-@retval 0 if rec1 is equal to rec2
-@retval negative if rec1 is less than rec2
-@retval positive if rec2 is greater than rec2 */
-int
-cmp_rec_rec_with_match(
- const rec_t* rec1,
- const rec_t* rec2,
- const ulint* offsets1,
- const ulint* offsets2,
- const dict_index_t* index,
- bool nulls_unequal,
- ulint* matched_fields);
-/** Compare two B-tree records.
+/** Compare two B-tree or R-tree records.
Only the common first fields are compared, and externally stored field
are treated as equal.
-@param[in] rec1 B-tree record
-@param[in] rec2 B-tree record
+@param[in] rec1 record (possibly not on an index page)
+@param[in] rec2 B-tree or R-tree record in an index page
@param[in] offsets1 rec_get_offsets(rec1, index)
@param[in] offsets2 rec_get_offsets(rec2, index)
+@param[in] nulls_unequal true if this is for index cardinality
+ statistics estimation with
+ innodb_stats_method=nulls_unequal
+ or innodb_stats_method=nulls_ignored
@param[out] matched_fields number of completely matched fields
within the first field not completely matched
-@return positive, 0, negative if rec1 is greater, equal, less, than rec2,
-respectively */
-UNIV_INLINE
+@retval 0 if rec1 is equal to rec2
+@retval negative if rec1 is less than rec2
+@retval positive if rec1 is greater than rec2 */
int
cmp_rec_rec(
const rec_t* rec1,
const rec_t* rec2,
- const ulint* offsets1,
- const ulint* offsets2,
+ const rec_offs* offsets1,
+ const rec_offs* offsets2,
const dict_index_t* index,
- ulint* matched_fields = NULL);
+ bool nulls_unequal = false,
+ ulint* matched_fields = NULL)
+ MY_ATTRIBUTE((nonnull(1,2,3,4,5)));
/** Compare two data fields.
@param[in] dfield1 data field
diff --git a/storage/innobase/include/rem0cmp.ic b/storage/innobase/include/rem0cmp.ic
index 2412d22e8fa..4230543615a 100644
--- a/storage/innobase/include/rem0cmp.ic
+++ b/storage/innobase/include/rem0cmp.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -52,40 +53,6 @@ cmp_dfield_dfield(
dfield_get_len(dfield2)));
}
-/** Compare two B-tree records.
-Only the common first fields are compared, and externally stored field
-are treated as equal.
-@param[in] rec1 B-tree record
-@param[in] rec2 B-tree record
-@param[in] offsets1 rec_get_offsets(rec1, index)
-@param[in] offsets2 rec_get_offsets(rec2, index)
-@param[out] matched_fields number of completely matched fields
- within the first field not completely matched
-@return positive, 0, negative if rec1 is greater, equal, less, than rec2,
-respectively */
-UNIV_INLINE
-int
-cmp_rec_rec(
- const rec_t* rec1,
- const rec_t* rec2,
- const ulint* offsets1,
- const ulint* offsets2,
- const dict_index_t* index,
- ulint* matched_fields)
-{
- ulint match_f;
- int ret;
-
- ret = cmp_rec_rec_with_match(
- rec1, rec2, offsets1, offsets2, index, false, &match_f);
-
- if (matched_fields != NULL) {
- *matched_fields = match_f;
- }
-
- return(ret);
-}
-
/** Compare two data fields.
@param[in] dfield1 data field
@param[in] dfield2 data field
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index c81f0479ce6..81a09afa3d8 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -71,29 +71,72 @@ The status is stored in the low-order bits. */
/* Length of a B-tree node pointer, in bytes */
#define REC_NODE_PTR_SIZE 4
+#ifndef UNIV_INNOCHECKSUM
/** SQL null flag in a 1-byte offset of ROW_FORMAT=REDUNDANT records */
-#define REC_1BYTE_SQL_NULL_MASK 0x80UL
+static const rec_offs REC_1BYTE_SQL_NULL_MASK= 0x80;
/** SQL null flag in a 2-byte offset of ROW_FORMAT=REDUNDANT records */
-#define REC_2BYTE_SQL_NULL_MASK 0x8000UL
+static const rec_offs REC_2BYTE_SQL_NULL_MASK= 0x8000;
/** In a 2-byte offset of ROW_FORMAT=REDUNDANT records, the second most
significant bit denotes that the tail of a field is stored off-page. */
-#define REC_2BYTE_EXTERN_MASK 0x4000UL
+static const rec_offs REC_2BYTE_EXTERN_MASK= 0x4000;
+
+static const size_t RECORD_OFFSET= 2;
+static const size_t INDEX_OFFSET=
+ RECORD_OFFSET + sizeof(rec_t *) / sizeof(rec_offs);
-#ifdef UNIV_DEBUG
-/* Length of the rec_get_offsets() header */
-# define REC_OFFS_HEADER_SIZE 4
-#else /* UNIV_DEBUG */
/* Length of the rec_get_offsets() header */
-# define REC_OFFS_HEADER_SIZE 2
+static const size_t REC_OFFS_HEADER_SIZE=
+#ifdef UNIV_DEBUG
+ sizeof(rec_t *) / sizeof(rec_offs) +
+ sizeof(dict_index_t *) / sizeof(rec_offs) +
#endif /* UNIV_DEBUG */
+ 2;
/* Number of elements that should be initially allocated for the
offsets[] array, first passed to rec_get_offsets() */
-#define REC_OFFS_NORMAL_SIZE OFFS_IN_REC_NORMAL_SIZE
-#define REC_OFFS_SMALL_SIZE 10
+static const size_t REC_OFFS_NORMAL_SIZE= 300;
+static const size_t REC_OFFS_SMALL_SIZE= 18;
+static const size_t REC_OFFS_SEC_INDEX_SIZE=
+ /* PK max key parts */ 16 + /* sec idx max key parts */ 16 +
+ /* child page number for non-leaf pages */ 1;
+
+/* Offset consists of two parts: 2 upper bits is type and all other bits is
+value */
+
+enum field_type_t
+{
+ /** normal field */
+ STORED_IN_RECORD= 0 << 14,
+ /** this field is stored off-page */
+ STORED_OFFPAGE= 1 << 14,
+ /** just an SQL NULL */
+ SQL_NULL= 2 << 14
+};
+
+/** without 2 upper bits */
+static const rec_offs DATA_MASK= 0x3fff;
+/** 2 upper bits */
+static const rec_offs TYPE_MASK= ~DATA_MASK;
+inline field_type_t get_type(rec_offs n)
+{
+ return static_cast<field_type_t>(n & TYPE_MASK);
+}
+inline void set_type(rec_offs &n, field_type_t type)
+{
+ n= (n & DATA_MASK) | static_cast<rec_offs>(type);
+}
+inline rec_offs get_value(rec_offs n) { return n & DATA_MASK; }
+inline rec_offs combine(rec_offs value, field_type_t type)
+{
+ return get_value(value) | static_cast<rec_offs>(type);
+}
+
+/** Compact flag ORed to the extra size returned by rec_offs_base()[0] */
+static const rec_offs REC_OFFS_COMPACT= 1 << 15;
+/** External flag in offsets returned by rec_offs_base()[0] */
+static const rec_offs REC_OFFS_EXTERNAL= 1 << 14;
-#ifndef UNIV_INNOCHECKSUM
/******************************************************//**
The following function is used to get the pointer of the next chained record
on the same page.
@@ -398,7 +441,7 @@ offsets form. If the field is SQL null, the flag is ORed in the returned
value.
@return offset of the start of the field, SQL null flag ORed */
UNIV_INLINE
-ulint
+uint8_t
rec_1_get_field_end_info(
/*=====================*/
const rec_t* rec, /*!< in: record */
@@ -412,7 +455,7 @@ value.
@return offset of the start of the field, SQL null flag and extern
storage flag ORed */
UNIV_INLINE
-ulint
+rec_offs
rec_2_get_field_end_info(
/*=====================*/
const rec_t* rec, /*!< in: record */
@@ -453,11 +496,11 @@ rec_get_n_extern_new(
(ULINT_UNDEFINED to compute all offsets)
@param[in,out] heap memory heap
@return the new offsets */
-ulint*
+rec_offs*
rec_get_offsets_func(
const rec_t* rec,
const dict_index_t* index,
- ulint* offsets,
+ rec_offs* offsets,
#ifdef UNIV_DEBUG
bool leaf,
#endif /* UNIV_DEBUG */
@@ -494,7 +537,7 @@ rec_get_offsets_reverse(
const dict_index_t* index, /*!< in: record descriptor */
ulint node_ptr,/*!< in: nonzero=node pointer,
0=leaf node */
- ulint* offsets)/*!< in/out: array consisting of
+ rec_offs* offsets)/*!< in/out: array consisting of
offsets[0] allocated elements */
MY_ATTRIBUTE((nonnull));
#ifdef UNIV_DEBUG
@@ -507,7 +550,7 @@ rec_offs_validate(
/*==============*/
const rec_t* rec, /*!< in: record or NULL */
const dict_index_t* index, /*!< in: record descriptor or NULL */
- const ulint* offsets)/*!< in: array returned by
+ const rec_offs* offsets)/*!< in: array returned by
rec_get_offsets() */
MY_ATTRIBUTE((nonnull(3), warn_unused_result));
/************************************************************//**
@@ -519,7 +562,7 @@ rec_offs_make_valid(
/*================*/
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in: array returned by
+ rec_offs* offsets)/*!< in: array returned by
rec_get_offsets() */
MY_ATTRIBUTE((nonnull));
#else
@@ -557,10 +600,10 @@ The following function is used to get an offset to the nth
data field in a record.
@return offset from the origin of rec */
UNIV_INLINE
-ulint
+rec_offs
rec_get_nth_field_offs(
/*===================*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n, /*!< in: index of the field */
ulint* len) /*!< out: length of the field; UNIV_SQL_NULL
if SQL null */
@@ -575,7 +618,7 @@ UNIV_INLINE
ulint
rec_offs_comp(
/*==========*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Determine if the offsets are for a record containing
@@ -585,7 +628,7 @@ UNIV_INLINE
ulint
rec_offs_any_extern(
/*================*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Determine if the offsets are for a record containing null BLOB pointers.
@@ -595,7 +638,7 @@ const byte*
rec_offs_any_null_extern(
/*=====================*/
const rec_t* rec, /*!< in: record */
- const ulint* offsets) /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets) /*!< in: rec_get_offsets(rec) */
MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Returns nonzero if the extern bit is set in nth field of rec.
@@ -604,7 +647,7 @@ UNIV_INLINE
ulint
rec_offs_nth_extern(
/*================*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
MY_ATTRIBUTE((warn_unused_result));
@@ -613,7 +656,7 @@ rec_offs_nth_extern(
@param[in] n nth field */
void
rec_offs_make_nth_extern(
- ulint* offsets,
+ rec_offs* offsets,
const ulint n);
/******************************************************//**
Returns nonzero if the SQL NULL bit is set in nth field of rec.
@@ -622,7 +665,7 @@ UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
@@ -632,7 +675,7 @@ UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
MY_ATTRIBUTE((warn_unused_result));
@@ -643,7 +686,7 @@ UNIV_INLINE
ulint
rec_offs_n_extern(
/*==============*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/***********************************************************//**
This is used to modify the value of an already existing field in a record.
@@ -656,7 +699,7 @@ void
rec_set_nth_field(
/*==============*/
rec_t* rec, /*!< in: record */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n, /*!< in: index number of the field */
const void* data, /*!< in: pointer to the data if not SQL null */
ulint len) /*!< in: length of the data or UNIV_SQL_NULL.
@@ -685,7 +728,7 @@ UNIV_INLINE
ulint
rec_offs_get_n_alloc(
/*=================*/
- const ulint* offsets)/*!< in: array for rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array for rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
The following function sets the number of allocated elements
@@ -694,7 +737,7 @@ UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
- ulint* offsets, /*!< out: array for rec_get_offsets(),
+ rec_offs*offsets, /*!< out: array for rec_get_offsets(),
must be allocated */
ulint n_alloc) /*!< in: number of elements */
MY_ATTRIBUTE((nonnull));
@@ -707,7 +750,7 @@ UNIV_INLINE
ulint
rec_offs_n_fields(
/*==============*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
The following function returns the data size of a physical
@@ -719,7 +762,7 @@ UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns the total size of record minus data size of record.
@@ -730,7 +773,7 @@ UNIV_INLINE
ulint
rec_offs_extra_size(
/*================*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns the total size of a physical record.
@@ -739,7 +782,7 @@ UNIV_INLINE
ulint
rec_offs_size(
/*==========*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
#ifdef UNIV_DEBUG
/**********************************************************//**
@@ -750,7 +793,7 @@ byte*
rec_get_start(
/*==========*/
const rec_t* rec, /*!< in: pointer to record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns a pointer to the end of the record.
@@ -760,7 +803,7 @@ byte*
rec_get_end(
/*========*/
const rec_t* rec, /*!< in: pointer to record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
#else /* UNIV_DEBUG */
# define rec_get_start(rec, offsets) ((rec) - rec_offs_extra_size(offsets))
@@ -777,7 +820,7 @@ rec_t*
rec_copy(
void* buf,
const rec_t* rec,
- const ulint* offsets);
+ const rec_offs* offsets);
/** Determine the size of a data tuple prefix in a temporary file.
@param[in] index clustered or secondary index
@@ -801,7 +844,7 @@ rec_init_offsets_temp(
/*==================*/
const rec_t* rec, /*!< in: temporary file record */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in/out: array of offsets;
+ rec_offs* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
MY_ATTRIBUTE((nonnull));
@@ -843,7 +886,7 @@ UNIV_INLINE
ulint
rec_fold(
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint n_fields,
ulint n_bytes,
index_id_t tree_id)
@@ -944,7 +987,7 @@ ibool
rec_validate(
/*=========*/
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Prints an old-style physical record. */
@@ -961,7 +1004,7 @@ rec_print_mbr_rec(
/*==========*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Prints a physical record. */
@@ -970,7 +1013,7 @@ rec_print_new(
/*==========*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Prints a physical record. */
@@ -992,7 +1035,7 @@ rec_print(
std::ostream& o,
const rec_t* rec,
ulint info,
- const ulint* offsets);
+ const rec_offs* offsets);
/** Wrapper for pretty-printing a record */
struct rec_index_print
@@ -1019,31 +1062,32 @@ operator<<(std::ostream& o, const rec_index_print& r);
struct rec_offsets_print
{
/** Constructor */
- rec_offsets_print(const rec_t* rec, const ulint* offsets) :
+ rec_offsets_print(const rec_t* rec, const rec_offs* offsets) :
m_rec(rec), m_offsets(offsets)
{}
/** Record */
const rec_t* m_rec;
/** Offsets to each field */
- const ulint* m_offsets;
+ const rec_offs* m_offsets;
};
/** Display a record.
@param[in,out] o output stream
@param[in] r record to display
@return the output stream */
+ATTRIBUTE_COLD
std::ostream&
operator<<(std::ostream& o, const rec_offsets_print& r);
-# ifndef DBUG_OFF
/** Pretty-printer of records and tuples */
class rec_printer : public std::ostringstream {
public:
/** Construct a pretty-printed record.
@param rec record with header
@param offsets rec_get_offsets(rec, ...) */
- rec_printer(const rec_t* rec, const ulint* offsets)
+ ATTRIBUTE_COLD
+ rec_printer(const rec_t* rec, const rec_offs* offsets)
:
std::ostringstream ()
{
@@ -1056,7 +1100,8 @@ public:
@param rec record, possibly lacking header
@param info rec_get_info_bits(rec)
@param offsets rec_get_offsets(rec, ...) */
- rec_printer(const rec_t* rec, ulint info, const ulint* offsets)
+ ATTRIBUTE_COLD
+ rec_printer(const rec_t* rec, ulint info, const rec_offs* offsets)
:
std::ostringstream ()
{
@@ -1065,6 +1110,7 @@ public:
/** Construct a pretty-printed tuple.
@param tuple data tuple */
+ ATTRIBUTE_COLD
rec_printer(const dtuple_t* tuple)
:
std::ostringstream ()
@@ -1075,6 +1121,7 @@ public:
/** Construct a pretty-printed tuple.
@param field array of data tuple fields
@param n number of fields */
+ ATTRIBUTE_COLD
rec_printer(const dfield_t* field, ulint n)
:
std::ostringstream ()
@@ -1091,7 +1138,7 @@ private:
/** Assignment operator */
rec_printer& operator=(const rec_printer& other);
};
-# endif /* !DBUG_OFF */
+
# ifdef UNIV_DEBUG
/** Read the DB_TRX_ID of a clustered index record.
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 4d2c00de48f..f65bca8181d 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -30,15 +30,6 @@ Created 5/30/1994 Heikki Tuuri
#include "dict0boot.h"
#include "btr0types.h"
-/* Compact flag ORed to the extra size returned by rec_get_offsets() */
-#define REC_OFFS_COMPACT ((ulint) 1 << 31)
-/* SQL NULL flag in offsets returned by rec_get_offsets() */
-#define REC_OFFS_SQL_NULL ((ulint) 1 << 31)
-/* External flag in offsets returned by rec_get_offsets() */
-#define REC_OFFS_EXTERNAL ((ulint) 1 << 30)
-/* Mask for offsets returned by rec_get_offsets() */
-#define REC_OFFS_MASK (REC_OFFS_EXTERNAL - 1)
-
/* Offsets of the bit-fields in an old-style record. NOTE! In the table the
most significant bytes and bits are written below less significant.
@@ -873,7 +864,7 @@ offsets form. If the field is SQL null, the flag is ORed in the returned
value.
@return offset of the start of the field, SQL null flag ORed */
UNIV_INLINE
-ulint
+uint8_t
rec_1_get_field_end_info(
/*=====================*/
const rec_t* rec, /*!< in: record */
@@ -892,7 +883,7 @@ value.
@return offset of the start of the field, SQL null flag and extern
storage flag ORed */
UNIV_INLINE
-ulint
+rec_offs
rec_2_get_field_end_info(
/*=====================*/
const rec_t* rec, /*!< in: record */
@@ -931,13 +922,13 @@ UNIV_INLINE
ulint
rec_offs_get_n_alloc(
/*=================*/
- const ulint* offsets)/*!< in: array for rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array for rec_get_offsets() */
{
ulint n_alloc;
ut_ad(offsets);
n_alloc = offsets[0];
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
- UNIV_MEM_ASSERT_W(offsets, n_alloc * sizeof *offsets);
+ MEM_CHECK_ADDRESSABLE(offsets, n_alloc * sizeof *offsets);
return(n_alloc);
}
@@ -948,13 +939,13 @@ UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
- ulint* offsets, /*!< out: array for rec_get_offsets(),
+ rec_offs*offsets, /*!< out: array for rec_get_offsets(),
must be allocated */
ulint n_alloc) /*!< in: number of elements */
{
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
- UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets);
- offsets[0] = n_alloc;
+ MEM_UNDEFINED(offsets, n_alloc * sizeof *offsets);
+ offsets[0] = static_cast<rec_offs>(n_alloc);
}
/**********************************************************//**
@@ -964,7 +955,7 @@ UNIV_INLINE
ulint
rec_offs_n_fields(
/*==============*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
ut_ad(offsets);
@@ -985,22 +976,22 @@ rec_offs_validate(
/*==============*/
const rec_t* rec, /*!< in: record or NULL */
const dict_index_t* index, /*!< in: record descriptor or NULL */
- const ulint* offsets)/*!< in: array returned by
+ const rec_offs* offsets)/*!< in: array returned by
rec_get_offsets() */
{
ulint i = rec_offs_n_fields(offsets);
ulint last = ULINT_MAX;
- ulint comp = *rec_offs_base(offsets) & REC_OFFS_COMPACT;
+ bool comp = rec_offs_base(offsets)[0] & REC_OFFS_COMPACT;
if (rec) {
- ut_ad((ulint) rec == offsets[2]);
+ ut_ad(!memcmp(&rec, &offsets[RECORD_OFFSET], sizeof(rec)));
if (!comp) {
ut_a(rec_get_n_fields_old(rec) >= i);
}
}
if (index) {
ulint max_n_fields;
- ut_ad((ulint) index == offsets[3]);
+ ut_ad(!memcmp(&index, &offsets[INDEX_OFFSET], sizeof(index)));
max_n_fields = ut_max(
dict_index_get_n_fields(index),
dict_index_get_n_unique_in_tree(index) + 1);
@@ -1025,7 +1016,7 @@ rec_offs_validate(
ut_a(!index->n_def || i <= max_n_fields);
}
while (i--) {
- ulint curr = rec_offs_base(offsets)[1 + i] & REC_OFFS_MASK;
+ rec_offs curr = get_value(rec_offs_base(offsets)[1 + i]);
ut_a(curr <= last);
last = curr;
}
@@ -1041,15 +1032,15 @@ rec_offs_make_valid(
/*================*/
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in: array returned by
+ rec_offs* offsets)/*!< in: array returned by
rec_get_offsets() */
{
ut_ad(rec);
ut_ad(index);
ut_ad(offsets);
ut_ad(rec_get_n_fields(rec, index) >= rec_offs_n_fields(offsets));
- offsets[2] = (ulint) rec;
- offsets[3] = (ulint) index;
+ memcpy(&offsets[RECORD_OFFSET], &rec, sizeof(rec));
+ memcpy(&offsets[INDEX_OFFSET], &index, sizeof(index));
}
#endif /* UNIV_DEBUG */
@@ -1058,34 +1049,26 @@ The following function is used to get an offset to the nth
data field in a record.
@return offset from the origin of rec */
UNIV_INLINE
-ulint
+rec_offs
rec_get_nth_field_offs(
/*===================*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n, /*!< in: index of the field */
ulint* len) /*!< out: length of the field; UNIV_SQL_NULL
if SQL null */
{
- ulint offs;
- ulint length;
ut_ad(n < rec_offs_n_fields(offsets));
- if (n == 0) {
- offs = 0;
- } else {
- offs = rec_offs_base(offsets)[n] & REC_OFFS_MASK;
- }
+ rec_offs offs = n == 0 ? 0 : get_value(rec_offs_base(offsets)[n]);
+ rec_offs next_offs = rec_offs_base(offsets)[1 + n];
- length = rec_offs_base(offsets)[1 + n];
-
- if (length & REC_OFFS_SQL_NULL) {
- length = UNIV_SQL_NULL;
+ if (get_type(next_offs) == SQL_NULL) {
+ *len = UNIV_SQL_NULL;
} else {
- length &= REC_OFFS_MASK;
- length -= offs;
+
+ *len = get_value(next_offs) - offs;
}
- *len = length;
return(offs);
}
@@ -1097,7 +1080,7 @@ UNIV_INLINE
ulint
rec_offs_comp(
/*==========*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);
@@ -1111,7 +1094,7 @@ UNIV_INLINE
ulint
rec_offs_any_extern(
/*================*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
return(*rec_offs_base(offsets) & REC_OFFS_EXTERNAL);
@@ -1125,7 +1108,7 @@ const byte*
rec_offs_any_null_extern(
/*=====================*/
const rec_t* rec, /*!< in: record */
- const ulint* offsets) /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets) /*!< in: rec_get_offsets(rec) */
{
ulint i;
ut_ad(rec_offs_validate(rec, NULL, offsets));
@@ -1160,12 +1143,12 @@ UNIV_INLINE
ulint
rec_offs_nth_extern(
/*================*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
- return(rec_offs_base(offsets)[1 + n] & REC_OFFS_EXTERNAL);
+ return get_type(rec_offs_base(offsets)[1 + n]) == STORED_OFFPAGE;
}
/******************************************************//**
@@ -1175,12 +1158,12 @@ UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
- return(rec_offs_base(offsets)[1 + n] & REC_OFFS_SQL_NULL);
+ return get_type(rec_offs_base(offsets)[1 + n]) == SQL_NULL;
}
/******************************************************//**
@@ -1190,16 +1173,16 @@ UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
if (!n) {
- return(rec_offs_base(offsets)[1 + n] & REC_OFFS_MASK);
+ return get_value(rec_offs_base(offsets)[1 + n]);
}
- return((rec_offs_base(offsets)[1 + n] - rec_offs_base(offsets)[n])
- & REC_OFFS_MASK);
+ return get_value((rec_offs_base(offsets)[1 + n]))
+ - get_value(rec_offs_base(offsets)[n]);
}
/******************************************************//**
@@ -1209,7 +1192,7 @@ UNIV_INLINE
ulint
rec_offs_n_extern(
/*==============*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n = 0;
@@ -1407,7 +1390,7 @@ void
rec_set_nth_field(
/*==============*/
rec_t* rec, /*!< in: record */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n, /*!< in: index number of the field */
const void* data, /*!< in: pointer to the data
if not SQL null */
@@ -1462,16 +1445,16 @@ UNIV_INLINE
void
rec_offs_set_n_fields(
/*==================*/
- ulint* offsets, /*!< in/out: array returned by
+ rec_offs* offsets, /*!< in/out: array returned by
rec_get_offsets() */
- ulint n_fields) /*!< in: number of fields */
+ ulint n_fields) /*!< in: number of fields */
{
ut_ad(offsets);
ut_ad(n_fields > 0);
ut_ad(n_fields <= REC_MAX_N_FIELDS);
ut_ad(n_fields + REC_OFFS_HEADER_SIZE
<= rec_offs_get_n_alloc(offsets));
- offsets[1] = n_fields;
+ offsets[1] = static_cast<rec_offs>(n_fields);
}
/**********************************************************//**
@@ -1484,13 +1467,12 @@ UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint size;
ut_ad(rec_offs_validate(NULL, NULL, offsets));
- size = rec_offs_base(offsets)[rec_offs_n_fields(offsets)]
- & REC_OFFS_MASK;
+ size = get_value(rec_offs_base(offsets)[rec_offs_n_fields(offsets)]);
ut_ad(size < UNIV_PAGE_SIZE);
return(size);
}
@@ -1504,7 +1486,7 @@ UNIV_INLINE
ulint
rec_offs_extra_size(
/*================*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint size;
ut_ad(rec_offs_validate(NULL, NULL, offsets));
@@ -1520,7 +1502,7 @@ UNIV_INLINE
ulint
rec_offs_size(
/*==========*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
return(rec_offs_data_size(offsets) + rec_offs_extra_size(offsets));
}
@@ -1534,7 +1516,7 @@ byte*
rec_get_end(
/*========*/
const rec_t* rec, /*!< in: pointer to record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
return(const_cast<rec_t*>(rec + rec_offs_data_size(offsets)));
@@ -1548,7 +1530,7 @@ byte*
rec_get_start(
/*==========*/
const rec_t* rec, /*!< in: pointer to record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
return(const_cast<rec_t*>(rec - rec_offs_extra_size(offsets)));
@@ -1565,7 +1547,7 @@ rec_t*
rec_copy(
void* buf,
const rec_t* rec,
- const ulint* offsets)
+ const rec_offs* offsets)
{
ulint extra_len;
ulint data_len;
@@ -1644,6 +1626,11 @@ rec_get_converted_size(
data_size = dtuple_get_data_size(dtuple, 0);
+ /* If primary key is being updated then the new record inherits
+ externally stored fields from the delete-marked old record.
+ In that case, n_ext may be less value than
+ dtuple_get_n_ext(tuple). */
+ ut_ad(n_ext <= dtuple_get_n_ext(dtuple));
extra_size = rec_get_converted_extra_size(
data_size, dtuple_get_n_fields(dtuple), n_ext);
@@ -1696,7 +1683,7 @@ UNIV_INLINE
ulint
rec_fold(
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint n_fields,
ulint n_bytes,
index_id_t tree_id)
diff --git a/storage/innobase/include/rem0types.h b/storage/innobase/include/rem0types.h
index cc59bd91076..9172385a802 100644
--- a/storage/innobase/include/rem0types.h
+++ b/storage/innobase/include/rem0types.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -29,6 +30,9 @@ Created 5/30/1994 Heikki Tuuri
/* We define the physical record simply as an array of bytes */
typedef byte rec_t;
+/** This type represents a field offset in a rec_t* */
+typedef unsigned short int rec_offs;
+
/* Maximum values for various fields (for non-blob tuples) */
#define REC_MAX_N_FIELDS (1024 - 1)
#define REC_MAX_HEAP_NO (2 * 8192 - 1)
diff --git a/storage/innobase/include/row0ftsort.h b/storage/innobase/include/row0ftsort.h
index 1c1357e330b..84368374430 100644
--- a/storage/innobase/include/row0ftsort.h
+++ b/storage/innobase/include/row0ftsort.h
@@ -30,6 +30,7 @@ Created 10/13/2010 Jimmy Yang
#include "data0data.h"
#include "fts0fts.h"
#include "fts0priv.h"
+#include "rem0types.h"
#include "row0merge.h"
#include "btr0bulk.h"
@@ -247,7 +248,7 @@ row_merge_fts_sel_propagate(
int* sel_tree, /*<! in: selection tree */
ulint level, /*<! in: selection tree level */
const mrec_t** mrec, /*<! in: sort record */
- ulint** offsets, /*<! in: record offsets */
+ rec_offs** offsets, /*<! in: record offsets */
dict_index_t* index); /*<! in: FTS index */
/********************************************************************//**
Read sorted file containing index data tuples and insert these data
diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h
index 164f6fe1ddb..27fe442f6ff 100644
--- a/storage/innobase/include/row0ins.h
+++ b/storage/innobase/include/row0ins.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2019, 2020 MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -31,6 +31,7 @@ Created 4/20/1996 Heikki Tuuri
#include "que0types.h"
#include "trx0types.h"
#include "row0types.h"
+#include <vector>
/***************************************************************//**
Checks if foreign key constraint fails for an index entry. Sets shared locks
@@ -159,7 +160,10 @@ row_ins_step(
/* Insert node structure */
struct ins_node_t{
- que_common_t common; /*!< node type: QUE_NODE_INSERT */
+ ins_node_t() : common(QUE_NODE_INSERT, NULL), entry(entry_list.end())
+ {
+ }
+ que_common_t common; /*!< node type: QUE_NODE_INSERT */
ulint ins_type;/* INS_VALUES, INS_SEARCHED, or INS_DIRECT */
dtuple_t* row; /*!< row to insert */
dict_table_t* table; /*!< table where to insert */
@@ -169,11 +173,12 @@ struct ins_node_t{
ulint state; /*!< node execution state */
dict_index_t* index; /*!< NULL, or the next index where the index
entry should be inserted */
- dtuple_t* entry; /*!< NULL, or entry to insert in the index;
+ std::vector<dtuple_t*>
+ entry_list;/* list of entries, one for each index */
+ std::vector<dtuple_t*>::iterator
+ entry; /*!< NULL, or entry to insert in the index;
after a successful insert of the entry,
this should be reset to NULL */
- UT_LIST_BASE_NODE_T(dtuple_t)
- entry_list;/* list of entries, one for each index */
/** buffer for the system columns */
byte sys_buf[DATA_ROW_ID_LEN
+ DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN];
diff --git a/storage/innobase/include/row0log.h b/storage/innobase/include/row0log.h
index 84b7ba891b2..383975c32d3 100644
--- a/storage/innobase/include/row0log.h
+++ b/storage/innobase/include/row0log.h
@@ -132,7 +132,7 @@ row_log_table_delete(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index) */
const byte* sys) /*!< in: DB_TRX_ID,DB_ROLL_PTR that should
be logged, or NULL to use those in rec */
ATTRIBUTE_COLD __attribute__((nonnull(1,2,3)));
@@ -147,7 +147,7 @@ row_log_table_update(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index) */
const dtuple_t* old_pk);/*!< in: row_log_table_get_pk()
before the update */
@@ -163,7 +163,7 @@ row_log_table_get_pk(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index),
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index),
or NULL */
byte* sys, /*!< out: DB_TRX_ID,DB_ROLL_PTR for
row_log_table_delete(), or NULL */
@@ -180,7 +180,7 @@ row_log_table_insert(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets);/*!< in: rec_get_offsets(rec,index) */
+ const rec_offs* offsets);/*!< in: rec_get_offsets(rec,index) */
/******************************************************//**
Notes that a BLOB is being freed during online ALTER TABLE. */
void
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h
index a1719e0448e..0d48fbd2e8a 100644
--- a/storage/innobase/include/row0merge.h
+++ b/storage/innobase/include/row0merge.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -203,18 +203,6 @@ row_merge_file_destroy_low(
int fd); /*!< in: merge file descriptor */
/*********************************************************************//**
-Provide a new pathname for a table that is being renamed if it belongs to
-a file-per-table tablespace. The caller is responsible for freeing the
-memory allocated for the return value.
-@return new pathname of tablespace file, or NULL if space = 0 */
-char*
-row_make_new_pathname(
-/*==================*/
- dict_table_t* table, /*!< in: table to be renamed */
- const char* new_name) /*!< in: new name */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
-/*********************************************************************//**
Rename the tables in the data dictionary. The data dictionary must
have been locked exclusively by the caller, because the transaction
will not be committed.
@@ -489,7 +477,7 @@ row_merge_read_rec(
const mrec_t** mrec, /*!< out: pointer to merge record,
or NULL on end of list
(non-NULL on I/O error) */
- ulint* offsets,/*!< out: offsets of mrec */
+ rec_offs* offsets,/*!< out: offsets of mrec */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
MY_ATTRIBUTE((warn_unused_result));
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 60f53221c9a..d5cdd4a3f17 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -814,6 +814,8 @@ struct VCOL_STORAGE
byte *innobase_record;
byte *maria_record;
String *blob_value_storage;
+ VCOL_STORAGE(): maria_table(NULL), innobase_record(NULL),
+ maria_record(NULL), blob_value_storage(NULL) {}
};
/**
@@ -836,12 +838,48 @@ bool innobase_allocate_row_for_vcol(
dict_index_t* index,
mem_heap_t** heap,
TABLE** table,
- byte** record,
- VCOL_STORAGE** storage);
+ VCOL_STORAGE* storage);
/** Free memory allocated by innobase_allocate_row_for_vcol() */
void innobase_free_row_for_vcol(VCOL_STORAGE *storage);
+class ib_vcol_row
+{
+ VCOL_STORAGE storage;
+public:
+ mem_heap_t *heap;
+
+ ib_vcol_row(mem_heap_t *heap) : heap(heap) {}
+
+ byte *record(THD *thd, dict_index_t *index, TABLE **table)
+ {
+ if (!storage.innobase_record)
+ {
+ bool ok = innobase_allocate_row_for_vcol(thd, index, &heap, table,
+ &storage);
+ if (!ok)
+ return NULL;
+ }
+ return storage.innobase_record;
+ };
+
+ ~ib_vcol_row()
+ {
+ if (heap)
+ {
+ if (storage.innobase_record)
+ innobase_free_row_for_vcol(&storage);
+ mem_heap_free(heap);
+ }
+ }
+};
+
+/** Report virtual value computation failure in ib::error
+@param[in] row the data row
+*/
+ATTRIBUTE_COLD
+void innobase_report_computed_value_failed(dtuple_t *row);
+
/** Get the computed value by supplying the base column values.
@param[in,out] row the data row
@param[in] col virtual column
diff --git a/storage/innobase/include/row0row.h b/storage/innobase/include/row0row.h
index 694604af408..1c7e40ac690 100644
--- a/storage/innobase/include/row0row.h
+++ b/storage/innobase/include/row0row.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -44,7 +44,7 @@ ulint
row_get_trx_id_offset(
/*==================*/
const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets)/*!< in: record offsets */
+ const rec_offs* offsets)/*!< in: record offsets */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Reads the trx id field from a clustered index record.
@@ -55,7 +55,7 @@ row_get_rec_trx_id(
/*===============*/
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Reads the roll pointer field from a clustered index record.
@@ -66,7 +66,7 @@ row_get_rec_roll_ptr(
/*=================*/
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/* Flags for row build type. */
@@ -138,7 +138,7 @@ row_build(
this record must be at least
s-latched and the latch held
as long as the row dtuple is used! */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index)
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index)
or NULL, in which case this function
will invoke rec_get_offsets() */
const dict_table_t* col_table,
@@ -189,7 +189,7 @@ row_build_w_add_vcol(
ulint type,
const dict_index_t* index,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
const dict_table_t* col_table,
const dtuple_t* add_cols,
const dict_add_v_col_t* add_v,
@@ -206,9 +206,7 @@ row_rec_to_index_entry_low(
/*=======================*/
const rec_t* rec, /*!< in: record in the index */
const dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
- ulint* n_ext, /*!< out: number of externally
- stored columns */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
MY_ATTRIBUTE((warn_unused_result));
@@ -221,9 +219,7 @@ row_rec_to_index_entry(
/*===================*/
const rec_t* rec, /*!< in: record in the index */
const dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in/out: rec_get_offsets(rec) */
- ulint* n_ext, /*!< out: number of externally
- stored columns */
+ const rec_offs* offsets,/*!< in/out: rec_get_offsets(rec) */
mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
MY_ATTRIBUTE((warn_unused_result));
@@ -266,7 +262,7 @@ row_build_row_ref_in_tuple(
held as long as the row
reference is used! */
const dict_index_t* index, /*!< in: secondary index */
- ulint* offsets,/*!< in: rec_get_offsets(rec, index)
+ rec_offs* offsets,/*!< in: rec_get_offsets(rec, index)
or NULL */
trx_t* trx) /*!< in: transaction or NULL */
MY_ATTRIBUTE((nonnull(1,2,3)));
@@ -285,7 +281,7 @@ row_build_row_ref_fast(
const rec_t* rec, /*!< in: record in the index; must be
preserved while ref is used, as we do
not copy field values to heap */
- const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets);/*!< in: array returned by rec_get_offsets() */
/***************************************************************//**
Searches the clustered index record for a row, if we have the row
reference.
diff --git a/storage/innobase/include/row0row.ic b/storage/innobase/include/row0row.ic
index 36a281d2fb9..a3dd51aaac2 100644
--- a/storage/innobase/include/row0row.ic
+++ b/storage/innobase/include/row0row.ic
@@ -36,7 +36,7 @@ ulint
row_get_trx_id_offset(
/*==================*/
const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets)/*!< in: record offsets */
+ const rec_offs* offsets)/*!< in: record offsets */
{
ulint pos;
ulint offset;
@@ -63,7 +63,7 @@ row_get_rec_trx_id(
/*===============*/
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint offset;
@@ -88,7 +88,7 @@ row_get_rec_roll_ptr(
/*=================*/
const rec_t* rec, /*!< in: record */
const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint offset;
@@ -147,7 +147,7 @@ row_build_row_ref_fast(
const rec_t* rec, /*!< in: record in the index; must be
preserved while ref is used, as we do
not copy field values to heap */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
dfield_t* dfield;
const byte* field;
diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h
index 7bca58037a6..b60770b01fb 100644
--- a/storage/innobase/include/row0upd.h
+++ b/storage/innobase/include/row0upd.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -28,6 +28,7 @@ Created 12/27/1996 Heikki Tuuri
#define row0upd_h
#include "data0data.h"
+#include "rem0types.h"
#include "row0types.h"
#include "btr0types.h"
#include "trx0types.h"
@@ -123,7 +124,7 @@ row_upd_rec_sys_fields(
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
const trx_t* trx, /*!< in: transaction */
roll_ptr_t roll_ptr);/*!< in: DB_ROLL_PTR to the undo log */
/*********************************************************************//**
@@ -165,7 +166,7 @@ ibool
row_upd_changes_field_size_or_external(
/*===================================*/
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
const upd_t* update);/*!< in: update vector */
/***********************************************************//**
Returns true if row update contains disowned external fields.
@@ -186,7 +187,7 @@ row_upd_rec_in_place(
/*=================*/
rec_t* rec, /*!< in/out: record where replaced */
dict_index_t* index, /*!< in: the index the record belongs to */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */
page_zip_des_t* page_zip);/*!< in: compressed page with enough space
available, or NULL */
@@ -201,7 +202,7 @@ row_upd_build_sec_rec_difference_binary(
/*====================================*/
const rec_t* rec, /*!< in: secondary index record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
const dtuple_t* entry, /*!< in: entry to insert */
mem_heap_t* heap) /*!< in: memory heap from which allocated */
MY_ATTRIBUTE((warn_unused_result, nonnull));
@@ -227,7 +228,7 @@ row_upd_build_difference_binary(
dict_index_t* index,
const dtuple_t* entry,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
bool no_sys,
trx_t* trx,
mem_heap_t* heap,
@@ -256,24 +257,18 @@ row_upd_index_replace_new_col_vals_index_pos(
mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
MY_ATTRIBUTE((nonnull));
-/***********************************************************//**
-Replaces the new column values stored in the update vector to the index entry
-given. */
-void
-row_upd_index_replace_new_col_vals(
-/*===============================*/
- dtuple_t* entry, /*!< in/out: index entry where replaced;
- the clustered index record must be
- covered by a lock or a page latch to
- prevent deletion (rollback or purge) */
- dict_index_t* index, /*!< in: index; NOTE that this may also be a
- non-clustered index */
- const upd_t* update, /*!< in: an update vector built for the
- CLUSTERED index so that the field number in
- an upd_field is the clustered index position */
- mem_heap_t* heap) /*!< in: memory heap for allocating and
- copying the new values */
- MY_ATTRIBUTE((nonnull));
+/** Replace the new column values stored in the update vector,
+during trx_undo_prev_version_build().
+@param entry clustered index tuple where the values are replaced
+ (the clustered index leaf page latch must be held)
+@param index clustered index
+@param update update vector for the clustered index
+@param heap memory heap for allocating and copying values
+@return whether the previous version was built successfully */
+bool
+row_upd_index_replace_new_col_vals(dtuple_t *entry, const dict_index_t &index,
+ const upd_t *update, mem_heap_t *heap)
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/***********************************************************//**
Replaces the new column values stored in the update vector. */
void
@@ -370,16 +365,6 @@ row_upd_changes_some_index_ord_field_binary(
/*========================================*/
const dict_table_t* table, /*!< in: table */
const upd_t* update);/*!< in: update vector for the row */
-/** Stores to the heap the row on which the node->pcur is positioned.
-@param[in] node row update node
-@param[in] thd mysql thread handle
-@param[in,out] mysql_table NULL, or mysql table object when
- user thread invokes dml */
-void
-row_upd_store_row(
- upd_node_t* node,
- THD* thd,
- TABLE* mysql_table);
/***********************************************************//**
Updates a row in a table. This is a high-level function used
in SQL execution graphs.
@@ -407,7 +392,7 @@ row_upd_rec_sys_fields_in_recovery(
/*===============================*/
rec_t* rec, /*!< in/out: record */
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint pos, /*!< in: TRX_ID position in rec */
trx_id_t trx_id, /*!< in: transaction id */
roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record */
diff --git a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
index 64f08cbb0b2..07e1c13d771 100644
--- a/storage/innobase/include/row0upd.ic
+++ b/storage/innobase/include/row0upd.ic
@@ -163,7 +163,7 @@ row_upd_rec_sys_fields(
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
const trx_t* trx, /*!< in: transaction */
roll_ptr_t roll_ptr)/*!< in: DB_ROLL_PTR to the undo log */
{
diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h
index 327bb546356..3b1f16ef15f 100644
--- a/storage/innobase/include/row0vers.h
+++ b/storage/innobase/include/row0vers.h
@@ -50,7 +50,7 @@ trx_t*
row_vers_impl_x_locked(
const rec_t* rec,
dict_index_t* index,
- const ulint* offsets);
+ const rec_offs* offsets);
/*****************************************************************//**
Finds out if we must preserve a delete marked earlier version of a clustered
@@ -112,7 +112,7 @@ row_vers_build_for_consistent_read(
mtr_t* mtr, /*!< in: mtr holding the latch on rec; it will
also hold the latch on purge_view */
dict_index_t* index, /*!< in: the clustered index */
- ulint** offsets,/*!< in/out: offsets returned by
+ rec_offs** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
ReadView* view, /*!< in: the consistent read view */
mem_heap_t** offset_heap,/*!< in/out: memory heap from which
@@ -139,7 +139,7 @@ row_vers_build_for_semi_consistent_read(
of this records */
mtr_t* mtr, /*!< in: mtr holding the latch on rec */
dict_index_t* index, /*!< in: the clustered index */
- ulint** offsets,/*!< in/out: offsets returned by
+ rec_offs** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
diff --git a/storage/innobase/include/span.h b/storage/innobase/include/span.h
deleted file mode 100644
index faeb41029b8..00000000000
--- a/storage/innobase/include/span.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2019, MariaDB Corporation.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-#pragma once
-
-#include <cstddef>
-#include <iterator>
-
-namespace st_ {
-
-template <class ElementType> class span {
-public:
- typedef ElementType element_type;
- typedef ElementType value_type;
- typedef size_t index_type;
- typedef ptrdiff_t difference_type;
- typedef element_type* pointer;
- typedef const element_type* const_pointer;
- typedef element_type& reference;
- typedef const element_type& const_reference;
- typedef pointer iterator;
- typedef const pointer const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- span() : data_(NULL), size_(0) {}
-
- span(pointer ptr, index_type count) : data_(ptr), size_(count) {}
-
- span(pointer first, pointer last) : data_(first), size_(last - first) {}
-
- template <size_t N> span(element_type (&arr)[N]) : data_(arr), size_(N)
- {
- }
-
- template <class Container>
- span(Container& cont) : data_(cont.begin()), size_(cont.size())
- {
- }
-
- template <class Container>
- span(const Container& cont) : data_(cont.begin()), size_(cont.size())
- {
- }
-
- span(const span& other) : data_(other.data_), size_(other.size_) {}
-
- ~span(){};
-
- span& operator=(const span& other)
- {
- data_ = other.data_;
- size_ = other.size_;
- return *this;
- }
-
- template <size_t Count> span<element_type> first() const
- {
- assert(!empty());
- return span(data_, 1);
- }
- template <size_t Count> span<element_type> last() const
- {
- assert(!empty());
- return span(data_ + size() - 1, 1);
- }
-
- span<element_type> first(index_type count) const
- {
- assert(!empty());
- return span(data_, 1);
- }
- span<element_type> last(index_type count) const
- {
- assert(!empty());
- return span(data_ + size() - 1, 1);
- }
- span<element_type> subspan(index_type offset, index_type count) const
- {
- assert(!empty());
- assert(size() >= offset + count);
- return span(data_ + offset, count);
- }
-
- index_type size() const { return size_; }
- index_type size_bytes() const { return size_ * sizeof(ElementType); }
- bool empty() const __attribute__((warn_unused_result))
- {
- return size_ == 0;
- }
-
- reference operator[](index_type idx) const
- {
- assert(size() > idx);
- return data_[idx];
- }
- reference front() const
- {
- assert(!empty());
- return data_[0];
- }
- reference back() const
- {
- assert(!empty());
- return data_[size() - 1];
- }
- pointer data() const
- {
- assert(!empty());
- return data_;
- }
-
- iterator begin() const { return data_; }
- iterator end() const { return data_ + size_; }
- reverse_iterator rbegin() const
- {
- return std::reverse_iterator<iterator>(std::advance(end(), -1));
- }
- reverse_iterator rend() const
- {
- return std::reverse_iterator<iterator>(
- std::advance(begin(), -1));
- }
-
-private:
- pointer data_;
- index_type size_;
-};
-
-} // namespace st_
diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h
index 343cb0e741a..ccc70206ede 100644
--- a/storage/innobase/include/srv0mon.h
+++ b/storage/innobase/include/srv0mon.h
@@ -2,7 +2,7 @@
Copyright (c) 2010, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -652,14 +652,14 @@ Use MONITOR_DEC if appropriate mutex protection exists.
} \
}
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
# define MONITOR_CHECK_DEFINED(value) do { \
mon_type_t m = value; \
- UNIV_MEM_ASSERT_RW(&m, sizeof m); \
+ MEM_CHECK_DEFINED(&m, sizeof m); \
} while (0)
-#else /* UNIV_DEBUG_VALGRIND */
+#else /* HAVE_valgrind_or_MSAN */
# define MONITOR_CHECK_DEFINED(value) (void) 0
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
#define MONITOR_INC_VALUE(monitor, value) \
MONITOR_CHECK_DEFINED(value); \
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index c1dcb2273e6..5214953f308 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -518,6 +518,8 @@ enum srv_operation_mode {
SRV_OPERATION_BACKUP,
/** Mariabackup restoring a backup for subsequent --copy-back */
SRV_OPERATION_RESTORE,
+ /** Mariabackup restoring a backup with rolling back prepared XA's*/
+ SRV_OPERATION_RESTORE_ROLLBACK_XA,
/** Mariabackup restoring the incremental part of a backup */
SRV_OPERATION_RESTORE_DELTA,
/** Mariabackup restoring a backup for subsequent --export */
@@ -527,6 +529,21 @@ enum srv_operation_mode {
/** Current mode of operation */
extern enum srv_operation_mode srv_operation;
+inline bool is_mariabackup_restore()
+{
+ /* To rollback XA's trx_sys must be initialized, the rest is the same
+ as regular backup restore, that is why we join this two operations in
+ the most cases. */
+ return srv_operation == SRV_OPERATION_RESTORE
+ || srv_operation == SRV_OPERATION_RESTORE_ROLLBACK_XA;
+}
+
+inline bool is_mariabackup_restore_or_export()
+{
+ return is_mariabackup_restore()
+ || srv_operation == SRV_OPERATION_RESTORE_EXPORT;
+}
+
extern my_bool srv_print_innodb_monitor;
extern my_bool srv_print_innodb_lock_monitor;
extern ibool srv_print_verbose_log;
@@ -1130,13 +1147,6 @@ struct srv_slot_t{
to do */
que_thr_t* thr; /*!< suspended query thread
(only used for user threads) */
-#ifdef UNIV_DEBUG
- struct debug_sync_t {
- UT_LIST_NODE_T(debug_sync_t) debug_sync_list;
- };
- UT_LIST_BASE_NODE_T(debug_sync_t) debug_sync;
- rw_lock_t debug_sync_lock;
-#endif
};
#ifdef UNIV_DEBUG
diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h
index 8b39733335d..e559814b33d 100644
--- a/storage/innobase/include/srv0start.h
+++ b/storage/innobase/include/srv0start.h
@@ -113,6 +113,8 @@ extern ibool srv_start_raw_disk_in_use;
/** Shutdown state */
enum srv_shutdown_t {
SRV_SHUTDOWN_NONE = 0, /*!< Database running normally */
+ /** Shutdown initiated in srv_shutdown_bg_undo_sources() */
+ SRV_SHUTDOWN_INITIATED,
SRV_SHUTDOWN_CLEANUP, /*!< Cleaning up in
logs_empty_and_mark_files_at_shutdown() */
SRV_SHUTDOWN_FLUSH_PHASE,/*!< At this phase the master and the
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index e0451d66de1..b2a436804fe 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -577,12 +577,6 @@ struct rw_lock_t
/** number of granted SX locks. */
volatile ulint sx_recursive;
- /** This is TRUE if the writer field is RW_LOCK_X_WAIT; this field
- is located far from the memory update hotspot fields which are at
- the start of this struct, thus we can peek this field without
- causing much memory bus traffic */
- bool writer_is_wait_ex;
-
/** The value is typically set to thread id of a writer thread making
normal rw_locks recursive. In case of asynchronous IO, when a non-zero
value of 'pass' is passed then we keep the lock non-recursive.
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index 0d8bd0a4509..0438d9d0c92 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -3,6 +3,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -59,9 +60,7 @@ extern mysql_pfs_key_t dict_sys_mutex_key;
extern mysql_pfs_key_t file_format_max_mutex_key;
extern mysql_pfs_key_t fil_system_mutex_key;
extern mysql_pfs_key_t flush_list_mutex_key;
-extern mysql_pfs_key_t fts_bg_threads_mutex_key;
extern mysql_pfs_key_t fts_delete_mutex_key;
-extern mysql_pfs_key_t fts_optimize_mutex_key;
extern mysql_pfs_key_t fts_doc_id_mutex_key;
extern mysql_pfs_key_t fts_pll_tokenize_mutex_key;
extern mysql_pfs_key_t hash_table_mutex_key;
@@ -81,7 +80,6 @@ extern mysql_pfs_key_t recv_writer_mutex_key;
extern mysql_pfs_key_t rtr_active_mutex_key;
extern mysql_pfs_key_t rtr_match_mutex_key;
extern mysql_pfs_key_t rtr_path_mutex_key;
-extern mysql_pfs_key_t rtr_ssn_mutex_key;
extern mysql_pfs_key_t redo_rseg_mutex_key;
extern mysql_pfs_key_t noredo_rseg_mutex_key;
extern mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index 9b1443523c7..563176f4abe 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -219,7 +219,6 @@ enum latch_level_t {
SYNC_FTS_TOKENIZE,
SYNC_FTS_OPTIMIZE,
- SYNC_FTS_BG_THREADS,
SYNC_FTS_CACHE_INIT,
SYNC_RECV,
SYNC_LOG_FLUSH_ORDER,
@@ -228,7 +227,6 @@ enum latch_level_t {
SYNC_PAGE_CLEANER,
SYNC_PURGE_QUEUE,
SYNC_TRX_SYS_HEADER,
- SYNC_REC_LOCK,
SYNC_THREADS,
SYNC_TRX,
SYNC_TRX_SYS,
@@ -305,9 +303,7 @@ enum latch_id_t {
LATCH_ID_FILE_FORMAT_MAX,
LATCH_ID_FIL_SYSTEM,
LATCH_ID_FLUSH_LIST,
- LATCH_ID_FTS_BG_THREADS,
LATCH_ID_FTS_DELETE,
- LATCH_ID_FTS_OPTIMIZE,
LATCH_ID_FTS_DOC_ID,
LATCH_ID_FTS_PLL_TOKENIZE,
LATCH_ID_HASH_TABLE_MUTEX,
@@ -327,7 +323,6 @@ enum latch_id_t {
LATCH_ID_REDO_RSEG,
LATCH_ID_NOREDO_RSEG,
LATCH_ID_RW_LOCK_DEBUG,
- LATCH_ID_RTR_SSN_MUTEX,
LATCH_ID_RTR_ACTIVE_MUTEX,
LATCH_ID_RTR_MATCH_MUTEX,
LATCH_ID_RTR_PATH_MUTEX,
@@ -380,7 +375,6 @@ enum latch_id_t {
LATCH_ID_BTR_DEFRAGMENT_MUTEX,
LATCH_ID_MTFLUSH_THREAD_MUTEX,
LATCH_ID_MTFLUSH_MUTEX,
- LATCH_ID_FIL_CRYPT_MUTEX,
LATCH_ID_FIL_CRYPT_STAT_MUTEX,
LATCH_ID_FIL_CRYPT_DATA_MUTEX,
LATCH_ID_FIL_CRYPT_THREADS_MUTEX,
@@ -665,10 +659,10 @@ public:
}
/** Iterate over the counters */
- template <typename Callback>
- void iterate(Callback& callback) const
- UNIV_NOTHROW
+ template<typename C> void iterate(const C& callback) UNIV_NOTHROW
{
+ m_mutex.enter();
+
Counters::const_iterator end = m_counters.end();
for (Counters::const_iterator it = m_counters.begin();
@@ -677,6 +671,8 @@ public:
callback(*it);
}
+
+ m_mutex.exit();
}
/** Disable the monitoring */
diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h
index ab9ae8a1f43..be06db4c954 100644
--- a/storage/innobase/include/trx0rec.h
+++ b/storage/innobase/include/trx0rec.h
@@ -207,7 +207,7 @@ trx_undo_report_row_operation(
const rec_t* rec, /*!< in: case of an update or delete
marking, the record in the clustered
index; NULL if insert */
- const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec) */
roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
undo log record */
MY_ATTRIBUTE((nonnull(1,2,8), warn_unused_result));
@@ -240,7 +240,7 @@ trx_undo_prev_version_build(
index_rec page and purge_view */
const rec_t* rec, /*!< in: version of a clustered index record */
dict_index_t* index, /*!< in: clustered index */
- ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(rec, index) */
mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
rec_t** old_vers,/*!< out, own: previous version, or NULL if
diff --git a/storage/innobase/include/trx0roll.h b/storage/innobase/include/trx0roll.h
index cae548d442b..0fd6973e551 100644
--- a/storage/innobase/include/trx0roll.h
+++ b/storage/innobase/include/trx0roll.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -35,15 +35,6 @@ extern bool trx_rollback_or_clean_is_active;
extern const trx_t* trx_roll_crash_recv_trx;
/*******************************************************************//**
-Determines if this transaction is rolling back an incomplete transaction
-in crash recovery.
-@return TRUE if trx is an incomplete transaction that is being rolled
-back in crash recovery */
-ibool
-trx_is_recv(
-/*========*/
- const trx_t* trx); /*!< in: transaction */
-/*******************************************************************//**
Returns a transaction savepoint taken at this point in time.
@return savepoint */
trx_savept_t
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 1d71920d6c5..4161d4d8563 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -73,12 +73,9 @@ Creates a transaction object for MySQL.
trx_t*
trx_allocate_for_mysql(void);
/*========================*/
-/********************************************************************//**
-Creates a transaction object for background operations by the master thread.
-@return own: transaction object */
-trx_t*
-trx_allocate_for_background(void);
-/*=============================*/
+
+/** @return allocated transaction object for internal operations */
+trx_t *trx_allocate_for_background();
/** Frees and initialize a transaction object instantinated during recovery.
@param trx trx object to free and initialize during recovery */
@@ -432,13 +429,6 @@ ibool
trx_is_interrupted(
/*===============*/
const trx_t* trx); /*!< in: transaction */
-/**********************************************************************//**
-Determines if the currently running transaction is in strict mode.
-@return TRUE if strict */
-ibool
-trx_is_strict(
-/*==========*/
- trx_t* trx); /*!< in: transaction */
/*******************************************************************//**
Calculates the "weight" of a transaction. The weight of one transaction
@@ -560,6 +550,7 @@ Check transaction state */
ut_ad(!(t)->id); \
ut_ad(!(t)->has_logged()); \
ut_ad(!(t)->is_referenced()); \
+ ut_ad(!(t)->is_wsrep()); \
ut_ad(!MVCC::is_view_active((t)->read_view)); \
ut_ad((t)->lock.wait_thr == NULL); \
ut_ad(UT_LIST_GET_LEN((t)->lock.trx_locks) == 0); \
@@ -880,6 +871,13 @@ public:
rolled back by trx_rollback_or_clean_recovered().
Protected by trx_t::mutex for transactions that are in trx_sys. */
bool is_recovered;
+#ifdef WITH_WSREP
+ /** whether wsrep_on(mysql_thd) held at the start of transaction */
+ bool wsrep;
+ bool is_wsrep() const { return UNIV_UNLIKELY(wsrep); }
+#else /* WITH_WSREP */
+ bool is_wsrep() const { return false; }
+#endif /* WITH_WSREP */
ReadView* read_view; /*!< consistent read view used in the
transaction, or NULL if not yet set */
@@ -916,7 +914,8 @@ public:
the coordinator using the XA API, and
is set to false after commit or
rollback. */
- unsigned active_commit_ordered:1;/* 1 if owns prepare mutex */
+ /** whether this is holding the prepare mutex */
+ bool active_commit_ordered;
/*------------------------------*/
bool check_unique_secondary;
/*!< normally TRUE, but if the user
@@ -1203,6 +1202,9 @@ public:
ut_ad(old_n_ref > 0);
}
+ /** Free the memory to trx_pools */
+ inline void free();
+
private:
/** Assign a rollback segment for modifying temporary tables.
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 7635cecbcd3..c7474cff4ea 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -41,7 +41,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 7
-#define INNODB_VERSION_BUGFIX 28
+#define INNODB_VERSION_BUGFIX 31
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@@ -178,10 +178,6 @@ command. */
#define UNIV_ENABLE_UNIT_TEST_ROW_RAW_FORMAT_INT
*/
-#if defined HAVE_valgrind && defined HAVE_VALGRIND_MEMCHECK_H
-# define UNIV_DEBUG_VALGRIND
-#endif
-
#ifdef DBUG_OFF
# undef UNIV_DEBUG
#elif !defined UNIV_DEBUG
@@ -189,8 +185,6 @@ command. */
#endif
#if 0
-#define UNIV_DEBUG_VALGRIND /* Enable extra
- Valgrind instrumentation */
#define UNIV_DEBUG_PRINT /* Enable the compilation of
some debug print functions */
#define UNIV_AHI_DEBUG /* Enable adaptive hash index
@@ -616,57 +610,6 @@ typedef void* os_thread_ret_t;
#include "ut0ut.h"
#include "sync0types.h"
-#include <my_valgrind.h>
-/* define UNIV macros in terms of my_valgrind.h */
-#define UNIV_MEM_INVALID(addr, size) MEM_UNDEFINED(addr, size)
-#define UNIV_MEM_FREE(addr, size) MEM_NOACCESS(addr, size)
-#define UNIV_MEM_ALLOC(addr, size) UNIV_MEM_INVALID(addr, size)
-#ifdef UNIV_DEBUG_VALGRIND
-# include <valgrind/memcheck.h>
-# define UNIV_MEM_VALID(addr, size) VALGRIND_MAKE_MEM_DEFINED(addr, size)
-# define UNIV_MEM_DESC(addr, size) VALGRIND_CREATE_BLOCK(addr, size, #addr)
-# define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b)
-# define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do { \
- const void* _p = (const void*) (ulint) \
- VALGRIND_CHECK_MEM_IS_DEFINED(addr, size); \
- if (UNIV_LIKELY_NULL(_p)) { \
- fprintf(stderr, "%s:%d: %p[%u] undefined at %ld\n", \
- __FILE__, __LINE__, \
- (const void*) (addr), (unsigned) (size), (long) \
- (((const char*) _p) - ((const char*) (addr)))); \
- if (should_abort) { \
- ut_error; \
- } \
- } \
-} while (0)
-# define UNIV_MEM_ASSERT_RW(addr, size) \
- UNIV_MEM_ASSERT_RW_LOW(addr, size, false)
-# define UNIV_MEM_ASSERT_RW_ABORT(addr, size) \
- UNIV_MEM_ASSERT_RW_LOW(addr, size, true)
-# define UNIV_MEM_ASSERT_W(addr, size) do { \
- const void* _p = (const void*) (ulint) \
- VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size); \
- if (UNIV_LIKELY_NULL(_p)) \
- fprintf(stderr, "%s:%d: %p[%u] unwritable at %ld\n", \
- __FILE__, __LINE__, \
- (const void*) (addr), (unsigned) (size), (long) \
- (((const char*) _p) - ((const char*) (addr)))); \
- } while (0)
-# define UNIV_MEM_TRASH(addr, c, size) do { \
- ut_d(memset(addr, c, size)); \
- UNIV_MEM_INVALID(addr, size); \
- } while (0)
-#else
-# define UNIV_MEM_VALID(addr, size) do {} while(0)
-# define UNIV_MEM_DESC(addr, size) do {} while(0)
-# define UNIV_MEM_UNDESC(b) do {} while(0)
-# define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do {} while(0)
-# define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0)
-# define UNIV_MEM_ASSERT_RW_ABORT(addr, size) do {} while(0)
-# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
-# define UNIV_MEM_TRASH(addr, c, size) do {} while(0)
-#endif
-
extern ulong srv_page_size_shift;
extern ulong srv_page_size;
diff --git a/storage/innobase/include/ut0mutex.h b/storage/innobase/include/ut0mutex.h
index 1f99ee17a24..5375be0ed71 100644
--- a/storage/innobase/include/ut0mutex.h
+++ b/storage/innobase/include/ut0mutex.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -142,16 +142,10 @@ public:
/* Some of the slots will be null in non-debug mode */
- if (*it == NULL) {
- continue;
- }
-
- latch_meta_t* latch_meta = *it;
-
- bool ret = callback(*latch_meta);
-
- if (!ret) {
- return(ret);
+ if (latch_meta_t* l= *it) {
+ if (!callback(*l)) {
+ return false;
+ }
}
}
diff --git a/storage/innobase/include/ut0pool.h b/storage/innobase/include/ut0pool.h
index f7bc4c5ebdf..749c4188edf 100644
--- a/storage/innobase/include/ut0pool.h
+++ b/storage/innobase/include/ut0pool.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -86,11 +87,6 @@ struct Pool {
for (Element* elem = m_start; elem != m_last; ++elem) {
ut_ad(elem->m_pool == this);
- /* Unpoison the memory for AddressSanitizer */
- MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type);
- /* Declare the contents as initialized for Valgrind;
- we checked this in mem_free(). */
- UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type);
Factory::destroy(&elem->m_type);
}
@@ -125,18 +121,6 @@ struct Pool {
elem = NULL;
}
-#if defined HAVE_valgrind || defined __SANITIZE_ADDRESS__
- if (elem) {
- /* Unpoison the memory for AddressSanitizer */
- MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type);
- /* Declare the memory initialized for Valgrind.
- The trx_t that are released to the pool are
- actually initialized; we checked that by
- UNIV_MEM_ASSERT_RW() in mem_free() below. */
- UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type);
- }
-#endif
-
m_lock_strategy.exit();
return elem ? &elem->m_type : NULL;
}
@@ -149,12 +133,10 @@ struct Pool {
byte* p = reinterpret_cast<byte*>(ptr + 1);
elem = reinterpret_cast<Element*>(p - sizeof(*elem));
- UNIV_MEM_ASSERT_RW(&elem->m_type, sizeof elem->m_type);
elem->m_pool->m_lock_strategy.enter();
elem->m_pool->putl(elem);
- MEM_NOACCESS(&elem->m_type, sizeof elem->m_type);
elem->m_pool->m_lock_strategy.exit();
}
@@ -177,9 +159,6 @@ private:
void putl(Element* elem)
{
ut_ad(elem >= m_start && elem < m_last);
-
- ut_ad(Factory::debug(&elem->m_type));
-
m_pqueue.push(elem);
}
diff --git a/storage/innobase/include/ut0rnd.h b/storage/innobase/include/ut0rnd.h
index b6d4d4abbd2..9af8687bfd0 100644
--- a/storage/innobase/include/ut0rnd.h
+++ b/storage/innobase/include/ut0rnd.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -27,46 +28,48 @@ Created 1/20/1994 Heikki Tuuri
#define ut0rnd_h
#include "ut0byte.h"
+#include <my_sys.h>
#ifndef UNIV_INNOCHECKSUM
-/** The 'character code' for end of field or string (used
-in folding records */
-#define UT_END_OF_FIELD 257
-
-/********************************************************//**
-This is used to set the random number seed. */
-UNIV_INLINE
-void
-ut_rnd_set_seed(
-/*============*/
- ulint seed); /*!< in: seed */
-/********************************************************//**
-The following function generates a series of 'random' ulint integers.
-@return the next 'random' number */
-UNIV_INLINE
-ulint
-ut_rnd_gen_next_ulint(
-/*==================*/
- ulint rnd); /*!< in: the previous random number value */
-/*********************************************************//**
-The following function generates 'random' ulint integers which
-enumerate the value space (let there be N of them) of ulint integers
-in a pseudo-random fashion. Note that the same integer is repeated
-always after N calls to the generator.
-@return the 'random' number */
-UNIV_INLINE
-ulint
-ut_rnd_gen_ulint(void);
-/*==================*/
-/********************************************************//**
-Generates a random integer from a given interval.
-@return the 'random' number */
-UNIV_INLINE
-ulint
-ut_rnd_interval(
-/*============*/
- ulint low, /*!< in: low limit; can generate also this value */
- ulint high); /*!< in: high limit; can generate also this value */
+/** Seed value of ut_rnd_gen() */
+extern int32 ut_rnd_current;
+
+/** @return a pseudo-random 32-bit number */
+inline uint32_t ut_rnd_gen()
+{
+ /* This is a Galois linear-feedback shift register.
+ https://en.wikipedia.org/wiki/Linear-feedback_shift_register#Galois_LFSRs
+ The generating primitive Galois Field polynomial is the Castagnoli
+ polynomial that was made popular by CRC-32C:
+ x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+
+ x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+1 */
+ const uint32_t crc32c= 0x1edc6f41;
+
+ uint32_t rnd= my_atomic_load32_explicit(&ut_rnd_current,
+ MY_MEMORY_ORDER_RELAXED);
+
+ if (UNIV_UNLIKELY(rnd == 0))
+ {
+ rnd= static_cast<uint32_t>(my_interval_timer());
+ if (!rnd) rnd= 1;
+ }
+ else
+ {
+ bool lsb= rnd & 1;
+ rnd>>= 1;
+ if (lsb)
+ rnd^= crc32c;
+ }
+
+ my_atomic_store32_explicit(&ut_rnd_current, rnd, MY_MEMORY_ORDER_RELAXED);
+ return rnd;
+}
+
+/** @return a random number between 0 and n-1, inclusive */
+inline ulint ut_rnd_interval(ulint n)
+{
+ return n > 1 ? static_cast<ulint>(ut_rnd_gen() % n) : 0;
+}
/*******************************************************//**
The following function generates a hash value for a ulint integer
diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic
index 0003c42baad..c0105160a42 100644
--- a/storage/innobase/include/ut0rnd.ic
+++ b/storage/innobase/include/ut0rnd.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -29,98 +29,6 @@ Created 5/30/1994 Heikki Tuuri
#ifndef UNIV_INNOCHECKSUM
-#define UT_RND1 151117737
-#define UT_RND2 119785373
-#define UT_RND3 85689495
-#define UT_RND4 76595339
-#define UT_SUM_RND2 98781234
-#define UT_SUM_RND3 126792457
-#define UT_SUM_RND4 63498502
-#define UT_XOR_RND1 187678878
-#define UT_XOR_RND2 143537923
-
-/** Seed value of ut_rnd_gen_ulint() */
-extern ulint ut_rnd_ulint_counter;
-
-/********************************************************//**
-This is used to set the random number seed. */
-UNIV_INLINE
-void
-ut_rnd_set_seed(
-/*============*/
- ulint seed) /*!< in: seed */
-{
- ut_rnd_ulint_counter = seed;
-}
-
-/********************************************************//**
-The following function generates a series of 'random' ulint integers.
-@return the next 'random' number */
-UNIV_INLINE
-ulint
-ut_rnd_gen_next_ulint(
-/*==================*/
- ulint rnd) /*!< in: the previous random number value */
-{
- ulint n_bits;
-
- n_bits = 8 * sizeof(ulint);
-
- rnd = UT_RND2 * rnd + UT_SUM_RND3;
- rnd = UT_XOR_RND1 ^ rnd;
- rnd = (rnd << 20) + (rnd >> (n_bits - 20));
- rnd = UT_RND3 * rnd + UT_SUM_RND4;
- rnd = UT_XOR_RND2 ^ rnd;
- rnd = (rnd << 20) + (rnd >> (n_bits - 20));
- rnd = UT_RND1 * rnd + UT_SUM_RND2;
-
- return(rnd);
-}
-
-/********************************************************//**
-The following function generates 'random' ulint integers which
-enumerate the value space of ulint integers in a pseudo random
-fashion. Note that the same integer is repeated always after
-2 to power 32 calls to the generator (if ulint is 32-bit).
-@return the 'random' number */
-UNIV_INLINE
-ulint
-ut_rnd_gen_ulint(void)
-/*==================*/
-{
- ulint rnd;
-
- ut_rnd_ulint_counter = UT_RND1 * ut_rnd_ulint_counter + UT_RND2;
-
- rnd = ut_rnd_gen_next_ulint(ut_rnd_ulint_counter);
-
- return(rnd);
-}
-
-/********************************************************//**
-Generates a random integer from a given interval.
-@return the 'random' number */
-UNIV_INLINE
-ulint
-ut_rnd_interval(
-/*============*/
- ulint low, /*!< in: low limit; can generate also this value */
- ulint high) /*!< in: high limit; can generate also this value */
-{
- ulint rnd;
-
- ut_ad(high >= low);
-
- if (low == high) {
-
- return(low);
- }
-
- rnd = ut_rnd_gen_ulint();
-
- return(low + (rnd % (high - low)));
-}
-
/*******************************************************//**
The following function generates a hash value for a ulint integer
to a hash table of size table_size, which should be a prime
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index 000d8b6b379..a19f3db188d 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, MariaDB Corporation.
+Copyright (c) 2019, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -389,48 +389,41 @@ operator<<(
It contains a std::ostringstream object. The main purpose of this class is
to forward operator<< to the underlying std::ostringstream object. Do not
use this class directly, instead use one of the derived classes. */
-class logger {
-public:
- template<typename T>
- ATTRIBUTE_COLD
- logger& operator<<(const T& rhs)
- {
- m_oss << rhs;
- return(*this);
- }
-
- /** Write the given buffer to the internal string stream object.
- @param[in] buf the buffer whose contents will be logged.
- @param[in] count the length of the buffer buf.
- @return the output stream into which buffer was written. */
- ATTRIBUTE_COLD
- std::ostream&
- write(
- const char* buf,
- std::streamsize count)
- {
- return(m_oss.write(buf, count));
- }
-
- /** Write the given buffer to the internal string stream object.
- @param[in] buf the buffer whose contents will be logged.
- @param[in] count the length of the buffer buf.
- @return the output stream into which buffer was written. */
- ATTRIBUTE_COLD
- std::ostream&
- write(
- const byte* buf,
- std::streamsize count)
- {
- return(m_oss.write(reinterpret_cast<const char*>(buf), count));
- }
-
- std::ostringstream m_oss;
+class logger
+{
protected:
- /* This class must not be used directly, hence making the default
- constructor protected. */
- ATTRIBUTE_COLD
- logger() {}
+ /* This class must not be used directly */
+ ATTRIBUTE_COLD ATTRIBUTE_NOINLINE logger() {}
+public:
+ template<typename T> ATTRIBUTE_COLD ATTRIBUTE_NOINLINE
+ logger& operator<<(const T& rhs)
+ {
+ m_oss << rhs;
+ return *this;
+ }
+
+ /** Handle a fixed character string in the same way as a pointer to
+ an unknown-length character string, to reduce object code bloat. */
+ template<size_t N> logger& operator<<(const char (&rhs)[N])
+ { return *this << static_cast<const char*>(rhs); }
+
+ /** Output an error code name */
+ ATTRIBUTE_COLD logger& operator<<(dberr_t err);
+
+ /** Append a string.
+ @param buf string buffer
+ @param size buffer size
+ @return the output stream */
+ ATTRIBUTE_COLD __attribute__((noinline))
+ std::ostream &write(const char *buf, std::streamsize size)
+ {
+ return m_oss.write(buf, size);
+ }
+
+ std::ostream &write(const byte *buf, std::streamsize size)
+ { return write(reinterpret_cast<const char*>(buf), size); }
+
+ std::ostringstream m_oss;
};
/** The class info is used to emit informational log messages. It is to be
@@ -464,6 +457,14 @@ class error : public logger {
public:
ATTRIBUTE_COLD
~error();
+ /** Indicates that error::~error() was invoked. Can be used to
+ determine if error messages were logged during innodb code execution.
+ @return true if there were error messages, false otherwise. */
+ static bool was_logged() { return logged; }
+
+private:
+ /** true if error::~error() was invoked, false otherwise */
+ static bool logged;
};
/** The class fatal is used to emit an error message and stop the server
diff --git a/storage/innobase/innodb.cmake b/storage/innobase/innodb.cmake
index dbe3f8881e7..523176b4530 100644
--- a/storage/innobase/innodb.cmake
+++ b/storage/innobase/innodb.cmake
@@ -100,7 +100,8 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wconversion")
IF (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR
- CMAKE_SYSTEM_PROCESSOR MATCHES "i386")
+ CMAKE_SYSTEM_PROCESSOR MATCHES "i386" AND
+ CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
INCLUDE(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-fno-builtin-memcmp" HAVE_NO_BUILTIN_MEMCMP)
IF (HAVE_NO_BUILTIN_MEMCMP)
@@ -176,11 +177,6 @@ IF(NOT MSVC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i686")
ENDIF()
- CHECK_FUNCTION_EXISTS(posix_memalign HAVE_POSIX_MEMALIGN)
- IF(HAVE_POSIX_MEMALIGN)
- ADD_DEFINITIONS(-DHAVE_POSIX_MEMALIGN)
- ENDIF()
-
# Only use futexes on Linux if GCC atomics are available
IF(NOT MSVC AND NOT CMAKE_CROSSCOMPILING)
CHECK_C_SOURCE_RUNS(
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 9fdc8feee90..913c80027bf 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -320,17 +320,18 @@ static FILE* lock_latest_err_file;
/*********************************************************************//**
Reports that a transaction id is insensible, i.e., in the future. */
+ATTRIBUTE_COLD
void
lock_report_trx_id_insanity(
/*========================*/
trx_id_t trx_id, /*!< in: trx id */
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec, index) */
trx_id_t max_trx_id) /*!< in: trx_sys_get_max_trx_id() */
{
ib::error()
- << "Transaction id " << trx_id
+ << "Transaction id " << ib::hex(trx_id)
<< " associated with record" << rec_offsets_print(rec, offsets)
<< " in index " << index->name
<< " of table " << index->table->name
@@ -352,14 +353,14 @@ lock_check_trx_id_sanity(
trx_id_t trx_id, /*!< in: trx id */
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets) /*!< in: rec_get_offsets(rec, index) */
{
ut_ad(rec_offs_validate(rec, index, offsets));
trx_id_t max_trx_id = trx_sys_get_max_trx_id();
bool is_ok = trx_id < max_trx_id;
- if (!is_ok) {
+ if (UNIV_UNLIKELY(!is_ok)) {
lock_report_trx_id_insanity(
trx_id, rec, index, offsets, max_trx_id);
}
@@ -377,7 +378,7 @@ lock_clust_rec_cons_read_sees(
const rec_t* rec, /*!< in: user record which should be read or
passed over by a read cursor */
dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ReadView* view) /*!< in: consistent read view */
{
ut_ad(dict_index_is_clust(index));
@@ -643,6 +644,57 @@ lock_rec_get_insert_intention(
return(lock->type_mode & LOCK_INSERT_INTENTION);
}
+#ifdef WITH_WSREP
+/** Check if both conflicting lock and other record lock are brute force
+(BF). This case is a bug so report lock information and wsrep state.
+@param[in] lock_rec1 conflicting waiting record lock or NULL
+@param[in] lock_rec2 other waiting record lock
+@param[in] trx1 lock_rec1 can be NULL, trx
+*/
+static void wsrep_assert_no_bf_bf_wait(
+ const lock_t* lock_rec1,
+ const lock_t* lock_rec2,
+ const trx_t* trx1)
+{
+ ut_ad(!lock_rec1 || lock_get_type_low(lock_rec1) == LOCK_REC);
+ ut_ad(lock_get_type_low(lock_rec2) == LOCK_REC);
+
+ if (!trx1->is_wsrep() || !lock_rec2->trx->is_wsrep())
+ return;
+ if (UNIV_LIKELY(!wsrep_thd_is_BF(trx1->mysql_thd, FALSE)))
+ return;
+ if (UNIV_LIKELY(!wsrep_thd_is_BF(lock_rec2->trx->mysql_thd, FALSE)))
+ return;
+
+ mtr_t mtr;
+
+ if (lock_rec1) {
+ ib::error() << "Waiting lock on table: "
+ << lock_rec1->index->table->name
+ << " index: "
+ << lock_rec1->index->name()
+ << " that has conflicting lock ";
+ lock_rec_print(stderr, lock_rec1, mtr);
+ }
+
+ ib::error() << "Conflicting lock on table: "
+ << lock_rec2->index->table->name
+ << " index: "
+ << lock_rec2->index->name()
+ << " that has lock ";
+ lock_rec_print(stderr, lock_rec2, mtr);
+
+ ib::error() << "WSREP state: ";
+
+ wsrep_report_bf_lock_wait(trx1->mysql_thd,
+ trx1->id);
+ wsrep_report_bf_lock_wait(lock_rec2->trx->mysql_thd,
+ lock_rec2->trx->id);
+ /* BF-BF wait is a bug */
+ ut_error;
+}
+#endif /* WITH_WSREP */
+
/*********************************************************************//**
Checks if a lock request for a new lock has to wait for request lock2.
@return TRUE if new lock has to wait for lock2 to be removed */
@@ -750,69 +802,9 @@ lock_rec_has_to_wait(
}
#ifdef WITH_WSREP
- /* if BF thread is locking and has conflict with another BF
- thread, we need to look at trx ordering and lock types */
- if (wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) {
- mtr_t mtr;
-
- if (wsrep_debug) {
- ib::info() <<
- "BF-BF lock conflict, locking: " << for_locking;
- lock_rec_print(stderr, lock2, mtr);
- ib::info() << " SQL1: "
- << wsrep_thd_query(trx->mysql_thd);
- ib::info() << " SQL2: "
- << wsrep_thd_query(lock2->trx->mysql_thd);
- }
-
- if (wsrep_trx_order_before(trx->mysql_thd,
- lock2->trx->mysql_thd) &&
- (type_mode & LOCK_MODE_MASK) == LOCK_X &&
- (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X) {
- if (for_locking || wsrep_debug) {
- /* exclusive lock conflicts are not
- accepted */
- ib::info() <<
- "BF-BF X lock conflict,"
- "mode: " << type_mode <<
- " supremum: " << lock_is_on_supremum;
- ib::info() <<
- "conflicts states: my "
- << wsrep_thd_conflict_state(trx->mysql_thd, FALSE)
- << " locked "
- << wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE);
- lock_rec_print(stderr, lock2, mtr);
- ib::info() << " SQL1: "
- << wsrep_thd_query(trx->mysql_thd);
- ib::info() << " SQL2: "
- << wsrep_thd_query(lock2->trx->mysql_thd);
-
- if (for_locking) {
- return FALSE;
- }
- }
- } else {
- /* if lock2->index->n_uniq <=
- lock2->index->n_user_defined_cols
- operation is on uniq index
- */
- if (wsrep_debug) {
- ib::info() <<
- "BF conflict, modes: "
- << type_mode << ":" << lock2->type_mode
- << " idx: " << lock2->index->name()
- << " table: " << lock2->index->table->name.m_name
- << " n_uniq: " << lock2->index->n_uniq
- << " n_user: " << lock2->index->n_user_defined_cols;
- ib::info() << " SQL1: "
- << wsrep_thd_query(trx->mysql_thd);
- ib::info() << " SQL2: "
- << wsrep_thd_query(lock2->trx->mysql_thd);
- }
- return FALSE;
- }
- }
+ /* There should not be two conflicting locks that are
+ brute force. If there is it is a bug. */
+ wsrep_assert_no_bf_bf_wait(NULL, lock2, trx);
#endif /* WITH_WSREP */
return(TRUE);
@@ -1100,12 +1092,10 @@ wsrep_kill_victim(
ut_ad(trx_mutex_own(lock->trx));
/* quit for native mysql */
- if (!wsrep_on(trx->mysql_thd)) {
- return;
- }
+ if (!trx->is_wsrep()) return;
my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE);
- my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
+ my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE);
mtr_t mtr;
if ((bf_this && !bf_other) ||
@@ -1113,7 +1103,7 @@ wsrep_kill_victim(
trx->mysql_thd, lock->trx->mysql_thd))) {
if (lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) {
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::info() << "WSREP: BF victim waiting\n";
}
/* cannot release lock, until our lock
@@ -1185,7 +1175,7 @@ lock_rec_other_has_conflicting(
if (lock_rec_has_to_wait(true, trx, mode, lock, is_supremum)) {
#ifdef WITH_WSREP
- if (wsrep_on_trx(trx)) {
+ if (trx->is_wsrep()) {
trx_mutex_enter(lock->trx);
/* Below function will roll back either trx
or lock->trx depending on priority of the
@@ -1214,7 +1204,7 @@ lock_sec_rec_some_has_impl(
/*=======================*/
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: secondary index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
{
trx_t* trx;
trx_id_t max_trx_id;
@@ -1346,13 +1336,14 @@ lock_number_of_tables_locked(
/*============== RECORD LOCK CREATION AND QUEUE MANAGEMENT =============*/
#ifdef WITH_WSREP
+ATTRIBUTE_COLD
static
void
wsrep_print_wait_locks(
/*===================*/
lock_t* c_lock) /* conflicting lock to print */
{
- if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) {
+ if (c_lock->trx->lock.wait_lock != c_lock) {
mtr_t mtr;
ib::info() << "WSREP: c_lock != wait lock";
ib::info() << " SQL: "
@@ -1478,12 +1469,12 @@ lock_rec_create_low(
ut_ad(index->table->get_ref_count() > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
- if (c_lock && wsrep_on_trx(trx)
+ if (c_lock && trx->is_wsrep()
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
- while (hash && wsrep_thd_is_BF(hash->trx->mysql_thd, TRUE)
+ while (hash && wsrep_thd_is_BF(hash->trx->mysql_thd, FALSE)
&& wsrep_trx_order_before(hash->trx->mysql_thd,
trx->mysql_thd)) {
prev = hash;
@@ -1504,7 +1495,7 @@ lock_rec_create_low(
c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE;
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
wsrep_print_wait_locks(c_lock);
}
@@ -1531,12 +1522,9 @@ lock_rec_create_low(
trx_mutex_exit(c_lock->trx);
- if (wsrep_debug) {
- ib::info() << "WSREP: c_lock canceled "
- << ib::hex(c_lock->trx->id)
- << " SQL: "
- << wsrep_thd_query(
- c_lock->trx->mysql_thd);
+ if (UNIV_UNLIKELY(wsrep_debug)) {
+ wsrep_report_bf_lock_wait(trx->mysql_thd, trx->id);
+ wsrep_report_bf_lock_wait(c_lock->trx->mysql_thd, c_lock->trx->id);
}
/* have to bail out here to avoid lock_set_lock... */
@@ -1615,6 +1603,7 @@ lock_rec_insert_by_trx_age(
hash_table_t* hash;
hash_cell_t* cell;
+ ut_ad(!in_lock->trx->is_wsrep());
space = in_lock->un_member.rec_lock.space;
page_no = in_lock->un_member.rec_lock.page_no;
rec_fold = lock_rec_fold(space, page_no);
@@ -1796,7 +1785,7 @@ lock_rec_enqueue_waiting(
transaction as a victim, it is possible that we
already have the lock now granted! */
#ifdef WITH_WSREP
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::info() << "WSREP: BF thread got lock granted early, ID " << ib::hex(trx->id)
<< " query: " << wsrep_thd_query(trx->mysql_thd);
}
@@ -1877,30 +1866,19 @@ lock_rec_add_to_queue(
= lock_rec_other_has_expl_req(
mode, block, false, heap_no, trx);
#ifdef WITH_WSREP
- //ut_a(!other_lock || (wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- // wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)));
- if (other_lock &&
- wsrep_on(trx->mysql_thd) &&
- !wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- !wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)) {
-
- ib::info() << "WSREP BF lock conflict for my lock:\n BF:" <<
- ((wsrep_thd_is_BF(trx->mysql_thd, FALSE)) ? "BF" : "normal") << " exec: " <<
- wsrep_thd_exec_mode(trx->mysql_thd) << " conflict: " <<
- wsrep_thd_conflict_state(trx->mysql_thd, false) << " seqno: " <<
- wsrep_thd_trx_seqno(trx->mysql_thd) << " SQL: " <<
- wsrep_thd_query(trx->mysql_thd);
- trx_t* otrx = other_lock->trx;
- ib::info() << "WSREP other lock:\n BF:" <<
- ((wsrep_thd_is_BF(otrx->mysql_thd, FALSE)) ? "BF" : "normal") << " exec: " <<
- wsrep_thd_exec_mode(otrx->mysql_thd) << " conflict: " <<
- wsrep_thd_conflict_state(otrx->mysql_thd, false) << " seqno: " <<
- wsrep_thd_trx_seqno(otrx->mysql_thd) << " SQL: " <<
- wsrep_thd_query(otrx->mysql_thd);
- }
-#else
- ut_a(!other_lock);
+ if (UNIV_UNLIKELY(other_lock && trx->is_wsrep())) {
+ /* Only BF transaction may be granted lock
+ before other conflicting lock request. */
+ if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)
+ && !wsrep_thd_is_BF(other_lock->trx->mysql_thd, FALSE)) {
+ /* If it is not BF, this case is a bug. */
+ wsrep_report_bf_lock_wait(trx->mysql_thd, trx->id);
+ wsrep_report_bf_lock_wait(other_lock->trx->mysql_thd, other_lock->trx->id);
+ ut_error;
+ }
+ } else
#endif /* WITH_WSREP */
+ ut_ad(!other_lock);
}
#endif /* UNIV_DEBUG */
@@ -2191,6 +2169,7 @@ lock_rec_has_to_wait_in_queue(
ulint bit_offset;
hash_table_t* hash;
+ ut_ad(wait_lock);
ut_ad(lock_mutex_own());
ut_ad(lock_get_wait(wait_lock));
ut_ad(lock_get_type_low(wait_lock) == LOCK_REC);
@@ -2207,29 +2186,11 @@ lock_rec_has_to_wait_in_queue(
for (lock = lock_rec_get_first_on_page_addr(hash, space, page_no);
lock != wait_lock;
lock = lock_rec_get_next_on_page_const(lock)) {
-
const byte* p = (const byte*) &lock[1];
if (heap_no < lock_rec_get_n_bits(lock)
&& (p[bit_offset] & bit_mask)
&& lock_has_to_wait(wait_lock, lock)) {
-#ifdef WITH_WSREP
- if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) &&
- wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) {
- if (wsrep_debug) {
- mtr_t mtr;
- ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id)
- << " query: " << wsrep_thd_query(wait_lock->trx->mysql_thd);
- lock_rec_print(stderr, wait_lock, mtr);
- ib::info() << "WSREP: do not wait another BF trx: " << ib::hex(lock->trx->id)
- << " query: " << wsrep_thd_query(lock->trx->mysql_thd);
- lock_rec_print(stderr, lock, mtr);
- }
- /* don't wait for another BF lock */
- continue;
- }
-#endif /* WITH_WSREP */
-
return(lock);
}
}
@@ -2350,6 +2311,7 @@ lock_grant_and_move_on_page(ulint rec_fold, ulint space, ulint page_no)
Move granted locks to the head of the list. */
while (lock) {
/* If the lock is a wait lock on this page, and it does not need to wait. */
+ ut_ad(!lock->trx->is_wsrep());
if (lock_get_wait(lock)
&& lock->un_member.rec_lock.space == space
&& lock->un_member.rec_lock.page_no == page_no
@@ -2415,11 +2377,18 @@ static void lock_rec_dequeue_from_page(lock_t* in_lock)
lock != NULL;
lock = lock_rec_get_next_on_page(lock)) {
- if (lock_get_wait(lock)
- && !lock_rec_has_to_wait_in_queue(lock)) {
+ if (!lock_get_wait(lock)) {
+ continue;
+ }
+ const lock_t* c = lock_rec_has_to_wait_in_queue(lock);
+ if (!c) {
/* Grant the lock */
ut_ad(lock->trx != in_lock->trx);
lock_grant(lock);
+#ifdef WITH_WSREP
+ } else {
+ wsrep_assert_no_bf_bf_wait(c, lock, c->trx);
+#endif /* WITH_WSREP */
}
}
} else {
@@ -3656,16 +3625,13 @@ lock_table_create(
UT_LIST_ADD_LAST(trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock && wsrep_on_trx(trx)) {
+ if (c_lock && trx->is_wsrep()) {
if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
ut_list_insert(table->locks, c_lock, lock,
TableLockGetNode());
- if (wsrep_debug) {
- ib::info() << "table lock BF conflict for "
- << ib::hex(c_lock->trx->id)
- << " SQL: "
- << wsrep_thd_query(
- c_lock->trx->mysql_thd);
+ if (UNIV_UNLIKELY(wsrep_debug)) {
+ wsrep_report_bf_lock_wait(trx->mysql_thd, trx->id);
+ wsrep_report_bf_lock_wait(c_lock->trx->mysql_thd, c_lock->trx->id);
}
} else {
ut_list_append(table->locks, lock, TableLockGetNode());
@@ -3676,7 +3642,9 @@ lock_table_create(
if (c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) {
c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE;
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
+ wsrep_report_bf_lock_wait(trx->mysql_thd, trx->id);
+ wsrep_report_bf_lock_wait(c_lock->trx->mysql_thd, c_lock->trx->id);
wsrep_print_wait_locks(c_lock);
}
@@ -3686,14 +3654,6 @@ lock_table_create(
lock_cancel_waiting_and_release(
c_lock->trx->lock.wait_lock);
trx_mutex_enter(trx);
-
- if (wsrep_debug) {
- ib::info() << "WSREP: c_lock canceled "
- << ib::hex(c_lock->trx->id)
- << " SQL: "
- << wsrep_thd_query(
- c_lock->trx->mysql_thd);
- }
}
trx_mutex_exit(c_lock->trx);
@@ -3886,7 +3846,7 @@ lock_table_enqueue_waiting(
}
#ifdef WITH_WSREP
- if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
+ if (trx->is_wsrep() && trx->lock.was_chosen_as_deadlock_victim) {
return(DB_DEADLOCK);
}
#endif /* WITH_WSREP */
@@ -3959,10 +3919,10 @@ lock_table_other_has_incompatible(
&& (wait || !lock_get_wait(lock))) {
#ifdef WITH_WSREP
- if (wsrep_on(lock->trx->mysql_thd)) {
- if (wsrep_debug) {
+ if (lock->trx->is_wsrep()) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::info() << "WSREP: table lock abort for table:"
- << table->name.m_name;
+ << table->name;
ib::info() << " SQL: "
<< wsrep_thd_query(lock->trx->mysql_thd);
}
@@ -4253,8 +4213,8 @@ lock_grant_and_move_on_rec(
}
/* Grant locks if there are no conflicting locks ahead.
Move granted locks to the head of the list. */
- for (;lock != NULL;) {
-
+ while (lock) {
+ ut_ad(!lock->trx->is_wsrep());
/* If the lock is a wait lock on this page, and it does not need to wait. */
if (lock->un_member.rec_lock.space == space
&& lock->un_member.rec_lock.page_no == page_no
@@ -4349,12 +4309,18 @@ released:
for (lock = first_lock; lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
- if (lock_get_wait(lock)
- && !lock_rec_has_to_wait_in_queue(lock)) {
-
+ if (!lock_get_wait(lock)) {
+ continue;
+ }
+ const lock_t* c = lock_rec_has_to_wait_in_queue(lock);
+ if (!c) {
/* Grant the lock */
ut_ad(trx != lock->trx);
lock_grant(lock);
+#ifdef WITH_WSREP
+ } else {
+ wsrep_assert_no_bf_bf_wait(c, lock, c->trx);
+#endif /* WITH_WSREP */
}
}
} else {
@@ -4793,8 +4759,8 @@ static void lock_rec_print(FILE* file, const lock_t* lock, mtr_t& mtr)
putc('\n', file);
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
mtr.start();
@@ -5187,7 +5153,7 @@ lock_rec_queue_validate(
const buf_block_t* block, /*!< in: buffer block containing rec */
const rec_t* rec, /*!< in: record to look at */
const dict_index_t* index, /*!< in: index, or NULL if not known */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
{
const lock_t* lock;
ulint heap_no;
@@ -5253,24 +5219,28 @@ lock_rec_queue_validate(
explicit granted lock. */
#ifdef WITH_WSREP
- if (wsrep_on(other_lock->trx->mysql_thd)) {
- if (!lock_get_wait(other_lock) ) {
- ib::info() << "WSREP impl BF lock conflict for my impl lock:\n BF:" <<
- ((wsrep_thd_is_BF(impl_trx->mysql_thd, FALSE)) ? "BF" : "normal") << " exec: " <<
- wsrep_thd_exec_mode(impl_trx->mysql_thd) << " conflict: " <<
- wsrep_thd_conflict_state(impl_trx->mysql_thd, false) << " seqno: " <<
- wsrep_thd_trx_seqno(impl_trx->mysql_thd) << " SQL: " <<
- wsrep_thd_query(impl_trx->mysql_thd);
-
- trx_t* otrx = other_lock->trx;
-
- ib::info() << "WSREP other lock:\n BF:" <<
- ((wsrep_thd_is_BF(otrx->mysql_thd, FALSE)) ? "BF" : "normal") << " exec: " <<
- wsrep_thd_exec_mode(otrx->mysql_thd) << " conflict: " <<
- wsrep_thd_conflict_state(otrx->mysql_thd, false) << " seqno: " <<
- wsrep_thd_trx_seqno(otrx->mysql_thd) << " SQL: " <<
- wsrep_thd_query(otrx->mysql_thd);
- }
+ /** Galera record locking rules:
+ * If there is no other record lock to the same record, we may grant
+ the lock request.
+ * If there is other record lock but this requested record lock is
+ compatible, we may grant the lock request.
+ * If there is other record lock and it is not compatible with
+ requested lock, all normal transactions must wait.
+ * BF (brute force) additional exceptions :
+ ** If BF already holds record lock for requested record, we may
+ grant new record lock even if there is conflicting record lock(s)
+ waiting on a queue.
+ ** If conflicting transaction holds requested record lock,
+ we will cancel this record lock and select conflicting transaction
+ for BF abort or kill victim.
+ ** If conflicting transaction is waiting for requested record lock
+ we will cancel this wait and select conflicting transaction
+ for BF abort or kill victim.
+ ** There should not be two BF transactions waiting for same record lock
+ */
+ if (other_lock->trx->is_wsrep() && !lock_get_wait(other_lock)) {
+ wsrep_report_bf_lock_wait(impl_trx->mysql_thd, impl_trx->id);
+ wsrep_report_bf_lock_wait(other_lock->trx->mysql_thd, other_lock->trx->id);
if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
block, heap_no,
@@ -5279,9 +5249,11 @@ lock_rec_queue_validate(
}
} else
#endif /* WITH_WSREP */
- ut_ad(lock_get_wait(other_lock));
- ut_ad(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
- block, heap_no, impl_trx));
+ {
+ ut_ad(lock_get_wait(other_lock));
+ ut_ad(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
+ block, heap_no, impl_trx));
+ }
}
mutex_exit(&impl_trx->mutex);
@@ -5312,13 +5284,20 @@ lock_rec_queue_validate(
mode, block, false, heap_no,
lock->trx);
#ifdef WITH_WSREP
- ut_a(!other_lock
- || wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE)
- || wsrep_thd_is_BF(other_lock->trx->mysql_thd, FALSE));
-
-#else
- ut_a(!other_lock);
+ if (UNIV_UNLIKELY(other_lock && lock->trx->is_wsrep())) {
+ /* Only BF transaction may be granted
+ lock before other conflicting lock
+ request. */
+ if (!wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE)
+ && !wsrep_thd_is_BF(other_lock->trx->mysql_thd, FALSE)) {
+ /* If no BF, this case is a bug. */
+ wsrep_report_bf_lock_wait(lock->trx->mysql_thd, lock->trx->id);
+ wsrep_report_bf_lock_wait(other_lock->trx->mysql_thd, other_lock->trx->id);
+ ut_error;
+ }
+ } else
#endif /* WITH_WSREP */
+ ut_ad(!other_lock);
} else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) {
ut_a(lock_rec_has_to_wait_in_queue(lock));
@@ -5352,8 +5331,8 @@ lock_rec_validate_page(
ulint nth_bit = 0;
ulint i;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(!lock_mutex_own());
@@ -5738,8 +5717,8 @@ lock_rec_insert_check_and_lock(
#ifdef UNIV_DEBUG
{
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- const ulint* offsets;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ const rec_offs* offsets;
rec_offs_init(offsets_);
offsets = rec_get_offsets(next_rec, index, offsets_, true,
@@ -5804,7 +5783,7 @@ lock_rec_convert_impl_to_expl(
const buf_block_t* block, /*!< in: buffer block of rec */
const rec_t* rec, /*!< in: user record on page */
dict_index_t* index, /*!< in: index of record */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
{
trx_t* trx;
@@ -5859,7 +5838,7 @@ lock_clust_rec_modify_check_and_lock(
const rec_t* rec, /*!< in: record which should be
modified */
dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
{
dberr_t err;
@@ -5959,8 +5938,8 @@ lock_sec_rec_modify_check_and_lock(
#ifdef UNIV_DEBUG
{
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- const ulint* offsets;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ const rec_offs* offsets;
rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets_, true,
@@ -6004,7 +5983,7 @@ lock_sec_rec_read_check_and_lock(
be read or passed over by a
read cursor */
dict_index_t* index, /*!< in: secondary index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
@@ -6082,7 +6061,7 @@ lock_clust_rec_read_check_and_lock(
be read or passed over by a
read cursor */
dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
@@ -6166,8 +6145,8 @@ lock_clust_rec_read_check_and_lock_alt(
que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* tmp_heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
dberr_t err;
rec_offs_init(offsets_);
@@ -6639,7 +6618,8 @@ lock_table_locks_lookup(
ut_a(lock->trx == trx);
if (lock_get_type_low(lock) == LOCK_REC) {
- ut_ad(!dict_index_is_online_ddl(lock->index)
+ ut_ad(lock->index->online_status
+ != ONLINE_INDEX_CREATION
|| dict_index_is_clust(lock->index));
if (lock->index->table == table) {
break;
@@ -7038,7 +7018,7 @@ DeadlockChecker::select_victim() const
/* The joining transaction is 'smaller',
choose it as the victim and roll it back. */
#ifdef WITH_WSREP
- if (wsrep_thd_is_BF(m_start->mysql_thd, TRUE)) {
+ if (wsrep_thd_is_BF(m_start->mysql_thd, FALSE)) {
return(m_wait_lock->trx);
}
#endif /* WITH_WSREP */
@@ -7046,7 +7026,7 @@ DeadlockChecker::select_victim() const
}
#ifdef WITH_WSREP
- if (wsrep_thd_is_BF(m_wait_lock->trx->mysql_thd, TRUE)) {
+ if (wsrep_thd_is_BF(m_wait_lock->trx->mysql_thd, FALSE)) {
return(m_start);
}
#endif /* WITH_WSREP */
diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc
index 947e56ebeee..5d0d41ef494 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -192,8 +192,7 @@ wsrep_is_BF_lock_timeout(
const trx_t* trx,
bool locked = true)
{
- if (wsrep_on_trx(trx)
- && wsrep_thd_is_BF(trx->mysql_thd, FALSE)
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)
&& trx->error_state != DB_DEADLOCK) {
ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx->id)
<< " query: " << wsrep_thd_query(trx->mysql_thd);
@@ -402,8 +401,9 @@ lock_wait_suspend_thread(
if (lock_wait_timeout < 100000000
&& wait_time > (double) lock_wait_timeout
#ifdef WITH_WSREP
- && (!wsrep_on_trx(trx) ||
- (!wsrep_is_BF_lock_timeout(trx, false) && trx->error_state != DB_DEADLOCK))
+ && (!trx->is_wsrep()
+ || (!wsrep_is_BF_lock_timeout(trx, false)
+ && trx->error_state != DB_DEADLOCK))
#endif /* WITH_WSREP */
) {
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index c3eaa05b680..4c68f3743e9 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -83,12 +83,9 @@ reduce the size of the log.
/** Redo log system */
log_t* log_sys = NULL;
-/** Whether to generate and require checksums on the redo log pages */
+/** Whether to require checksums on the redo log pages */
my_bool innodb_log_checksums;
-/** Pointer to the log checksum calculation function */
-log_checksum_func_t log_checksum_algorithm_ptr;
-
/* Next log block number to do dummy record filling if no log records written
for a while */
static ulint next_lbn_to_pad = 0;
@@ -857,7 +854,7 @@ log_block_store_checksum(
/*=====================*/
byte* block) /*!< in/out: pointer to a log block */
{
- log_block_set_checksum(block, log_block_calc_checksum(block));
+ log_block_set_checksum(block, log_block_calc_checksum_crc32(block));
}
/******************************************************//**
@@ -1203,7 +1200,7 @@ loop:
}
}
- if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE)) {
+ if (UNIV_UNLIKELY(srv_shutdown_state > SRV_SHUTDOWN_INITIATED)) {
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"InnoDB log write: "
LSN_PF "," LSN_PF,
@@ -1430,7 +1427,7 @@ log_group_checkpoint(lsn_t end_lsn)
ut_ad(end_lsn == 0 || end_lsn >= log_sys->next_checkpoint_lsn);
ut_ad(end_lsn <= log_sys->lsn);
ut_ad(end_lsn + SIZE_OF_MLOG_CHECKPOINT <= log_sys->lsn
- || srv_shutdown_state != SRV_SHUTDOWN_NONE);
+ || srv_shutdown_state > SRV_SHUTDOWN_INITIATED);
DBUG_PRINT("ib_log", ("checkpoint " UINT64PF " at " LSN_PF
" written",
@@ -1600,7 +1597,7 @@ bool log_checkpoint(bool sync)
if (oldest_lsn
> log_sys->last_checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT) {
/* Some log has been written since the previous checkpoint. */
- } else if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ } else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
/* MariaDB 10.3 startup expects the redo log file to be
logically empty (not even containing a MLOG_CHECKPOINT record)
after a clean shutdown. Perform an extra checkpoint at
@@ -1625,7 +1622,7 @@ bool log_checkpoint(bool sync)
lsn_t flush_lsn = oldest_lsn;
const lsn_t end_lsn = log_sys->lsn;
const bool do_write
- = srv_shutdown_state == SRV_SHUTDOWN_NONE
+ = srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
|| flush_lsn != end_lsn;
if (fil_names_clear(flush_lsn, do_write)) {
@@ -1893,7 +1890,7 @@ wait_suspend_loop:
"Waiting for %s to exit", thread_name);
if (srv_print_verbose_log && count > COUNT_INTERVAL) {
ib::info() << "Waiting for " << thread_name
- << "to exit";
+ << " to exit";
count = 0;
}
goto loop;
@@ -1936,6 +1933,9 @@ wait_suspend_loop:
"Waiting for page cleaner");
ib::info() << "Waiting for page_cleaner to "
"finish flushing of buffer pool";
+ /* This is a workaround to avoid the InnoDB hang
+ when OS datetime changed backwards */
+ os_event_set(buf_flush_event);
count = 0;
}
}
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 9a20c7f7d22..446e0afe576 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -57,6 +57,7 @@ Created 9/20/1997 Heikki Tuuri
#include "srv0start.h"
#include "trx0roll.h"
#include "row0merge.h"
+#include "fil0pagecompress.h"
/** Log records are stored in the hash table in chunks at most of this size;
this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */
@@ -103,14 +104,6 @@ static ulint recv_previous_parsed_rec_offset;
/** The 'multi' flag of the previous parsed redo log record */
static ulint recv_previous_parsed_rec_is_multi;
-/** This many frames must be left free in the buffer pool when we scan
-the log and store the scanned log records in the buffer pool: we will
-use these free frames to read in pages when we start applying the
-log records to the database.
-This is the default value. If the actual size of the buffer pool is
-larger than 10 MB we'll set this value to 512. */
-ulint recv_n_pool_free_frames;
-
/** The maximum lsn we see for a page during the recovery process. If this
is bigger than the lsn we are able to scan up to, that is an indication that
the recovery failed and the database may be corrupt. */
@@ -321,7 +314,7 @@ public:
if (!i->second.created) {
continue;
}
- if (buf_block_t* block = buf_page_get_gen(
+ if (buf_block_t* block = buf_page_get_low(
i->first, univ_page_size, RW_X_LATCH, NULL,
BUF_GET_IF_IN_POOL, __FILE__, __LINE__,
&mtr, NULL)) {
@@ -414,8 +407,7 @@ fil_name_process(
}
ut_ad(srv_operation == SRV_OPERATION_NORMAL
- || srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_EXPORT);
+ || is_mariabackup_restore_or_export());
/* We will also insert space=NULL into the map, so that
further checks can ensure that a MLOG_FILE_NAME record was
@@ -598,7 +590,7 @@ fil_name_parse(
ut_ad(0); // the caller checked this
/* fall through */
case MLOG_FILE_NAME:
- if (corrupt) {
+ if (UNIV_UNLIKELY(corrupt)) {
ib::error() << "MLOG_FILE_NAME incorrect:" << ptr;
recv_sys->found_corrupt_log = true;
break;
@@ -608,7 +600,7 @@ fil_name_parse(
reinterpret_cast<char*>(ptr), len, space_id, false);
break;
case MLOG_FILE_DELETE:
- if (corrupt) {
+ if (UNIV_UNLIKELY(corrupt)) {
ib::error() << "MLOG_FILE_DELETE incorrect:" << ptr;
recv_sys->found_corrupt_log = true;
break;
@@ -636,7 +628,7 @@ fil_name_parse(
}
break;
case MLOG_FILE_RENAME2:
- if (corrupt) {
+ if (UNIV_UNLIKELY(corrupt)) {
ib::error() << "MLOG_FILE_RENAME2 incorrect:" << ptr;
recv_sys->found_corrupt_log = true;
}
@@ -677,7 +669,7 @@ fil_name_parse(
}
}
- if (corrupt) {
+ if (UNIV_UNLIKELY(corrupt)) {
ib::error() << "MLOG_FILE_RENAME2 new_name incorrect:" << ptr
<< " new_name: " << new_name;
recv_sys->found_corrupt_log = true;
@@ -761,7 +753,6 @@ recv_sys_var_init(void)
recv_previous_parsed_rec_type = MLOG_SINGLE_REC_FLAG;
recv_previous_parsed_rec_offset = 0;
recv_previous_parsed_rec_is_multi = 0;
- recv_n_pool_free_frames = 256;
recv_max_page_lsn = 0;
}
@@ -841,17 +832,10 @@ recv_sys_init()
recv_sys->flush_end = os_event_create(0);
}
- ulint size = buf_pool_get_curr_size();
- /* Set appropriate value of recv_n_pool_free_frames. */
- if (size >= 10 << 20) {
- /* Buffer pool of size greater than 10 MB. */
- recv_n_pool_free_frames = 512;
- }
-
recv_sys->buf = static_cast<byte*>(
ut_malloc_nokey(RECV_PARSING_BUF_SIZE));
- recv_sys->addr_hash = hash_create(size / 512);
+ recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
recv_sys->progress_time = time(NULL);
recv_max_page_lsn = 0;
@@ -981,6 +965,8 @@ fail:
}
});
+ DBUG_EXECUTE_IF("log_checksum_mismatch", { cksum = crc + 1; });
+
if (crc != cksum) {
ib::error() << "Invalid log block checksum."
<< " block: " << block_number
@@ -1239,7 +1225,10 @@ recv_log_recover_10_3()
% univ_page_size.physical()),
OS_FILE_LOG_BLOCK_SIZE, buf, NULL);
- if (log_block_calc_checksum(buf) != log_block_get_checksum(buf)) {
+ const ulint cksum = log_block_get_checksum(buf);
+
+ if (cksum != LOG_NO_CHECKSUM_MAGIC
+ && cksum != log_block_calc_checksum_crc32(buf)) {
return(DB_CORRUPTION);
}
@@ -2309,14 +2298,105 @@ static void recv_read_in_area(const page_id_t page_id)
mutex_enter(&recv_sys->mutex);
}
+/** This is another low level function for the recovery system
+to create a page which has buffered page intialization redo log records.
+@param[in] page_id page to be created using redo logs
+@param[in,out] recv_addr Hashed redo logs for the given page id
+@return whether the page creation successfully */
+static buf_block_t* recv_recovery_create_page_low(const page_id_t page_id,
+ recv_addr_t* recv_addr)
+{
+ mtr_t mtr;
+ mlog_init_t::init& i = mlog_init.last(page_id);
+ const lsn_t end_lsn = UT_LIST_GET_LAST(recv_addr->rec_list)->end_lsn;
+
+ if (end_lsn < i.lsn)
+ {
+ DBUG_LOG("ib_log", "skip log for page "
+ << page_id
+ << " LSN " << end_lsn
+ << " < " << i.lsn);
+ recv_addr->state = RECV_PROCESSED;
+ignore:
+ ut_a(recv_sys->n_addrs);
+ recv_sys->n_addrs--;
+ return NULL;
+ }
+
+ fil_space_t* space = fil_space_acquire(recv_addr->space);
+ if (!space)
+ {
+ recv_addr->state = RECV_PROCESSED;
+ goto ignore;
+ }
+
+ if (space->enable_lsn)
+ {
+init_fail:
+ fil_space_release(space);
+ recv_addr->state = RECV_NOT_PROCESSED;
+ return NULL;
+ }
+
+ /* Determine if a tablespace could be for an internal table
+ for FULLTEXT INDEX. For those tables, no MLOG_INDEX_LOAD record
+ used to be written when redo logging was disabled. Hence, we
+ cannot optimize away page reads, because all the redo
+ log records for initializing and modifying the page in the
+ past could be older than the page in the data file.
+
+ The check is too broad, causing all
+ tables whose names start with FTS_ to skip the optimization. */
+
+ if (strstr(space->name, "/FTS_"))
+ goto init_fail;
+
+ mtr.start();
+ mtr.set_log_mode(MTR_LOG_NONE);
+ buf_block_t* block = buf_page_create(page_id, page_size_t(space->flags),
+ &mtr);
+ if (recv_addr->state == RECV_PROCESSED)
+ /* The page happened to exist in the buffer pool, or it was
+ just being read in. Before buf_page_get_with_no_latch() returned,
+ all changes must have been applied to the page already. */
+ mtr.commit();
+ else
+ {
+ i.created = true;
+ buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
+ recv_recover_page(block, mtr, recv_addr, i.lsn);
+ ut_ad(mtr.has_committed());
+ }
+
+ fil_space_release(space);
+ return block;
+}
+
+/** This is a low level function for the recovery system
+to create a page which has buffered intialized redo log records.
+@param[in] page_id page to be created using redo logs
+@return whether the page creation successfully */
+buf_block_t* recv_recovery_create_page_low(const page_id_t page_id)
+{
+ buf_block_t* block= NULL;
+ mutex_enter(&recv_sys->mutex);
+ recv_addr_t* recv_addr= recv_get_fil_addr_struct(page_id.space(),
+ page_id.page_no());
+ if (recv_addr && recv_addr->state == RECV_WILL_NOT_READ)
+ {
+ block= recv_recovery_create_page_low(page_id, recv_addr);
+ }
+ mutex_exit(&recv_sys->mutex);
+ return block;
+}
+
/** Apply the hash table of stored log records to persistent data pages.
@param[in] last_batch whether the change buffer merge will be
performed as part of the operation */
void recv_apply_hashed_log_recs(bool last_batch)
{
ut_ad(srv_operation == SRV_OPERATION_NORMAL
- || srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_EXPORT);
+ || is_mariabackup_restore_or_export());
mutex_enter(&recv_sys->mutex);
@@ -2334,9 +2414,8 @@ void recv_apply_hashed_log_recs(bool last_batch)
ut_ad(!last_batch == log_mutex_own());
- recv_no_ibuf_operations = !last_batch
- || srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_EXPORT;
+ recv_no_ibuf_operations
+ = !last_batch || is_mariabackup_restore_or_export();
ut_d(recv_no_log_write = recv_no_ibuf_operations);
@@ -2400,7 +2479,7 @@ ignore:
apply:
mtr.start();
mtr.set_log_mode(MTR_LOG_NONE);
- if (buf_block_t* block = buf_page_get_gen(
+ if (buf_block_t* block = buf_page_get_low(
page_id, univ_page_size,
RW_X_LATCH, NULL,
BUF_GET_IF_IN_POOL,
@@ -2414,77 +2493,9 @@ apply:
mtr.commit();
recv_read_in_area(page_id);
}
- } else {
- mlog_init_t::init& i = mlog_init.last(page_id);
- const lsn_t end_lsn = UT_LIST_GET_LAST(
- recv_addr->rec_list)->end_lsn;
-
- if (end_lsn < i.lsn) {
- DBUG_LOG("ib_log", "skip log for page "
- << page_id
- << " LSN " << end_lsn
- << " < " << i.lsn);
-skip:
- recv_addr->state = RECV_PROCESSED;
- goto ignore;
- }
-
- fil_space_t* space = fil_space_acquire(
- recv_addr->space);
- if (!space) {
- goto skip;
- }
-
- if (space->enable_lsn) {
-do_read:
- fil_space_release(space);
- recv_addr->state = RECV_NOT_PROCESSED;
- goto apply;
- }
-
- /* Determine if a tablespace could be
- for an internal table for FULLTEXT INDEX.
- For those tables, no MLOG_INDEX_LOAD record
- used to be written when redo logging was
- disabled. Hence, we cannot optimize
- away page reads, because all the redo
- log records for initializing and
- modifying the page in the past could
- be older than the page in the data
- file.
-
- The check is too broad, causing all
- tables whose names start with FTS_ to
- skip the optimization. */
-
- if (strstr(space->name, "/FTS_")) {
- goto do_read;
- }
-
- mtr.start();
- mtr.set_log_mode(MTR_LOG_NONE);
- buf_block_t* block = buf_page_create(
- page_id, page_size_t(space->flags),
- &mtr);
- if (recv_addr->state == RECV_PROCESSED) {
- /* The page happened to exist
- in the buffer pool, or it was
- just being read in. Before
- buf_page_get_with_no_latch()
- returned, all changes must have
- been applied to the page already. */
- mtr.commit();
- } else {
- i.created = true;
- buf_block_dbg_add_level(
- block, SYNC_NO_ORDER_CHECK);
- mtr.x_latch_at_savepoint(0, block);
- recv_recover_page(block, mtr,
- recv_addr, i.lsn);
- ut_ad(mtr.has_committed());
- }
-
- fil_space_release(space);
+ } else if (!recv_recovery_create_page_low(
+ page_id, recv_addr)) {
+ goto apply;
}
}
}
@@ -2575,10 +2586,10 @@ recv_parse_log_rec(
*body = NULL;
- UNIV_MEM_INVALID(type, sizeof *type);
- UNIV_MEM_INVALID(space, sizeof *space);
- UNIV_MEM_INVALID(page_no, sizeof *page_no);
- UNIV_MEM_INVALID(body, sizeof *body);
+ MEM_UNDEFINED(type, sizeof *type);
+ MEM_UNDEFINED(space, sizeof *space);
+ MEM_UNDEFINED(page_no, sizeof *page_no);
+ MEM_UNDEFINED(body, sizeof *body);
if (ptr == end_ptr) {
@@ -2691,6 +2702,7 @@ recv_calc_lsn_on_data_add(
@param[in] space tablespace ID (could be garbage)
@param[in] page_no page number (could be garbage)
@return whether processing should continue */
+ATTRIBUTE_COLD
static
bool
recv_report_corrupt_log(
@@ -2707,7 +2719,8 @@ recv_report_corrupt_log(
ib::info() << "Log record type " << type << ", page " << space << ":"
<< page_no << ". Log parsing proceeded successfully up to "
<< recv_sys->recovered_lsn << ". Previous log record type "
- << recv_previous_parsed_rec_type << ", is multi "
+ << recv_previous_parsed_rec_type
+ << ", is multi "
<< recv_previous_parsed_rec_is_multi << " Recv offset "
<< ptr_offset << ", prev "
<< recv_previous_parsed_rec_offset;
@@ -2758,14 +2771,40 @@ recv_mlog_index_load(ulint space_id, ulint page_no, lsn_t lsn)
}
}
+/** Check whether read redo log memory exceeds the available memory
+of buffer pool. Store last_stored_lsn if it is not in last phase
+@param[in] store whether to store page operations
+@param[in] available_mem Available memory in buffer pool to
+ read redo logs. */
+static bool recv_sys_heap_check(store_t* store, ulint available_mem)
+{
+ if (*store != STORE_NO
+ && mem_heap_get_size(recv_sys->heap) >= available_mem)
+ {
+ if (*store == STORE_YES)
+ recv_sys->last_stored_lsn= recv_sys->recovered_lsn;
+
+ *store= STORE_NO;
+ DBUG_PRINT("ib_log",("Ran out of memory and last "
+ "stored lsn " LSN_PF " last stored offset "
+ ULINTPF "\n",recv_sys->recovered_lsn,
+ recv_sys->recovered_offset));
+ return true;
+ }
+
+ return false;
+}
+
/** Parse log records from a buffer and optionally store them to a
hash table to wait merging to file pages.
-@param[in] checkpoint_lsn the LSN of the latest checkpoint
-@param[in] store whether to store page operations
-@param[in] apply whether to apply the records
+@param[in] checkpoint_lsn the LSN of the latest checkpoint
+@param[in] store whether to store page operations
+@param[in] available_mem memory to read the redo logs
+@param[in] apply whether to apply the records
@return whether MLOG_CHECKPOINT record was seen the first time,
or corruption was noticed */
-bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
+bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t* store,
+ ulint available_mem, bool apply)
{
byte* ptr;
byte* end_ptr;
@@ -2777,6 +2816,7 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
ulint space;
ulint page_no;
byte* body;
+ const bool last_phase = (*store == STORE_IF_EXISTS);
ut_ad(log_mutex_own());
ut_ad(mutex_own(&recv_sys->mutex));
@@ -2791,6 +2831,12 @@ loop:
return(false);
}
+ /* Check for memory overflow and ignore the parsing of remaining
+ redo log records if InnoDB ran out of memory */
+ if (recv_sys_heap_check(store, available_mem) && last_phase) {
+ return false;
+ }
+
switch (*ptr) {
case MLOG_CHECKPOINT:
#ifdef UNIV_LOG_LSN_DEBUG
@@ -2814,12 +2860,12 @@ loop:
len = recv_parse_log_rec(&type, ptr, end_ptr, &space,
&page_no, apply, &body);
- if (recv_sys->found_corrupt_log) {
+ if (UNIV_UNLIKELY(recv_sys->found_corrupt_log)) {
recv_report_corrupt_log(ptr, type, space, page_no);
return(true);
}
- if (recv_sys->found_corrupt_fs) {
+ if (UNIV_UNLIKELY(recv_sys->found_corrupt_fs)) {
return(true);
}
@@ -2876,8 +2922,9 @@ loop:
if (lsn == checkpoint_lsn) {
if (recv_sys->mlog_checkpoint_lsn) {
- ut_ad(recv_sys->mlog_checkpoint_lsn
- <= recv_sys->recovered_lsn);
+ /* There can be multiple
+ MLOG_CHECKPOINT lsn for the
+ same checkpoint. */
break;
}
recv_sys->mlog_checkpoint_lsn
@@ -2893,7 +2940,7 @@ loop:
break;
#endif /* UNIV_LOG_LSN_DEBUG */
default:
- switch (store) {
+ switch (*store) {
case STORE_NO:
break;
case STORE_IF_EXISTS:
@@ -2943,7 +2990,7 @@ loop:
&type, ptr, end_ptr, &space, &page_no,
false, &body);
- if (recv_sys->found_corrupt_log) {
+ if (UNIV_UNLIKELY(recv_sys->found_corrupt_log)) {
corrupted_log:
recv_report_corrupt_log(
ptr, type, space, page_no);
@@ -3036,13 +3083,13 @@ corrupted_log:
&type, ptr, end_ptr, &space, &page_no,
apply, &body);
- if (recv_sys->found_corrupt_log
+ if (UNIV_UNLIKELY(recv_sys->found_corrupt_log)
&& !recv_report_corrupt_log(
ptr, type, space, page_no)) {
return(true);
}
- if (recv_sys->found_corrupt_fs) {
+ if (UNIV_UNLIKELY(recv_sys->found_corrupt_fs)) {
return(true);
}
@@ -3077,7 +3124,7 @@ corrupted_log:
recv_parse_or_apply_log_rec_body(). */
break;
default:
- switch (store) {
+ switch (*store) {
case STORE_NO:
break;
case STORE_IF_EXISTS:
@@ -3120,7 +3167,6 @@ bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn)
if (!recv_sys->parse_start_lsn) {
/* Cannot start parsing yet because no start point for
it found */
-
return(false);
}
@@ -3141,7 +3187,6 @@ bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn)
}
if (more_len == 0) {
-
return(false);
}
@@ -3176,8 +3221,9 @@ bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn)
/** Moves the parsing buffer data left to the buffer start. */
void recv_sys_justify_left_parsing_buf()
{
- ut_memmove(recv_sys->buf, recv_sys->buf + recv_sys->recovered_offset,
- recv_sys->len - recv_sys->recovered_offset);
+ memmove(recv_sys->buf,
+ recv_sys->buf + recv_sys->recovered_offset,
+ recv_sys->len - recv_sys->recovered_offset);
recv_sys->len -= recv_sys->recovered_offset;
@@ -3187,26 +3233,30 @@ void recv_sys_justify_left_parsing_buf()
/** Scan redo log from a buffer and stores new log data to the parsing buffer.
Parse and hash the log records if new data found.
Apply log records automatically when the hash table becomes full.
+@param[in] available_mem we let the hash table of recs to
+ grow to this size, at the maximum
+@param[in,out] store_to_hash whether the records should be
+ stored to the hash table; this is
+ reset if just debug checking is
+ needed, or when the available_mem
+ runs out
+@param[in] log_block log segment
+@param[in] checkpoint_lsn latest checkpoint LSN
+@param[in] start_lsn buffer start LSN
+@param[in] end_lsn buffer end LSN
+@param[in,out] contiguous_lsn it is known that all groups contain
+ contiguous log data upto this lsn
+@param[out] group_scanned_lsn scanning succeeded upto this lsn
@return true if not able to scan any more in this log group */
-static
-bool
-recv_scan_log_recs(
-/*===============*/
- ulint available_memory,/*!< in: we let the hash table of recs
- to grow to this size, at the maximum */
- store_t* store_to_hash, /*!< in,out: whether the records should be
- stored to the hash table; this is reset
- if just debug checking is needed, or
- when the available_memory runs out */
- const byte* log_block, /*!< in: log segment */
- lsn_t checkpoint_lsn, /*!< in: latest checkpoint LSN */
- lsn_t start_lsn, /*!< in: buffer start LSN */
- lsn_t end_lsn, /*!< in: buffer end LSN */
- lsn_t* contiguous_lsn, /*!< in/out: it is known that all log
- groups contain contiguous log data up
- to this lsn */
- lsn_t* group_scanned_lsn)/*!< out: scanning succeeded up to
- this lsn */
+static bool recv_scan_log_recs(
+ ulint available_mem,
+ store_t* store_to_hash,
+ const byte* log_block,
+ lsn_t checkpoint_lsn,
+ lsn_t start_lsn,
+ lsn_t end_lsn,
+ lsn_t* contiguous_lsn,
+ lsn_t* group_scanned_lsn)
{
lsn_t scanned_lsn = start_lsn;
bool finished = false;
@@ -3214,14 +3264,13 @@ recv_scan_log_recs(
bool more_data = false;
bool apply = recv_sys->mlog_checkpoint_lsn != 0;
ulint recv_parsing_buf_size = RECV_PARSING_BUF_SIZE;
-
+ const bool last_phase = (*store_to_hash == STORE_IF_EXISTS);
ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_ad(end_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_ad(end_lsn >= start_lsn + OS_FILE_LOG_BLOCK_SIZE);
const byte* const log_end = log_block
+ ulint(end_lsn - start_lsn);
-
do {
ut_ad(!finished);
@@ -3332,6 +3381,13 @@ recv_scan_log_recs(
= log_block_get_checkpoint_no(log_block);
}
+ /* During last phase of scanning, there can be redo logs
+ left in recv_sys->buf to parse & store it in recv_sys->heap */
+ if (last_phase
+ && recv_sys->recovered_lsn < recv_sys->scanned_lsn) {
+ more_data = true;
+ }
+
if (data_len < OS_FILE_LOG_BLOCK_SIZE) {
/* Log data for this group ends here */
finished = true;
@@ -3349,7 +3405,8 @@ recv_scan_log_recs(
/* Try to parse more log records */
if (recv_parse_log_recs(checkpoint_lsn,
- *store_to_hash, apply)) {
+ store_to_hash, available_mem,
+ apply)) {
ut_ad(recv_sys->found_corrupt_log
|| recv_sys->found_corrupt_fs
|| recv_sys->mlog_checkpoint_lsn
@@ -3358,22 +3415,18 @@ recv_scan_log_recs(
goto func_exit;
}
- if (*store_to_hash != STORE_NO
- && mem_heap_get_size(recv_sys->heap) > available_memory) {
-
- DBUG_PRINT("ib_log", ("Ran out of memory and last "
- "stored lsn " LSN_PF,
- recv_sys->recovered_lsn));
-
- recv_sys->last_stored_lsn = recv_sys->recovered_lsn;
- *store_to_hash = STORE_NO;
- }
+ recv_sys_heap_check(store_to_hash, available_mem);
if (recv_sys->recovered_offset > recv_parsing_buf_size / 4) {
/* Move parsing buffer data to the buffer start */
-
recv_sys_justify_left_parsing_buf();
}
+
+ /* Need to re-parse the redo log which're stored
+ in recv_sys->buf */
+ if (last_phase && *store_to_hash == STORE_NO) {
+ finished = false;
+ }
}
func_exit:
@@ -3422,9 +3475,8 @@ recv_group_scan_log_recs(
lsn_t end_lsn;
store_t store_to_hash = recv_sys->mlog_checkpoint_lsn == 0
? STORE_NO : (last_phase ? STORE_IF_EXISTS : STORE_YES);
- ulint available_mem = UNIV_PAGE_SIZE
- * (buf_pool_get_n_pages()
- - (recv_n_pool_free_frames * srv_buf_pool_instances));
+ ulint available_mem = (buf_pool_get_n_pages() * 2 / 3)
+ << srv_page_size_shift;
group->scanned_lsn = end_lsn = *contiguous_lsn = ut_uint64_align_down(
*contiguous_lsn, OS_FILE_LOG_BLOCK_SIZE);
@@ -3437,6 +3489,8 @@ recv_group_scan_log_recs(
redo log records before we have
finished the redo log scan. */
recv_apply_hashed_log_recs(false);
+ /* Rescan the redo logs from last stored lsn */
+ end_lsn = recv_sys->recovered_lsn;
}
start_lsn = ut_uint64_align_down(end_lsn,
@@ -3448,8 +3502,7 @@ recv_group_scan_log_recs(
} while (end_lsn != start_lsn
&& !recv_scan_log_recs(
available_mem, &store_to_hash, log_sys->buf,
- checkpoint_lsn,
- start_lsn, end_lsn,
+ checkpoint_lsn, start_lsn, end_lsn,
contiguous_lsn, &group->scanned_lsn));
if (recv_sys->found_corrupt_log || recv_sys->found_corrupt_fs) {
@@ -3471,8 +3524,7 @@ static
dberr_t
recv_init_missing_space(dberr_t err, const recv_spaces_t::const_iterator& i)
{
- if (srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_EXPORT) {
+ if (is_mariabackup_restore_or_export()) {
ib::warn() << "Tablespace " << i->first << " was not"
" found at " << i->second.name << " when"
" restoring a (partial?) backup. All redo log"
@@ -3553,7 +3605,7 @@ recv_validate_tablespace(bool rescan, bool& missing_tablespace)
for (recv_spaces_t::iterator i = recv_spaces.begin();
i != recv_spaces.end(); i++) {
- if (i->second.status != file_name_t::MISSING) {
+ if (UNIV_LIKELY(i->second.status != file_name_t::MISSING)) {
continue;
}
@@ -3649,8 +3701,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
dberr_t err = DB_SUCCESS;
ut_ad(srv_operation == SRV_OPERATION_NORMAL
- || srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_EXPORT);
+ || is_mariabackup_restore_or_export());
/* Initialize red-black tree for fast insertions into the
flush_list during recovery process. */
@@ -3864,6 +3915,8 @@ skip_apply:
rescan = true;
}
+ recv_sys->parse_start_lsn = checkpoint_lsn;
+
if (srv_operation == SRV_OPERATION_NORMAL) {
buf_dblwr_process();
}
@@ -4038,26 +4091,91 @@ recv_recovery_rollback_active(void)
}
}
-/** Find a doublewrite copy of a page.
-@param[in] space_id tablespace identifier
-@param[in] page_no page number
-@return page frame
-@retval NULL if no page was found */
-const byte*
-recv_dblwr_t::find_page(ulint space_id, ulint page_no)
+bool recv_dblwr_t::validate_page(const page_id_t page_id,
+ const byte *page,
+ const fil_space_t *space,
+ byte *tmp_buf)
+{
+ if (page_id.page_no() == 0)
+ {
+ ulint flags= fsp_header_get_flags(page);
+ if (!fsp_flags_is_valid(flags, page_id.space()))
+ {
+ ulint cflags= fsp_flags_convert_from_101(flags);
+ if (cflags == ULINT_UNDEFINED)
+ {
+ ib::warn() << "Ignoring a doublewrite copy of page " << page_id
+ << "due to invalid flags " << ib::hex(flags);
+ return false;
+ }
+
+ flags= cflags;
+ }
+
+ /* Page 0 is never page_compressed or encrypted. */
+ return !buf_page_is_corrupted(true, page, page_size_t(flags));
+ }
+
+ ut_ad(tmp_buf);
+ byte *tmp_frame= tmp_buf;
+ byte *tmp_page= tmp_buf + srv_page_size;
+ const uint16_t page_type= mach_read_from_2(page + FIL_PAGE_TYPE);
+ const page_size_t page_size(space->flags);
+ const bool expect_encrypted= space->crypt_data &&
+ space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED;
+
+ if (expect_encrypted &&
+ mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION))
+ {
+ if (!fil_space_verify_crypt_checksum(page, page_size))
+ return false;
+ if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED)
+ return true;
+ if (page_size.is_compressed())
+ return false;
+ memcpy(tmp_page, page, page_size.physical());
+ if (!fil_space_decrypt(space, tmp_frame, tmp_page))
+ return false;
+ }
+
+ switch (page_type) {
+ case FIL_PAGE_PAGE_COMPRESSED:
+ memcpy(tmp_page, page, page_size.physical());
+ /* fall through */
+ case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED:
+ if (page_size.is_compressed())
+ return false; /* ROW_FORMAT=COMPRESSED cannot be page_compressed */
+ ulint decomp= fil_page_decompress(tmp_frame, tmp_page);
+ if (!decomp)
+ return false; /* decompression failed */
+ if (decomp == srv_page_size)
+ return false; /* the page was not compressed (invalid page type) */
+ return !buf_page_is_corrupted(true, tmp_page, page_size, space);
+ }
+
+ return !buf_page_is_corrupted(true, page, page_size, space);
+}
+
+byte *recv_dblwr_t::find_page(const page_id_t page_id,
+ const fil_space_t *space, byte *tmp_buf)
{
- const byte *result= NULL;
+ byte *result= NULL;
lsn_t max_lsn= 0;
for (list::const_iterator i = pages.begin(); i != pages.end(); ++i)
{
- const byte *page= *i;
- if (page_get_page_no(page) != page_no ||
- page_get_space_id(page) != space_id)
+ byte *page= *i;
+ if (page_get_page_no(page) != page_id.page_no() ||
+ page_get_space_id(page) != page_id.space())
continue;
const lsn_t lsn= mach_read_from_8(page + FIL_PAGE_LSN);
- if (lsn <= max_lsn)
+ if (lsn <= max_lsn ||
+ !validate_page(page_id, page, space, tmp_buf))
+ {
+ /* Mark processed for subsequent iterations in buf_dblwr_process() */
+ memset(page + FIL_PAGE_LSN, 0, 8);
continue;
+ }
max_lsn= lsn;
result= page;
}
diff --git a/storage/innobase/mem/mem0mem.cc b/storage/innobase/mem/mem0mem.cc
index bcdb115812c..783451abbf2 100644
--- a/storage/innobase/mem/mem0mem.cc
+++ b/storage/innobase/mem/mem0mem.cc
@@ -222,8 +222,6 @@ mem_heap_validate(
block != NULL;
block = UT_LIST_GET_NEXT(list, block)) {
- mem_block_validate(block);
-
switch (block->type) {
case MEM_HEAP_DYNAMIC:
break;
@@ -278,7 +276,6 @@ mem_heap_create_block_func(
|| (type == MEM_HEAP_BUFFER + MEM_HEAP_BTR_SEARCH));
if (heap != NULL) {
- mem_block_validate(heap);
ut_d(mem_heap_validate(heap));
}
@@ -320,7 +317,6 @@ mem_heap_create_block_func(
block->buf_block = buf_block;
block->free_block = NULL;
- block->magic_n = MEM_BLOCK_MAGIC_N;
ut_d(ut_strlcpy_rev(block->file_name, file_name,
sizeof(block->file_name)));
ut_d(block->line = line);
@@ -338,8 +334,7 @@ mem_heap_create_block_func(
/* Not the first allocation for the heap. This block's
total_length field should be set to undefined. */
ut_d(block->total_size = ULINT_UNDEFINED);
- UNIV_MEM_INVALID(&block->total_size,
- sizeof block->total_size);
+ MEM_UNDEFINED(&block->total_size, sizeof block->total_size);
heap->total_size += len;
}
@@ -347,7 +342,7 @@ mem_heap_create_block_func(
/* Poison all available memory. Individual chunks will be unpoisoned on
every mem_heap_alloc() call. */
compile_time_assert(MEM_BLOCK_HEADER_SIZE >= sizeof *block);
- UNIV_MEM_FREE(block + 1, len - sizeof *block);
+ MEM_NOACCESS(block + 1, len - sizeof *block);
ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);
@@ -368,8 +363,6 @@ mem_heap_add_block(
mem_block_t* new_block;
ulint new_size;
- ut_d(mem_block_validate(heap));
-
block = UT_LIST_GET_LAST(heap->base);
/* We have to allocate a new block. The size is always at least
@@ -422,8 +415,6 @@ mem_heap_block_free(
buf_block = static_cast<buf_block_t*>(block->buf_block);
- mem_block_validate(block);
-
UT_LIST_REMOVE(heap->base, block);
ut_ad(heap->total_size >= block->len);
@@ -431,7 +422,6 @@ mem_heap_block_free(
type = heap->type;
len = block->len;
- block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
ut_ad(!buf_block);
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index b75a9c4cf02..424ac0b53f0 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -218,6 +218,13 @@ static void memo_slot_release(mtr_memo_slot_t *slot)
case MTR_MEMO_SX_LOCK:
rw_lock_sx_unlock(reinterpret_cast<rw_lock_t*>(slot->object));
break;
+ case MTR_MEMO_SPACE_X_LOCK:
+ {
+ fil_space_t *space= static_cast<fil_space_t*>(slot->object);
+ space->committed_size= space->size;
+ rw_lock_x_unlock(&space->latch);
+ }
+ break;
case MTR_MEMO_X_LOCK:
rw_lock_x_unlock(reinterpret_cast<rw_lock_t*>(slot->object));
break;
@@ -251,6 +258,13 @@ struct ReleaseLatches {
case MTR_MEMO_S_LOCK:
rw_lock_s_unlock(reinterpret_cast<rw_lock_t*>(slot->object));
break;
+ case MTR_MEMO_SPACE_X_LOCK:
+ {
+ fil_space_t *space= static_cast<fil_space_t*>(slot->object);
+ space->committed_size= space->size;
+ rw_lock_x_unlock(&space->latch);
+ }
+ break;
case MTR_MEMO_X_LOCK:
rw_lock_x_unlock(reinterpret_cast<rw_lock_t*>(slot->object));
break;
@@ -294,6 +308,24 @@ struct DebugCheck {
};
#endif
+/** Find buffer fix count of the given block acquired by the
+mini-transaction */
+struct FindBlock
+{
+ int32_t num_fix;
+ const buf_block_t *const block;
+
+ FindBlock(const buf_block_t *block_buf): num_fix(0), block(block_buf) {}
+
+ bool operator()(const mtr_memo_slot_t* slot)
+ {
+ if (slot->object == block)
+ ut_d(if (slot->type != MTR_MEMO_MODIFY))
+ num_fix++;
+ return true;
+ }
+};
+
/** Release a resource acquired by the mini-transaction. */
struct ReleaseBlocks {
/** Release specific object */
@@ -378,7 +410,7 @@ mtr_write_log(
/** Start a mini-transaction. */
void mtr_t::start()
{
- UNIV_MEM_INVALID(this, sizeof *this);
+ MEM_UNDEFINED(this, sizeof *this);
new(&m_memo) mtr_buf_t();
new(&m_log) mtr_buf_t();
@@ -564,13 +596,23 @@ mtr_t::x_lock_space(ulint space_id, const char* file, unsigned line)
ut_ad(space);
ut_ad(space->id == space_id);
- x_lock(&space->latch, file, line);
+ x_lock_space(space, file, line);
ut_ad(space->purpose == FIL_TYPE_TEMPORARY
|| space->purpose == FIL_TYPE_IMPORT
|| space->purpose == FIL_TYPE_TABLESPACE);
return(space);
}
+/** Exclusively aqcuire a tablespace latch.
+@param space tablespace
+@param file source code file name of the caller
+@param line source code line number */
+void mtr_t::x_lock_space(fil_space_t *space, const char *file, unsigned line)
+{
+ rw_lock_x_lock_inline(&space->latch, 0, file, line);
+ memo_push(space, MTR_MEMO_SPACE_X_LOCK);
+}
+
/** Look up the system tablespace. */
void
mtr_t::lookup_sys_space()
@@ -764,27 +806,28 @@ with index pages.
void
mtr_t::release_free_extents(ulint n_reserved)
{
- fil_space_t* space;
-
- ut_ad(!m_undo_space);
-
- if (m_user_space) {
+ fil_space_t *space= m_user_space;
- ut_ad(m_user_space->id == m_user_space_id);
- ut_ad(memo_contains(get_memo(), &m_user_space->latch,
- MTR_MEMO_X_LOCK));
+ ut_ad(!m_undo_space);
- space = m_user_space;
- } else {
-
- ut_ad(m_sys_space->id == TRX_SYS_SPACE);
- ut_ad(memo_contains(get_memo(), &m_sys_space->latch,
- MTR_MEMO_X_LOCK));
+ if (space)
+ ut_ad(m_user_space->id == m_user_space_id);
+ else
+ {
+ ut_ad(m_sys_space->id == TRX_SYS_SPACE);
+ space= m_sys_space;
+ }
- space = m_sys_space;
- }
+ ut_ad(memo_contains(get_memo(), space, MTR_MEMO_SPACE_X_LOCK));
+ space->release_free_extents(n_reserved);
+}
- space->release_free_extents(n_reserved);
+int32_t mtr_t::get_fix_count(buf_block_t *block)
+{
+ Iterate<FindBlock> iteration((FindBlock(block)));
+ if (m_memo.for_each_block(iteration))
+ return iteration.functor.num_fix;
+ return 0;
}
#ifdef UNIV_DEBUG
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index fc411dad564..5c6da7ad51c 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -1,8 +1,8 @@
/***********************************************************************
-Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2019, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
@@ -413,7 +413,7 @@ public:
/** Accessor for the AIO context
@param[in] segment Segment for which to get the context
@return the AIO context for the segment */
- io_context* io_ctx(ulint segment)
+ io_context_t io_ctx(ulint segment)
MY_ATTRIBUTE((warn_unused_result))
{
ut_ad(segment < get_n_segments());
@@ -421,11 +421,11 @@ public:
return(m_aio_ctx[segment]);
}
- /** Creates an io_context for native linux AIO.
+ /** Creates an io_context_t for native linux AIO.
@param[in] max_events number of events
@param[out] io_ctx io_ctx to initialize.
@return true on success. */
- static bool linux_create_io_ctx(unsigned max_events, io_context_t* io_ctx)
+ static bool linux_create_io_ctx(unsigned max_events, io_context_t& io_ctx)
MY_ATTRIBUTE((warn_unused_result));
/** Checks if the system supports native linux aio. On some kernel
@@ -622,7 +622,7 @@ private:
/** completion queue for IO. There is one such queue per
segment. Each thread will work on one ctx exclusively. */
- io_context_t* m_aio_ctx;
+ std::vector<io_context_t> m_aio_ctx;
/** The array to collect completed IOs. There is one such
event for each possible pending IO. The size of the array
@@ -1474,6 +1474,12 @@ os_file_get_parent_dir(
return(NULL);
}
+ if (last_slash - path < 0) {
+ /* Sanity check, it prevents gcc from trying to handle this case which
+ * results in warnings for some optimized builds */
+ return (NULL);
+ }
+
/* Non-trivial directory component */
return(mem_strdupl(path, last_slash - path));
@@ -1792,10 +1798,14 @@ LinuxAIOHandler::resubmit(Slot* slot)
iocb->data = slot;
+ ut_a(reinterpret_cast<size_t>(iocb->u.c.buf) % OS_FILE_LOG_BLOCK_SIZE
+ == 0);
+
/* Resubmit an I/O request */
int ret = io_submit(m_array->io_ctx(m_segment), 1, &iocb);
+ ut_a(ret != -EINVAL);
- if (ret < -1) {
+ if (ret < 0) {
errno = -ret;
}
@@ -1896,8 +1906,8 @@ LinuxAIOHandler::collect()
ut_ad(m_array != NULL);
ut_ad(m_segment < m_array->get_n_segments());
- /* Which io_context we are going to use. */
- io_context* io_ctx = m_array->io_ctx(m_segment);
+ /* Which io_context_t we are going to use. */
+ io_context_t io_ctx = m_array->io_ctx(m_segment);
/* Starting point of the m_segment we will be working on. */
ulint start_pos = m_segment * m_n_slots;
@@ -1924,6 +1934,8 @@ LinuxAIOHandler::collect()
int ret;
ret = io_getevents(io_ctx, 1, m_n_slots, events, &timeout);
+ ut_a(ret != -EINVAL);
+ ut_ad(ret != -EFAULT);
for (int i = 0; i < ret; ++i) {
@@ -2150,14 +2162,18 @@ AIO::linux_dispatch(Slot* slot)
/* Find out what we are going to work with.
The iocb struct is directly in the slot.
- The io_context is one per segment. */
+ The io_context_t is one per segment. */
ulint io_ctx_index;
struct iocb* iocb = &slot->control;
io_ctx_index = (slot->pos * m_n_segments) / m_slots.size();
- int ret = io_submit(m_aio_ctx[io_ctx_index], 1, &iocb);
+ ut_a(reinterpret_cast<size_t>(iocb->u.c.buf) % OS_FILE_LOG_BLOCK_SIZE
+ == 0);
+
+ int ret = io_submit(io_ctx(io_ctx_index), 1, &iocb);
+ ut_a(ret != -EINVAL);
/* io_submit() returns number of successfully queued requests
or -errno. */
@@ -2169,25 +2185,26 @@ AIO::linux_dispatch(Slot* slot)
return(ret == 1);
}
-/** Creates an io_context for native linux AIO.
+/** Creates an io_context_t for native linux AIO.
@param[in] max_events number of events
@param[out] io_ctx io_ctx to initialize.
@return true on success. */
bool
AIO::linux_create_io_ctx(
unsigned max_events,
- io_context_t* io_ctx)
+ io_context_t& io_ctx)
{
ssize_t n_retries = 0;
for (;;) {
- memset(io_ctx, 0x0, sizeof(*io_ctx));
+ memset(&io_ctx, 0x0, sizeof(io_ctx));
/* Initialize the io_ctx. Tell it how many pending
IO requests this context will handle. */
- int ret = io_setup(max_events, io_ctx);
+ int ret = io_setup(max_events, &io_ctx);
+ ut_a(ret != -EINVAL);
if (ret == 0) {
/* Success. Return now. */
@@ -2221,14 +2238,14 @@ AIO::linux_create_io_ctx(
}
/* Have tried enough. Better call it a day. */
- ib::error()
+ ib::warn()
<< "io_setup() failed with EAGAIN after "
<< OS_AIO_IO_SETUP_RETRY_ATTEMPTS
<< " attempts.";
break;
case -ENOSYS:
- ib::error()
+ ib::warn()
<< "Linux Native AIO interface"
" is not supported on this platform. Please"
" check your OS documentation and install"
@@ -2237,7 +2254,7 @@ AIO::linux_create_io_ctx(
break;
default:
- ib::error()
+ ib::warn()
<< "Linux Native AIO setup"
<< " returned following error["
<< ret << "]";
@@ -2266,7 +2283,7 @@ AIO::is_linux_native_aio_supported()
io_context_t io_ctx;
char name[1000];
- if (!linux_create_io_ctx(1, &io_ctx)) {
+ if (!linux_create_io_ctx(1, io_ctx)) {
/* The platform does not support native aio. */
@@ -2282,6 +2299,10 @@ AIO::is_linux_native_aio_supported()
<< "Unable to create temp file to check"
" native AIO support.";
+ int ret = io_destroy(io_ctx);
+ ut_a(ret != -EINVAL);
+ ut_ad(ret != -EFAULT);
+
return(false);
}
} else {
@@ -2311,6 +2332,10 @@ AIO::is_linux_native_aio_supported()
<< " \"" << name << "\" to check native"
<< " AIO read support.";
+ int ret = io_destroy(io_ctx);
+ ut_a(ret != EINVAL);
+ ut_ad(ret != EFAULT);
+
return(false);
}
}
@@ -2335,15 +2360,19 @@ AIO::is_linux_native_aio_supported()
io_prep_pwrite(p_iocb, fd, ptr, UNIV_PAGE_SIZE, 0);
} else {
- ut_a(UNIV_PAGE_SIZE >= 512);
- io_prep_pread(p_iocb, fd, ptr, 512, 0);
+ ut_a(srv_page_size >= 4096);
+ io_prep_pread(p_iocb, fd, ptr, srv_page_size, 0);
}
+ ut_a(reinterpret_cast<size_t>(p_iocb->u.c.buf) % OS_FILE_LOG_BLOCK_SIZE
+ == 0);
int err = io_submit(io_ctx, 1, &p_iocb);
+ ut_a(err != -EINVAL);
if (err >= 1) {
/* Now collect the submitted IO request. */
err = io_getevents(io_ctx, 1, 1, &io_event, NULL);
+ ut_a(err != -EINVAL);
}
ut_free(buf);
@@ -2351,7 +2380,13 @@ AIO::is_linux_native_aio_supported()
switch (err) {
case 1:
- return(true);
+ {
+ int ret = io_destroy(io_ctx);
+ ut_a(ret != -EINVAL);
+ ut_ad(ret != -EFAULT);
+
+ return(true);
+ }
case -EINVAL:
case -ENOSYS:
@@ -2371,6 +2406,10 @@ AIO::is_linux_native_aio_supported()
<< "returned error[" << -err << "]";
}
+ int ret = io_destroy(io_ctx);
+ ut_a(ret != -EINVAL);
+ ut_ad(ret != -EFAULT);
+
return(false);
}
@@ -2379,12 +2418,12 @@ AIO::is_linux_native_aio_supported()
/** Retrieves the last error number if an error occurs in a file io function.
The number should be retrieved before any other OS calls (because they may
overwrite the error number). If the number is not known to this program,
-the OS error number + 100 is returned.
+the OS error number + OS_FILE_ERROR_MAX is returned.
@param[in] report_all_errors true if we want an error message
printed of all errors
@param[in] on_error_silent true then don't print any diagnostic
to the log
-@return error number, or OS error number + 100 */
+@return error number, or OS error number + OS_FILE_ERROR_MAX */
static
ulint
os_file_get_last_error_low(
@@ -2968,7 +3007,8 @@ os_file_create_func(
ut_a(type == OS_LOG_FILE
|| type == OS_DATA_FILE
- || type == OS_DATA_TEMP_FILE);
+ || type == OS_DATA_TEMP_FILE
+ || type == OS_DATA_FILE_NO_O_DIRECT);
ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL);
@@ -3015,7 +3055,8 @@ os_file_create_func(
/* We disable OS caching (O_DIRECT) only on data files */
if (!read_only
&& *success
- && (type != OS_LOG_FILE && type != OS_DATA_TEMP_FILE)
+ && (type != OS_LOG_FILE && type != OS_DATA_TEMP_FILE
+ && type != OS_DATA_FILE_NO_O_DIRECT)
&& (srv_file_flush_method == SRV_O_DIRECT
|| srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)) {
@@ -5396,7 +5437,7 @@ fallback:
? 0 : posix_fallocate(file, current_size,
size - current_size);
} while (err == EINTR
- && srv_shutdown_state == SRV_SHUTDOWN_NONE);
+ && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED);
switch (err) {
case 0:
@@ -5410,6 +5451,7 @@ fallback:
errno = err;
return false;
case EINVAL:
+ case EOPNOTSUPP:
/* fall back to the code below */
break;
}
@@ -5436,7 +5478,7 @@ fallback:
os_offset_t current_size = os_file_get_size(file);
while (current_size < size
- && srv_shutdown_state == SRV_SHUTDOWN_NONE) {
+ && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
ulint n_bytes;
if (size - current_size < (os_offset_t) buf_size) {
@@ -5779,8 +5821,7 @@ AIO::AIO(
m_n_segments(segments),
m_n_reserved()
# ifdef LINUX_NATIVE_AIO
- ,m_aio_ctx(),
- m_events(m_slots.size())
+ ,m_events(m_slots.size())
# endif /* LINUX_NATIVE_AIO */
#ifdef WIN_ASYNC_IO
,m_completion_port(new_completion_port())
@@ -5836,29 +5877,20 @@ AIO::init_slots()
dberr_t
AIO::init_linux_native_aio()
{
- /* Initialize the io_context array. One io_context
- per segment in the array. */
-
- ut_a(m_aio_ctx == NULL);
- m_aio_ctx = static_cast<io_context**>(
- ut_zalloc_nokey(m_n_segments * sizeof(*m_aio_ctx)));
-
- if (m_aio_ctx == NULL) {
- return(DB_OUT_OF_MEMORY);
- }
+ /* Initialize the io_context_t array. One io_context_t
+ per segment in the array. */
+ m_aio_ctx.resize(get_n_segments());
- io_context** ctx = m_aio_ctx;
ulint max_events = slots_per_segment();
- for (ulint i = 0; i < m_n_segments; ++i, ++ctx) {
+ for (std::vector<io_context_t>::iterator it = m_aio_ctx.begin(),
+ end = m_aio_ctx.end();
+ it != end; ++it) {
- if (!linux_create_io_ctx(max_events, ctx)) {
+ if (!linux_create_io_ctx(max_events, *it)) {
/* If something bad happened during aio setup
we disable linux native aio.
- The disadvantage will be a small memory leak
- at shutdown but that's ok compared to a crash
- or a not working server.
This frequently happens when running the test suite
with many threads on a system with low fs.aio-max-nr!
*/
@@ -5870,8 +5902,15 @@ AIO::init_linux_native_aio()
<< "try increasing system "
<< "fs.aio-max-nr to 1048576 or larger or "
<< "setting innodb_use_native_aio = 0 in my.cnf";
- ut_free(m_aio_ctx);
- m_aio_ctx = 0;
+
+ for (std::vector<io_context_t>::iterator it2
+ = m_aio_ctx.begin();
+ it2 != it; ++it2) {
+ int ret = io_destroy(*it2);
+ ut_a(ret != -EINVAL);
+ }
+
+ m_aio_ctx.clear();
srv_use_native_aio = FALSE;
return(DB_SUCCESS);
}
@@ -5947,15 +5986,15 @@ AIO::~AIO()
#if defined(LINUX_NATIVE_AIO)
if (srv_use_native_aio) {
- m_events.clear();
- ut_free(m_aio_ctx);
+ for (ulint i = 0; i < m_aio_ctx.size(); i++) {
+ int ret = io_destroy(m_aio_ctx[i]);
+ ut_a(ret != -EINVAL);
+ }
}
#endif /* LINUX_NATIVE_AIO */
#if defined(WIN_ASYNC_IO)
CloseHandle(m_completion_port);
#endif
-
- m_slots.clear();
}
/** Initializes the asynchronous io system. Creates one array each for ibuf
@@ -6249,6 +6288,10 @@ AIO::reserve_slot(
os_offset_t offset,
ulint len)
{
+ ut_ad(reinterpret_cast<size_t>(buf) % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
+
#ifdef WIN_ASYNC_IO
ut_a((len & 0xFFFFFFFFUL) == len);
#endif /* WIN_ASYNC_IO */
diff --git a/storage/innobase/os/os0proc.cc b/storage/innobase/os/os0proc.cc
index 70f389436fa..71cb88ae372 100644
--- a/storage/innobase/os/os0proc.cc
+++ b/storage/innobase/os/os0proc.cc
@@ -29,6 +29,7 @@ Created 9/30/1995 Heikki Tuuri
#ifdef HAVE_LINUX_LARGE_PAGES
# include "mysqld.h"
#endif
+#include "my_valgrind.h"
/* FreeBSD for example has only MAP_ANON, Linux has MAP_ANONYMOUS and
MAP_ANON but MAP_ANON is marked as deprecated */
@@ -101,7 +102,7 @@ os_mem_alloc_large(
my_atomic_addlint(
&os_total_large_mem_allocated, size);
- UNIV_MEM_ALLOC(ptr, size);
+ MEM_UNDEFINED(ptr, size);
return(ptr);
}
@@ -125,7 +126,7 @@ skip:
} else {
my_atomic_addlint(
&os_total_large_mem_allocated, size);
- UNIV_MEM_ALLOC(ptr, size);
+ MEM_UNDEFINED(ptr, size);
}
#else
size = getpagesize();
@@ -141,7 +142,7 @@ skip:
} else {
my_atomic_addlint(
&os_total_large_mem_allocated, size);
- UNIV_MEM_ALLOC(ptr, size);
+ MEM_UNDEFINED(ptr, size);
}
#endif
return(ptr);
@@ -157,6 +158,14 @@ os_mem_free_large(
{
ut_a(os_total_large_mem_allocated >= size);
+#ifdef __SANITIZE_ADDRESS__
+ // We could have manually poisoned that memory for ASAN.
+ // And we must unpoison it by ourself as specified in documentation
+ // for __asan_poison_memory_region() in sanitizer/asan_interface.h
+ // munmap() doesn't do it for us automatically.
+ MEM_UNDEFINED(ptr, size);
+#endif /* __SANITIZE_ADDRESS__ */
+
#ifdef HAVE_LINUX_LARGE_PAGES
if (my_use_large_pages && opt_large_page_size && !shmdt(ptr)) {
my_atomic_addlint(
diff --git a/storage/innobase/os/os0thread.cc b/storage/innobase/os/os0thread.cc
index b34d875b759..2aac53f572d 100644
--- a/storage/innobase/os/os0thread.cc
+++ b/storage/innobase/os/os0thread.cc
@@ -125,11 +125,17 @@ os_thread_create_func(
pthread_attr_t attr;
- pthread_attr_init(&attr);
+ int ret = pthread_attr_init(&attr);
+ if (UNIV_UNLIKELY(ret)) {
+ fprintf(stderr,
+ "InnoDB: Error: pthread_attr_init() returned %d\n",
+ ret);
+ abort();
+ }
my_atomic_addlint(&os_thread_count, 1);
- int ret = pthread_create(&new_thread_id, &attr, func, arg);
+ ret = pthread_create(&new_thread_id, &attr, func, arg);
ut_a(ret == 0);
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index b4ec3e6dcdf..6810edf6c33 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2018, 2019, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -35,38 +35,6 @@ Created 10/4/1994 Heikki Tuuri
#include <algorithm>
-/*******************************************************************//**
-This is a linear congruential generator PRNG. Returns a pseudo random
-number between 0 and 2^64-1 inclusive. The formula and the constants
-being used are:
-X[n+1] = (a * X[n] + c) mod m
-where:
-X[0] = my_interval_timer()
-a = 1103515245 (3^5 * 5 * 7 * 129749)
-c = 12345 (3 * 5 * 823)
-m = 18446744073709551616 (2^64)
-
-@return number between 0 and 2^64-1 */
-static
-ib_uint64_t
-page_cur_lcg_prng(void)
-/*===================*/
-{
-#define LCG_a 1103515245
-#define LCG_c 12345
- static uint64_t lcg_current;
-
- if (!lcg_current) {
- lcg_current = my_interval_timer();
- }
-
- /* no need to "% 2^64" explicitly because lcg_current is
- 64 bit and this will be done anyway */
- lcg_current = LCG_a * lcg_current + LCG_c;
-
- return(lcg_current);
-}
-
#ifdef BTR_CUR_HASH_ADAPT
# ifdef UNIV_SEARCH_PERF_STAT
static ulint page_cur_short_succ;
@@ -99,8 +67,8 @@ page_cur_try_search_shortcut(
ibool success = FALSE;
const page_t* page = buf_block_get_frame(block);
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(dtuple_check_typed(tuple));
@@ -183,8 +151,8 @@ page_cur_try_search_shortcut_bytes(
ibool success = FALSE;
const page_t* page = buf_block_get_frame(block);
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(dtuple_check_typed(tuple));
@@ -255,7 +223,7 @@ page_cur_rec_field_extends(
/*=======================*/
const dtuple_t* tuple, /*!< in: data tuple */
const rec_t* rec, /*!< in: record */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: compare nth field */
{
const dtype_t* type;
@@ -331,8 +299,8 @@ page_cur_search_with_match(
const page_zip_des_t* page_zip = buf_block_get_page_zip(block);
#endif /* UNIV_ZIP_DEBUG */
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(dtuple_validate(tuple));
@@ -594,8 +562,8 @@ page_cur_search_with_match_bytes(
const page_zip_des_t* page_zip = buf_block_get_page_zip(block);
#endif /* UNIV_ZIP_DEBUG */
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(dtuple_validate(tuple));
@@ -814,8 +782,7 @@ page_cur_open_on_rnd_user_rec(
buf_block_t* block, /*!< in: page */
page_cur_t* cursor) /*!< out: page cursor */
{
- ulint rnd;
- ulint n_recs = page_get_n_recs(buf_block_get_frame(block));
+ const ulint n_recs = page_get_n_recs(block->frame);
page_cur_set_before_first(block, cursor);
@@ -824,11 +791,8 @@ page_cur_open_on_rnd_user_rec(
return;
}
- rnd = (ulint) (page_cur_lcg_prng() % n_recs);
-
- do {
- page_cur_move_to_next(cursor);
- } while (rnd--);
+ cursor->rec = page_rec_get_nth(block->frame,
+ ut_rnd_interval(n_recs) + 1);
}
/** Write a redo log record of inserting a record into an index page.
@@ -868,11 +832,11 @@ page_cur_insert_rec_write_log(
{
mem_heap_t* heap = NULL;
- ulint cur_offs_[REC_OFFS_NORMAL_SIZE];
- ulint ins_offs_[REC_OFFS_NORMAL_SIZE];
+ rec_offs cur_offs_[REC_OFFS_NORMAL_SIZE];
+ rec_offs ins_offs_[REC_OFFS_NORMAL_SIZE];
- ulint* cur_offs;
- ulint* ins_offs;
+ rec_offs* cur_offs;
+ rec_offs* ins_offs;
rec_offs_init(cur_offs_);
rec_offs_init(ins_offs_);
@@ -1048,8 +1012,8 @@ page_cur_parse_insert_rec(
ulint info_and_status_bits = 0; /* remove warning */
page_cur_t cursor;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
page = block ? buf_block_get_frame(block) : NULL;
@@ -1212,6 +1176,52 @@ page_cur_parse_insert_rec(
return(const_cast<byte*>(ptr + end_seg_len));
}
+/************************************************************//**
+Allocates a block of memory from the heap of an index page.
+@return pointer to start of allocated buffer, or NULL if allocation fails */
+static
+byte*
+page_mem_alloc_heap(
+/*================*/
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
+ space available for inserting the record,
+ or NULL */
+ ulint need, /*!< in: total number of bytes needed */
+ ulint* heap_no)/*!< out: this contains the heap number
+ of the allocated record
+ if allocation succeeds */
+{
+ byte* block;
+ ulint avl_space;
+
+ ut_ad(page && heap_no);
+
+ avl_space = page_get_max_insert_size(page, 1);
+
+ if (avl_space >= need) {
+ const ulint h = page_dir_get_n_heap(page);
+ if (UNIV_UNLIKELY(h >= 8191)) {
+ /* At the minimum record size of 5+2 bytes,
+ we can only reach this condition when using
+ innodb_page_size=64k. */
+ ut_ad(srv_page_size == 65536);
+ return(NULL);
+ }
+ *heap_no = h;
+
+ block = page_header_get_ptr(page, PAGE_HEAP_TOP);
+
+ page_header_set_ptr(page, page_zip, PAGE_HEAP_TOP,
+ block + need);
+ page_dir_set_n_heap(page, page_zip, 1 + *heap_no);
+
+ return(block);
+ }
+
+ return(NULL);
+}
+
/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
@@ -1224,7 +1234,7 @@ page_cur_insert_rec_low(
which the new record is inserted */
dict_index_t* index, /*!< in: record descriptor */
const rec_t* rec, /*!< in: pointer to a physical record */
- ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(rec, index) */
mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
byte* insert_buf;
@@ -1253,7 +1263,7 @@ page_cur_insert_rec_low(
/* 1. Get the size of the physical record in the page */
rec_size = rec_offs_size(offsets);
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
{
const void* rec_start
= rec - rec_offs_extra_size(offsets);
@@ -1264,19 +1274,19 @@ page_cur_insert_rec_low(
: REC_N_OLD_EXTRA_BYTES);
/* All data bytes of the record must be valid. */
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
/* The variable-length header must be valid. */
- UNIV_MEM_ASSERT_RW(rec_start, extra_size);
+ MEM_CHECK_DEFINED(rec_start, extra_size);
}
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
/* 2. Try to find suitable space from page memory management */
free_rec = page_header_get_ptr(page, PAGE_FREE);
if (UNIV_LIKELY_NULL(free_rec)) {
/* Try to allocate from the head of the free list. */
- ulint foffsets_[REC_OFFS_NORMAL_SIZE];
- ulint* foffsets = foffsets_;
+ rec_offs foffsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* foffsets = foffsets_;
mem_heap_t* heap = NULL;
rec_offs_init(foffsets_);
@@ -1376,8 +1386,8 @@ use_heap:
rec_set_heap_no_old(insert_rec, heap_no);
}
- UNIV_MEM_ASSERT_RW(rec_get_start(insert_rec, offsets),
- rec_offs_size(offsets));
+ MEM_CHECK_DEFINED(rec_get_start(insert_rec, offsets),
+ rec_offs_size(offsets));
/* 6. Update the last insertion info in page header */
last_insert = page_header_get_ptr(page, PAGE_LAST_INSERT);
@@ -1469,7 +1479,7 @@ page_cur_insert_rec_zip(
page_cur_t* cursor, /*!< in/out: page cursor */
dict_index_t* index, /*!< in: record descriptor */
const rec_t* rec, /*!< in: pointer to a physical record */
- ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(rec, index) */
mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
byte* insert_buf;
@@ -1505,7 +1515,7 @@ page_cur_insert_rec_zip(
/* 1. Get the size of the physical record in the page */
rec_size = rec_offs_size(offsets);
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
{
const void* rec_start
= rec - rec_offs_extra_size(offsets);
@@ -1516,11 +1526,11 @@ page_cur_insert_rec_zip(
: REC_N_OLD_EXTRA_BYTES);
/* All data bytes of the record must be valid. */
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
/* The variable-length header must be valid. */
- UNIV_MEM_ASSERT_RW(rec_start, extra_size);
+ MEM_CHECK_DEFINED(rec_start, extra_size);
}
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
const bool reorg_before_insert = page_has_garbage(page)
&& rec_size > page_get_max_insert_size(page, 1)
@@ -1706,8 +1716,8 @@ page_cur_insert_rec_zip(
if (UNIV_LIKELY_NULL(free_rec)) {
/* Try to allocate from the head of the free list. */
lint extra_size_diff;
- ulint foffsets_[REC_OFFS_NORMAL_SIZE];
- ulint* foffsets = foffsets_;
+ rec_offs foffsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* foffsets = foffsets_;
mem_heap_t* heap = NULL;
rec_offs_init(foffsets_);
@@ -1845,8 +1855,8 @@ use_heap:
rec_set_n_owned_new(insert_rec, NULL, 0);
rec_set_heap_no_new(insert_rec, heap_no);
- UNIV_MEM_ASSERT_RW(rec_get_start(insert_rec, offsets),
- rec_offs_size(offsets));
+ MEM_CHECK_DEFINED(rec_get_start(insert_rec, offsets),
+ rec_offs_size(offsets));
page_zip_dir_insert(page_zip, cursor->rec, free_rec, insert_rec);
@@ -2038,8 +2048,8 @@ page_copy_rec_list_end_to_created_page(
byte* log_ptr;
ulint log_data_len;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(page_dir_get_n_heap(new_page) == PAGE_HEAP_NO_USER_LOW);
@@ -2260,7 +2270,7 @@ page_cur_parse_delete_rec(
if (block) {
page_t* page = buf_block_get_frame(block);
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_t* rec = page + offset;
rec_offs_init(offsets_);
@@ -2288,7 +2298,7 @@ page_cur_delete_rec(
/*================*/
page_cur_t* cursor, /*!< in/out: a page cursor */
const dict_index_t* index, /*!< in: record descriptor */
- const ulint* offsets,/*!< in: rec_get_offsets(
+ const rec_offs* offsets,/*!< in: rec_get_offsets(
cursor->rec, index) */
mtr_t* mtr) /*!< in: mini-transaction handle
or NULL */
@@ -2426,18 +2436,17 @@ page_cur_delete_rec(
#ifdef UNIV_COMPILE_TEST_FUNCS
/*******************************************************************//**
-Print the first n numbers, generated by page_cur_lcg_prng() to make sure
+Print the first n numbers, generated by ut_rnd_gen() to make sure
(visually) that it works properly. */
void
-test_page_cur_lcg_prng(
-/*===================*/
+test_ut_rnd_gen(
int n) /*!< in: print first n numbers */
{
int i;
unsigned long long rnd;
for (i = 0; i < n; i++) {
- rnd = page_cur_lcg_prng();
+ rnd = ut_rnd_gen();
printf("%llu\t%%2=%llu %%3=%llu %%5=%llu %%7=%llu %%11=%llu\n",
rnd,
rnd % 2,
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index e316c8b1568..b078763c684 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -36,6 +36,7 @@ Created 2/2/1994 Heikki Tuuri
#include "fut0lst.h"
#include "btr0sea.h"
#include "trx0sys.h"
+#include <algorithm>
/* THE INDEX PAGE
==============
@@ -250,43 +251,6 @@ page_set_autoinc(
}
}
-/************************************************************//**
-Allocates a block of memory from the heap of an index page.
-@return pointer to start of allocated buffer, or NULL if allocation fails */
-byte*
-page_mem_alloc_heap(
-/*================*/
- page_t* page, /*!< in/out: index page */
- page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
- space available for inserting the record,
- or NULL */
- ulint need, /*!< in: total number of bytes needed */
- ulint* heap_no)/*!< out: this contains the heap number
- of the allocated record
- if allocation succeeds */
-{
- byte* block;
- ulint avl_space;
-
- ut_ad(page && heap_no);
-
- avl_space = page_get_max_insert_size(page, 1);
-
- if (avl_space >= need) {
- block = page_header_get_ptr(page, PAGE_HEAP_TOP);
-
- page_header_set_ptr(page, page_zip, PAGE_HEAP_TOP,
- block + need);
- *heap_no = page_dir_get_n_heap(page);
-
- page_dir_set_n_heap(page, page_zip, 1 + *heap_no);
-
- return(block);
- }
-
- return(NULL);
-}
-
/**********************************************************//**
Writes a log record of page creation. */
UNIV_INLINE
@@ -582,8 +546,8 @@ page_copy_rec_list_end_no_locks(
page_cur_t cur1;
rec_t* cur2;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
page_cur_position(rec, block, &cur1);
@@ -814,8 +778,8 @@ page_copy_rec_list_start(
rtr_rec_move_t* rec_move = NULL;
rec_t* ret
= page_rec_get_prev(page_get_supremum_rec(new_page));
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
/* Here, "ret" may be pointing to a user record or the
@@ -1049,8 +1013,8 @@ page_delete_rec_list_end(
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
page_t* page = page_align(rec);
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(size == ULINT_UNDEFINED || size < UNIV_PAGE_SIZE);
@@ -1250,8 +1214,8 @@ page_delete_rec_list_start(
mtr_t* mtr) /*!< in: mtr */
{
page_cur_t cur1;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
mem_heap_t* heap = NULL;
rec_offs_init(offsets_);
@@ -1738,7 +1702,7 @@ void
page_rec_print(
/*===========*/
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: record descriptor */
+ const rec_offs* offsets)/*!< in: record descriptor */
{
ut_a(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
rec_print_new(stderr, rec, offsets);
@@ -1813,8 +1777,8 @@ page_print_list(
ulint count;
ulint n_recs;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_a((ibool)!!page_is_comp(page) == dict_table_is_comp(index->table));
@@ -1924,7 +1888,7 @@ ibool
page_rec_validate(
/*==============*/
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_owned;
ulint heap_no;
@@ -2019,10 +1983,9 @@ page_simple_validate_old(
n_slots = page_dir_get_n_slots(page);
- if (UNIV_UNLIKELY(n_slots > UNIV_PAGE_SIZE / 4)) {
- ib::error() << "Nonsensical number " << n_slots
- << " of page dir slots";
-
+ if (UNIV_UNLIKELY(n_slots < 2 || n_slots > UNIV_PAGE_SIZE / 4)) {
+ ib::error() << "Nonsensical number of page dir slots: "
+ << n_slots;
goto func_exit;
}
@@ -2219,10 +2182,9 @@ page_simple_validate_new(
n_slots = page_dir_get_n_slots(page);
- if (UNIV_UNLIKELY(n_slots > UNIV_PAGE_SIZE / 4)) {
- ib::error() << "Nonsensical number " << n_slots
- << " of page dir slots";
-
+ if (UNIV_UNLIKELY(n_slots < 2 || n_slots > srv_page_size / 4)) {
+ ib::error() << "Nonsensical number of page dir slots: "
+ << n_slots;
goto func_exit;
}
@@ -2420,8 +2382,13 @@ page_validate(
ulint n_slots;
ibool ret = FALSE;
ulint i;
- ulint* offsets = NULL;
- ulint* old_offsets = NULL;
+ rec_offs offsets_1[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_2[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_1;
+ rec_offs* old_offsets = offsets_2;
+
+ rec_offs_init(offsets_1);
+ rec_offs_init(offsets_2);
#ifdef UNIV_GIS_DEBUG
if (dict_index_is_spatial(index)) {
@@ -2432,8 +2399,13 @@ page_validate(
if (UNIV_UNLIKELY((ibool) !!page_is_comp(page)
!= dict_table_is_comp(index->table))) {
ib::error() << "'compact format' flag mismatch";
- goto func_exit2;
+func_exit2:
+ ib::error() << "Apparent corruption in space "
+ << page_get_space_id(page) << " page "
+ << page_get_page_no(page) << " index " << index->name;
+ return FALSE;
}
+
if (page_is_comp(page)) {
if (UNIV_UNLIKELY(!page_simple_validate_new(page))) {
goto func_exit2;
@@ -2474,15 +2446,14 @@ page_validate(
n_slots = page_dir_get_n_slots(page);
- if (UNIV_UNLIKELY(!(page_header_get_ptr(page, PAGE_HEAP_TOP)
- <= page_dir_get_nth_slot(page, n_slots - 1)))) {
+ const void* top = page_header_get_ptr(page, PAGE_HEAP_TOP);
+ const void* last_slot = page_dir_get_nth_slot(page, n_slots - 1);
+ if (UNIV_UNLIKELY(top > last_slot)) {
ib::warn() << "Record heap and dir overlap on space "
<< page_get_space_id(page) << " page "
<< page_get_page_no(page) << " index " << index->name
- << ", " << page_header_get_ptr(page, PAGE_HEAP_TOP)
- << ", " << page_dir_get_nth_slot(page, n_slots - 1);
-
+ << ", " << top << ", " << last_slot;
goto func_exit;
}
@@ -2644,11 +2615,7 @@ page_validate(
}
/* set old_offsets to offsets; recycle offsets */
- {
- ulint* offs = old_offsets;
- old_offsets = offsets;
- offsets = offs;
- }
+ std::swap(old_offsets, offsets);
}
if (page_is_comp(page)) {
@@ -2745,10 +2712,7 @@ func_exit:
mem_heap_free(heap);
if (UNIV_UNLIKELY(ret == FALSE)) {
-func_exit2:
- ib::error() << "Apparent corruption in space "
- << page_get_space_id(page) << " page "
- << page_get_page_no(page) << " index " << index->name;
+ goto func_exit2;
}
return(ret);
@@ -2813,7 +2777,7 @@ page_delete_rec(
page_cur_t* pcur, /*!< in/out: page cursor on record
to delete */
page_zip_des_t* page_zip,/*!< in: compressed page descriptor */
- const ulint* offsets)/*!< in: offsets for record */
+ const rec_offs* offsets)/*!< in: offsets for record */
{
bool no_compress_needed;
buf_block_t* block = pcur->block;
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index d6abec57821..9664bda6fea 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -2,7 +2,7 @@
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -27,16 +27,14 @@ Created June 2005 by Marko Makela
#include "page0size.h"
#include "page0zip.h"
+#include "span.h"
+
+using st_::span;
/** A BLOB field reference full of zero, for use in assertions and tests.
Initially, BLOB field references are set to zero, in
dtuple_convert_big_rec(). */
-const byte field_ref_zero[FIELD_REF_SIZE] = {
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
-};
+const byte field_ref_zero[UNIV_PAGE_SIZE_MAX] = { 0, };
#ifndef UNIV_INNOCHECKSUM
#include "page0page.h"
@@ -110,7 +108,7 @@ Compare at most sizeof(field_ref_zero) bytes.
/** Assert that a BLOB pointer is filled with zero bytes.
@param b in: BLOB pointer */
#define ASSERT_ZERO_BLOB(b) \
- ut_ad(!memcmp(b, field_ref_zero, sizeof field_ref_zero))
+ ut_ad(!memcmp(b, field_ref_zero, FIELD_REF_SIZE))
/* Enable some extra debugging output. This code can be enabled
independently of any UNIV_ debugging conditions. */
@@ -880,7 +878,7 @@ page_zip_compress_node_ptrs(
mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err = Z_OK;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
do {
const rec_t* rec = *recs++;
@@ -890,9 +888,9 @@ page_zip_compress_node_ptrs(
/* Only leaf nodes may contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
/* Compress the extra bytes. */
c_stream->avail_in = static_cast<uInt>(
@@ -955,8 +953,8 @@ page_zip_compress_sec(
- c_stream->next_in);
if (UNIV_LIKELY(c_stream->avail_in != 0)) {
- UNIV_MEM_ASSERT_RW(c_stream->next_in,
- c_stream->avail_in);
+ MEM_CHECK_DEFINED(c_stream->next_in,
+ c_stream->avail_in);
err = deflate(c_stream, Z_NO_FLUSH);
if (UNIV_UNLIKELY(err != Z_OK)) {
break;
@@ -985,7 +983,7 @@ page_zip_compress_clust_ext(
FILE_LOGFILE
z_stream* c_stream, /*!< in/out: compressed page stream */
const rec_t* rec, /*!< in: record */
- const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec) */
ulint trx_id_col, /*!< in: position of of DB_TRX_ID */
byte* deleted, /*!< in: dense directory entry pointing
to the head of the free list */
@@ -998,9 +996,9 @@ page_zip_compress_clust_ext(
int err;
ulint i;
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
ulint len;
@@ -1124,7 +1122,7 @@ page_zip_compress_clust(
mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err = Z_OK;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
/* BTR_EXTERN_FIELD_REF storage */
byte* externs = storage - n_dense
* (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
@@ -1138,9 +1136,9 @@ page_zip_compress_clust(
ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_n_fields(offsets)
== dict_index_get_n_fields(index));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
/* Compress the extra bytes. */
c_stream->avail_in = static_cast<uInt>(
@@ -1187,9 +1185,9 @@ page_zip_compress_clust(
== rec_get_nth_field(rec, offsets,
trx_id_col + 1, &len));
ut_ad(len == DATA_ROLL_PTR_LEN);
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
/* Compress any preceding bytes. */
c_stream->avail_in = static_cast<uInt>(
@@ -1295,7 +1293,7 @@ page_zip_compress(
&& dict_table_is_comp(index->table)
&& !dict_index_is_ibuf(index)));
- UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
+ MEM_CHECK_DEFINED(page, srv_page_size);
/* Check the data that will be omitted. */
ut_a(!memcmp(page + (PAGE_NEW_INFIMUM - REC_N_NEW_EXTRA_BYTES),
@@ -1492,7 +1490,7 @@ page_zip_compress(
trx_id_col = ULINT_UNDEFINED;
}
- UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in);
+ MEM_CHECK_DEFINED(c_stream.next_in, c_stream.avail_in);
err = deflate(&c_stream, Z_FULL_FLUSH);
if (err != Z_OK) {
goto zlib_error;
@@ -1546,7 +1544,7 @@ page_zip_compress(
- (c_stream.next_in - page));
ut_a(c_stream.avail_in <= UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR);
- UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in);
+ MEM_CHECK_DEFINED(c_stream.next_in, c_stream.avail_in);
err = deflate(&c_stream, Z_FINISH);
if (UNIV_UNLIKELY(err != Z_STREAM_END)) {
@@ -1581,9 +1579,11 @@ err_exit:
ut_ad(buf + c_stream.total_out == c_stream.next_out);
ut_ad((ulint) (storage - c_stream.next_out) >= c_stream.avail_out);
+#ifdef HAVE_valgrind
/* Valgrind believes that zlib does not initialize some bits
in the last 7 or 8 bytes of the stream. Make Valgrind happy. */
- UNIV_MEM_VALID(buf, c_stream.total_out);
+ MEM_MAKE_DEFINED(buf, c_stream.total_out);
+#endif /* HAVE_valgrind */
/* Zero out the area reserved for the modification log.
Space for the end marker of the modification log is not
@@ -1615,7 +1615,7 @@ err_exit:
page_zip_compress_write_log(page_zip, page, index, mtr);
}
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
#ifdef PAGE_ZIP_COMPRESS_DBG
if (logfile) {
@@ -1656,7 +1656,7 @@ page_zip_fields_free(
{
if (index) {
dict_table_t* table = index->table;
- dict_index_zip_pad_mutex_destroy(index);
+ mysql_mutex_destroy(&index->zip_pad.mutex);
mem_heap_free(index->heap);
dict_mem_table_free(table);
@@ -1758,8 +1758,9 @@ page_zip_fields_decode(
if (!val) {
val = ULINT_UNDEFINED;
} else if (UNIV_UNLIKELY(val >= n)) {
+fail:
page_zip_fields_free(index);
- index = NULL;
+ return NULL;
} else {
index->type = DICT_CLUSTERED;
}
@@ -1768,8 +1769,7 @@ page_zip_fields_decode(
} else {
/* Decode the number of nullable fields. */
if (UNIV_UNLIKELY(index->n_nullable > val)) {
- page_zip_fields_free(index);
- index = NULL;
+ goto fail;
} else {
index->n_nullable = unsigned(val);
}
@@ -1984,7 +1984,7 @@ const byte*
page_zip_apply_log_ext(
/*===================*/
rec_t* rec, /*!< in/out: record */
- const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec) */
ulint trx_id_col, /*!< in: position of of DB_TRX_ID */
const byte* data, /*!< in: modification log */
const byte* end) /*!< in: end of modification log */
@@ -2085,7 +2085,7 @@ page_zip_apply_log(
/*!< in: heap_no and status bits for
the next record to uncompress */
dict_index_t* index, /*!< in: index of the page */
- ulint* offsets)/*!< in/out: work area for
+ rec_offs* offsets)/*!< in/out: work area for
rec_get_offsets_reverse() */
{
const byte* const end = data + size;
@@ -2153,7 +2153,7 @@ page_zip_apply_log(
if (val & 1) {
/* Clear the data bytes of the record. */
mem_heap_t* heap = NULL;
- ulint* offs;
+ rec_offs* offs;
offs = rec_get_offsets(rec, index, offsets, is_leaf,
ULINT_UNDEFINED, &heap);
memset(rec, 0, rec_offs_data_size(offs));
@@ -2305,7 +2305,7 @@ page_zip_decompress_node_ptrs(
sorted by address */
ulint n_dense, /*!< in: size of recs[] */
dict_index_t* index, /*!< in: the index of the page */
- ulint* offsets, /*!< in/out: temporary offsets */
+ rec_offs* offsets, /*!< in/out: temporary offsets */
mem_heap_t* heap) /*!< in: temporary memory heap */
{
ulint heap_status = REC_STATUS_NODE_PTR
@@ -2494,7 +2494,7 @@ page_zip_decompress_sec(
sorted by address */
ulint n_dense, /*!< in: size of recs[] */
dict_index_t* index, /*!< in: the index of the page */
- ulint* offsets) /*!< in/out: temporary offsets */
+ rec_offs* offsets) /*!< in/out: temporary offsets */
{
ulint heap_status = REC_STATUS_ORDINARY
| PAGE_HEAP_NO_USER_LOW << REC_HEAP_NO_SHIFT;
@@ -2626,7 +2626,7 @@ page_zip_decompress_clust_ext(
/*==========================*/
z_stream* d_stream, /*!< in/out: compressed page stream */
rec_t* rec, /*!< in/out: record */
- const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec) */
ulint trx_id_col) /*!< in: position of of DB_TRX_ID */
{
ulint i;
@@ -2741,7 +2741,7 @@ page_zip_decompress_clust(
ulint n_dense, /*!< in: size of recs[] */
dict_index_t* index, /*!< in: the index of the page */
ulint trx_id_col, /*!< index of the trx_id column */
- ulint* offsets, /*!< in/out: temporary offsets */
+ rec_offs* offsets, /*!< in/out: temporary offsets */
mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err;
@@ -3044,11 +3044,11 @@ page_zip_decompress_low(
ulint n_dense;/* number of user records on the page */
ulint trx_id_col = ULINT_UNDEFINED;
mem_heap_t* heap;
- ulint* offsets;
+ rec_offs* offsets;
ut_ad(page_zip_simple_validate(page_zip));
- UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_ADDRESSABLE(page, srv_page_size);
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
/* The dense directory excludes the infimum and supremum records. */
n_dense = page_dir_get_n_heap(page_zip->data) - PAGE_HEAP_NO_USER_LOW;
@@ -3092,9 +3092,9 @@ page_zip_decompress_low(
#ifdef UNIV_ZIP_DEBUG
/* Clear the uncompressed page, except the header. */
- memset(PAGE_DATA + page, 0x55, UNIV_PAGE_SIZE - PAGE_DATA);
+ memset(PAGE_DATA + page, 0x55, srv_page_size - PAGE_DATA);
#endif /* UNIV_ZIP_DEBUG */
- UNIV_MEM_INVALID(PAGE_DATA + page, UNIV_PAGE_SIZE - PAGE_DATA);
+ MEM_UNDEFINED(PAGE_DATA + page, srv_page_size - PAGE_DATA);
/* Copy the page directory. */
if (UNIV_UNLIKELY(!page_zip_dir_decode(page_zip, page, recs,
@@ -3168,10 +3168,10 @@ zlib_error:
ulint n = 1 + 1/* node ptr */ + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index);
- offsets = static_cast<ulint*>(
+ offsets = static_cast<rec_offs*>(
mem_heap_alloc(heap, n * sizeof(ulint)));
- *offsets = n;
+ rec_offs_set_n_alloc(offsets, n);
}
/* Decompress the records in heap_no order. */
@@ -3224,7 +3224,7 @@ err_exit:
}
ut_a(page_is_comp(page));
- UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
+ MEM_CHECK_DEFINED(page, srv_page_size);
page_zip_fields_free(index);
mem_heap_free(heap);
@@ -3336,7 +3336,19 @@ page_zip_validate_low(
FIL_PAGE_LSN - FIL_PAGE_PREV)
|| memcmp(page_zip->data + FIL_PAGE_TYPE, page + FIL_PAGE_TYPE, 2)
|| memcmp(page_zip->data + FIL_PAGE_DATA, page + FIL_PAGE_DATA,
- PAGE_DATA - FIL_PAGE_DATA)) {
+ PAGE_ROOT_AUTO_INC)
+ /* The PAGE_ROOT_AUTO_INC can be updated while holding an SX-latch
+ on the clustered index root page (page number 3 in .ibd files).
+ That allows concurrent readers (holding buf_block_t::lock S-latch).
+ Because we do not know what type of a latch our caller is holding,
+ we will ignore the field on clustered index root pages in order
+ to avoid false positives. */
+ || (page_get_page_no(page) != 3/* clustered index root page */
+ && memcmp(&page_zip->data[FIL_PAGE_DATA + PAGE_ROOT_AUTO_INC],
+ &page[FIL_PAGE_DATA + PAGE_ROOT_AUTO_INC], 8))
+ || memcmp(&page_zip->data[FIL_PAGE_DATA + PAGE_HEADER_PRIV_END],
+ &page[FIL_PAGE_DATA + PAGE_HEADER_PRIV_END],
+ PAGE_DATA - FIL_PAGE_DATA - PAGE_HEADER_PRIV_END)) {
page_zip_fail(("page_zip_validate: page header\n"));
page_zip_hexdump(page_zip, sizeof *page_zip);
page_zip_hexdump(page_zip->data, page_zip_get_size(page_zip));
@@ -3355,8 +3367,8 @@ page_zip_validate_low(
temp_page_buf = static_cast<byte*>(ut_malloc_nokey(2 * UNIV_PAGE_SIZE));
temp_page = static_cast<byte*>(ut_align(temp_page_buf, UNIV_PAGE_SIZE));
- UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page, srv_page_size);
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
temp_page_zip = *page_zip;
valid = page_zip_decompress_low(&temp_page_zip, temp_page, TRUE);
@@ -3395,7 +3407,7 @@ page_zip_validate_low(
committed. Let us tolerate that difference when we
are performing a sloppy validation. */
- ulint* offsets;
+ rec_offs* offsets;
mem_heap_t* heap;
const rec_t* rec;
const rec_t* trec;
@@ -3419,11 +3431,12 @@ page_zip_validate_low(
differed. Let us ignore it. */
page_zip_fail(("page_zip_validate:"
" min_rec_flag"
- " (%s%lu,%lu,0x%02lx)\n",
+ " (%s" ULINTPF "," ULINTPF
+ ",0x%02x)\n",
sloppy ? "ignored, " : "",
page_get_space_id(page),
page_get_page_no(page),
- (ulong) page[offset]));
+ page[offset]));
/* We don't check for spatial index, since
the "minimum record" could be deleted when
doing rtr_update_mbr_field.
@@ -3562,7 +3575,7 @@ page_zip_write_rec_ext(
const page_t* page, /*!< in: page containing rec */
const byte* rec, /*!< in: record being written */
dict_index_t* index, /*!< in: record descriptor */
- const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec, index) */
ulint create, /*!< in: nonzero=insert, zero=update */
ulint trx_id_col, /*!< in: position of DB_TRX_ID */
ulint heap_no, /*!< in: heap number of rec */
@@ -3576,9 +3589,9 @@ page_zip_write_rec_ext(
ulint n_ext = rec_offs_n_extern(offsets);
ut_ad(rec_offs_validate(rec, index, offsets));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
externs -= (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
* (page_dir_get_n_heap(page) - PAGE_HEAP_NO_USER_LOW);
@@ -3681,7 +3694,7 @@ page_zip_write_rec(
page_zip_des_t* page_zip,/*!< in/out: compressed page */
const byte* rec, /*!< in: record being written */
dict_index_t* index, /*!< in: the index the record belongs to */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint create) /*!< in: nonzero=insert, zero=update */
{
const page_t* page;
@@ -3703,10 +3716,10 @@ page_zip_write_rec(
ut_ad(page_zip_header_cmp(page_zip, page));
ut_ad(page_simple_validate_new((page_t*) page));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
@@ -3931,7 +3944,7 @@ page_zip_write_blob_ptr(
const byte* rec, /*!< in/out: record whose data is being
written */
dict_index_t* index, /*!< in: index of the page */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint n, /*!< in: column index */
mtr_t* mtr) /*!< in: mini-transaction handle,
or NULL if no logging is needed */
@@ -3961,10 +3974,10 @@ page_zip_write_blob_ptr(
ut_ad(page_is_leaf(page));
ut_ad(dict_index_is_clust(index));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
blob_no = page_zip_get_n_prev_extern(page_zip, rec, index)
+ rec_get_n_extern_new(rec, index, n);
@@ -4107,8 +4120,8 @@ page_zip_write_node_ptr(
ut_ad(!page_is_leaf(page));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, size);
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, size);
storage = page_zip_dir_start(page_zip)
- (rec_get_heap_no_new(rec) - 1) * REC_NODE_PTR_SIZE;
@@ -4149,7 +4162,7 @@ page_zip_write_trx_id_and_roll_ptr(
/*===============================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
byte* rec, /*!< in/out: record */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint trx_id_col,/*!< in: column number of TRX_ID in rec */
trx_id_t trx_id, /*!< in: transaction identifier */
roll_ptr_t roll_ptr)/*!< in: roll_ptr */
@@ -4173,7 +4186,7 @@ page_zip_write_trx_id_and_roll_ptr(
ut_ad(page_is_leaf(page));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
storage = page_zip_dir_start(page_zip)
- (rec_get_heap_no_new(rec) - 1)
@@ -4200,10 +4213,10 @@ page_zip_write_trx_id_and_roll_ptr(
mach_write_to_7(field + DATA_TRX_ID_LEN, roll_ptr);
memcpy(storage, field, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
}
/**********************************************************************//**
@@ -4216,7 +4229,7 @@ page_zip_clear_rec(
page_zip_des_t* page_zip, /*!< in/out: compressed page */
byte* rec, /*!< in: record to clear */
const dict_index_t* index, /*!< in: index of rec */
- const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets) /*!< in: rec_get_offsets(rec, index) */
{
ulint heap_no;
page_t* page = page_align(rec);
@@ -4233,10 +4246,10 @@ page_zip_clear_rec(
heap_no = rec_get_heap_no_new(rec);
ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
if (!page_is_leaf(page)) {
/* Clear node_ptr. On the compressed page,
@@ -4305,7 +4318,7 @@ page_zip_rec_set_deleted(
{
byte* slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (flag) {
*slot |= (PAGE_ZIP_DIR_SLOT_DEL >> 8);
} else {
@@ -4328,7 +4341,7 @@ page_zip_rec_set_owned(
{
byte* slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (flag) {
*slot |= (PAGE_ZIP_DIR_SLOT_OWNED >> 8);
} else {
@@ -4355,7 +4368,7 @@ page_zip_dir_insert(
ut_ad(page_rec_get_next((rec_t*) prev_rec) == rec);
ut_ad(page_zip_simple_validate(page_zip));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (page_rec_is_infimum(prev_rec)) {
/* Use the first slot. */
@@ -4422,7 +4435,7 @@ page_zip_dir_delete(
page_zip_des_t* page_zip, /*!< in/out: compressed page */
byte* rec, /*!< in: deleted record */
const dict_index_t* index, /*!< in: index of rec */
- const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec) */
const byte* free) /*!< in: previous start of
the free list */
{
@@ -4434,10 +4447,10 @@ page_zip_dir_delete(
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(rec_offs_comp(offsets));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
slot_rec = page_zip_dir_find(page_zip, page_offset(rec));
@@ -4526,7 +4539,7 @@ page_zip_dir_add_slot(
byte* stored;
ut_ad(page_is_comp(page_zip->data));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
/* Read the old n_dense (n_heap has already been incremented). */
n_dense = page_dir_get_n_heap(page_zip->data)
@@ -4688,8 +4701,8 @@ page_zip_reorganize(
ut_ad(!dict_index_is_ibuf(index));
ut_ad(!dict_table_is_temporary(index->table));
/* Note that page_zip_validate(page_zip, page, index) may fail here. */
- UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page, srv_page_size);
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
/* Disable logging */
mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
@@ -4776,10 +4789,10 @@ page_zip_copy_recs(
ut_a(dict_index_is_clust(index));
}
- UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
- UNIV_MEM_ASSERT_W(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(src, UNIV_PAGE_SIZE);
- UNIV_MEM_ASSERT_RW(src_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_ADDRESSABLE(page, srv_page_size);
+ MEM_CHECK_ADDRESSABLE(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(src, srv_page_size);
+ MEM_CHECK_DEFINED(src_zip->data, page_zip_get_size(page_zip));
/* Copy those B-tree page header fields that are related to
the records stored in the page. Also copy the field
@@ -4973,61 +4986,26 @@ page_zip_calc_checksum(
return(0);
}
-/**********************************************************************//**
-Verify a compressed page's checksum.
-@return TRUE if the stored checksum is valid according to the value of
-innodb_checksum_algorithm */
-ibool
-page_zip_verify_checksum(
-/*=====================*/
- const void* data, /*!< in: compressed page */
- ulint size) /*!< in: size of compressed page */
+/** Validate the checksum on a ROW_FORMAT=COMPRESSED page.
+@param data ROW_FORMAT=COMPRESSED page
+@param size size of the page, in bytes
+@return whether the stored checksum matches innodb_checksum_algorithm */
+bool page_zip_verify_checksum(const byte *data, size_t size)
{
- const uint32_t stored = mach_read_from_4(
- static_cast<const byte*>(data) + FIL_PAGE_SPACE_OR_CHKSUM);
-
-#if FIL_PAGE_LSN % 8
-#error "FIL_PAGE_LSN must be 64 bit aligned"
-#endif
-
- /* Check if page is empty */
- if (stored == 0
- && *reinterpret_cast<const ib_uint64_t*>(static_cast<const char*>(
- data)
- + FIL_PAGE_LSN) == 0) {
- /* make sure that the page is really empty */
-#ifdef UNIV_INNOCHECKSUM
- ulint i;
- for (i = 0; i < size; i++) {
- if (*((const char*) data + i) != 0)
- break;
- }
- if (i >= size) {
- if (log_file) {
- fprintf(log_file, "Page::%llu is empty and"
- " uncorrupted\n", cur_page_num);
- }
-
- return(TRUE);
- }
-#else
- for (ulint i = 0; i < size; i++) {
- if (*((const char*) data + i) != 0) {
- return(FALSE);
- }
- }
- /* Empty page */
- return(TRUE);
-#endif /* UNIV_INNOCHECKSUM */
- }
-
const srv_checksum_algorithm_t curr_algo =
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
- return(TRUE);
+ return true;
+ }
+
+ if (buf_is_zeroes(span<const byte>(data, size))) {
+ return true;
}
+ const uint32_t stored = mach_read_from_4(
+ data + FIL_PAGE_SPACE_OR_CHKSUM);
+
uint32_t calc = page_zip_calc_checksum(data, size, curr_algo);
#ifdef UNIV_INNOCHECKSUM
@@ -5042,7 +5020,6 @@ page_zip_verify_checksum(
}
if (!strict_verify) {
-
const uint32_t crc32 = page_zip_calc_checksum(
data, size, SRV_CHECKSUM_ALGORITHM_CRC32);
diff --git a/storage/innobase/pars/lexyy.cc b/storage/innobase/pars/lexyy.cc
index e7f3981e0fe..1e93ec3ed50 100644
--- a/storage/innobase/pars/lexyy.cc
+++ b/storage/innobase/pars/lexyy.cc
@@ -356,8 +356,8 @@ static void yynoreturn yy_fatal_error ( const char* msg );
(yy_hold_char) = *yy_cp; \
*yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp;
-#define YY_NUM_RULES 123
-#define YY_END_OF_BUFFER 124
+#define YY_NUM_RULES 102
+#define YY_END_OF_BUFFER 103
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -365,53 +365,42 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static const flex_int16_t yy_accept[404] =
+static const flex_int16_t yy_accept[307] =
{ 0,
- 0, 0, 118, 118, 0, 0, 0, 0, 124, 122,
- 121, 121, 8, 122, 113, 5, 102, 108, 111, 109,
- 106, 110, 122, 112, 1, 122, 107, 105, 103, 104,
- 116, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 114, 115, 118, 119, 6, 7, 9, 10, 121, 4,
- 97, 117, 2, 1, 3, 98, 99, 101, 100, 0,
- 95, 0, 95, 95, 95, 95, 95, 44, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 28, 17, 25, 95, 95, 95, 95,
-
- 95, 95, 54, 62, 95, 14, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 118, 119, 119, 120, 6, 7,
- 9, 10, 2, 0, 96, 13, 45, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 27, 95, 95, 95, 41,
- 95, 95, 95, 95, 21, 95, 95, 95, 95, 95,
- 15, 95, 95, 95, 18, 95, 95, 95, 95, 95,
- 81, 95, 95, 95, 51, 95, 12, 95, 36, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
-
- 0, 96, 95, 95, 95, 95, 20, 95, 24, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 46, 95, 30, 95, 88, 95, 95, 39, 95, 95,
- 95, 95, 95, 48, 95, 93, 90, 32, 92, 95,
- 11, 65, 95, 95, 95, 42, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 29, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 86, 0, 95, 26,
- 95, 95, 95, 67, 95, 95, 95, 95, 37, 95,
- 95, 95, 95, 95, 95, 31, 66, 23, 95, 59,
- 95, 76, 95, 95, 95, 43, 95, 95, 95, 95,
-
- 95, 95, 95, 95, 91, 95, 95, 56, 95, 95,
- 95, 95, 95, 95, 95, 40, 33, 0, 80, 94,
- 19, 95, 95, 84, 95, 75, 55, 95, 64, 95,
- 52, 95, 95, 47, 95, 77, 95, 79, 95, 95,
- 34, 95, 95, 95, 35, 73, 95, 95, 95, 95,
- 60, 95, 50, 49, 95, 95, 95, 57, 53, 63,
- 95, 95, 22, 95, 95, 74, 82, 95, 95, 78,
- 95, 69, 95, 95, 95, 95, 95, 38, 89, 68,
- 95, 85, 95, 95, 95, 87, 95, 95, 61, 16,
- 95, 71, 70, 95, 58, 83, 95, 95, 95, 95,
-
- 95, 72, 0
+ 0, 0, 97, 97, 0, 0, 0, 0, 103, 101,
+ 100, 100, 8, 101, 92, 5, 81, 87, 90, 88,
+ 85, 89, 101, 91, 1, 101, 86, 84, 82, 83,
+ 95, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+ 93, 94, 97, 98, 6, 7, 9, 10, 100, 4,
+ 76, 96, 2, 1, 3, 77, 78, 80, 79, 0,
+ 74, 0, 74, 74, 74, 74, 36, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+ 23, 17, 20, 74, 74, 74, 74, 74, 74, 46,
+
+ 52, 74, 14, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74, 97, 98,
+ 98, 99, 6, 7, 9, 10, 2, 0, 75, 13,
+ 37, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 22, 74, 74, 34, 74,
+ 74, 74, 74, 18, 74, 74, 74, 74, 74, 15,
+ 74, 74, 74, 74, 74, 74, 74, 43, 74, 12,
+ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+ 0, 75, 74, 74, 19, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 38, 25, 74, 67, 74,
+
+ 32, 74, 74, 74, 74, 40, 74, 72, 69, 27,
+ 71, 74, 11, 55, 74, 74, 74, 74, 74, 74,
+ 74, 74, 24, 74, 74, 74, 74, 74, 74, 66,
+ 0, 21, 74, 57, 74, 74, 74, 31, 74, 74,
+ 74, 74, 74, 26, 56, 74, 49, 74, 62, 74,
+ 74, 35, 74, 74, 74, 74, 70, 74, 48, 74,
+ 74, 74, 74, 33, 28, 0, 73, 74, 64, 61,
+ 47, 74, 54, 74, 44, 74, 39, 63, 74, 74,
+ 29, 74, 30, 60, 74, 50, 42, 41, 74, 45,
+ 53, 74, 74, 74, 74, 74, 74, 68, 58, 74,
+
+ 65, 74, 51, 16, 59, 0
} ;
static const YY_CHAR yy_ec[256] =
@@ -424,12 +413,12 @@ static const YY_CHAR yy_ec[256] =
17, 17, 17, 17, 17, 17, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 1, 1, 1, 1, 51, 1, 34, 34, 34, 34,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 34,
+ 1, 1, 1, 1, 50, 1, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 52, 34, 34,
- 34, 34, 53, 34, 54, 34, 34, 34, 34, 34,
- 34, 34, 55, 1, 56, 1, 1, 1, 1, 1,
+ 34, 34, 34, 34, 34, 34, 34, 51, 34, 34,
+ 34, 34, 52, 34, 53, 34, 34, 34, 34, 34,
+ 34, 34, 54, 1, 55, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -446,418 +435,324 @@ static const YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static const YY_CHAR yy_meta[57] =
+static const YY_CHAR yy_meta[56] =
{ 0,
1, 1, 1, 2, 3, 1, 1, 4, 1, 1,
5, 1, 1, 1, 1, 6, 7, 1, 1, 1,
8, 1, 1, 6, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 1, 1
+ 9, 9, 9, 1, 1
} ;
-static const flex_int16_t yy_base[417] =
+static const flex_int16_t yy_base[320] =
{ 0,
- 0, 0, 296, 281, 283, 280, 261, 252, 253, 1285,
- 55, 57, 1285, 0, 1285, 1285, 1285, 1285, 1285, 1285,
- 1285, 1285, 211, 213, 46, 202, 1285, 43, 1285, 199,
- 1285, 46, 50, 56, 52, 66, 64, 51, 81, 92,
- 91, 94, 96, 111, 113, 116, 130, 134, 53, 143,
- 1285, 1285, 0, 106, 0, 206, 0, 205, 141, 0,
- 1285, 1285, 177, 56, 152, 1285, 1285, 1285, 1285, 161,
- 140, 147, 152, 154, 155, 161, 167, 171, 177, 172,
- 184, 174, 188, 189, 191, 194, 203, 212, 217, 219,
- 222, 223, 228, 224, 226, 233, 235, 239, 244, 251,
-
- 256, 260, 261, 262, 265, 271, 266, 281, 277, 287,
- 282, 288, 303, 306, 307, 292, 310, 321, 322, 323,
- 324, 325, 335, 338, 0, 112, 173, 1285, 0, 152,
- 0, 145, 130, 59, 0, 339, 341, 353, 351, 354,
- 365, 367, 355, 372, 376, 383, 379, 386, 388, 385,
- 398, 392, 402, 401, 414, 415, 416, 417, 426, 430,
- 432, 437, 433, 439, 442, 443, 449, 456, 460, 461,
- 463, 470, 472, 473, 479, 483, 485, 489, 492, 495,
- 498, 499, 502, 508, 509, 514, 515, 518, 520, 527,
- 530, 534, 536, 541, 543, 553, 555, 557, 559, 568,
-
- 41, 0, 564, 569, 570, 573, 574, 585, 580, 589,
- 586, 595, 598, 600, 605, 610, 611, 617, 620, 615,
- 622, 627, 626, 631, 641, 642, 646, 647, 648, 651,
- 652, 653, 657, 662, 663, 667, 669, 673, 680, 682,
- 684, 685, 686, 687, 689, 696, 698, 700, 701, 703,
- 699, 710, 714, 716, 729, 732, 731, 733, 735, 734,
- 746, 747, 748, 752, 753, 759, 749, 39, 769, 770,
- 771, 773, 774, 780, 783, 784, 787, 785, 786, 802,
- 800, 803, 816, 817, 818, 819, 820, 823, 833, 835,
- 836, 837, 838, 839, 848, 849, 852, 853, 854, 859,
-
- 863, 870, 868, 872, 875, 884, 885, 887, 889, 890,
- 888, 904, 906, 907, 908, 918, 919, 73, 921, 922,
- 923, 924, 933, 934, 936, 937, 938, 939, 940, 949,
- 952, 955, 953, 965, 969, 970, 971, 972, 974, 975,
- 981, 984, 986, 988, 990, 991, 1000, 1006, 1004, 1009,
- 1016, 1018, 1020, 1021, 1025, 1027, 1032, 1034, 1038, 1039,
- 1041, 1043, 1048, 1050, 1052, 1055, 1059, 1064, 1066, 1068,
- 1071, 1073, 1077, 1084, 1086, 1087, 1091, 1093, 1098, 1100,
- 1102, 1104, 1105, 1111, 1114, 1116, 1117, 1118, 1120, 1127,
- 1129, 1130, 1134, 1139, 1141, 1145, 1146, 1148, 1150, 1151,
-
- 1155, 1157, 1285, 1197, 1206, 1215, 1218, 1221, 1225, 1234,
- 1243, 1252, 1261, 1268, 1272, 1275
+ 0, 0, 262, 259, 249, 244, 239, 234, 236, 960,
+ 54, 56, 960, 0, 960, 960, 960, 960, 960, 960,
+ 960, 960, 217, 220, 45, 186, 960, 42, 960, 184,
+ 960, 45, 49, 55, 51, 65, 80, 50, 69, 94,
+ 90, 92, 104, 60, 114, 116, 131, 134, 135, 149,
+ 960, 960, 0, 61, 0, 194, 0, 197, 133, 0,
+ 960, 960, 163, 53, 143, 960, 960, 960, 960, 147,
+ 125, 123, 138, 151, 152, 153, 155, 166, 169, 173,
+ 170, 171, 176, 180, 193, 182, 200, 204, 206, 209,
+ 210, 211, 213, 224, 225, 226, 235, 240, 242, 245,
+
+ 251, 252, 255, 256, 258, 261, 270, 274, 272, 277,
+ 289, 288, 276, 294, 295, 300, 304, 305, 0, 79,
+ 110, 960, 0, 116, 0, 113, 98, 58, 0, 306,
+ 315, 316, 318, 319, 322, 328, 329, 332, 334, 338,
+ 344, 353, 351, 354, 366, 360, 367, 369, 376, 378,
+ 381, 385, 388, 382, 394, 400, 403, 404, 406, 407,
+ 410, 417, 423, 424, 426, 429, 433, 440, 442, 443,
+ 444, 445, 454, 456, 459, 461, 472, 473, 474, 477,
+ 53, 0, 475, 478, 479, 490, 502, 504, 505, 507,
+ 508, 509, 511, 518, 520, 523, 524, 525, 529, 538,
+
+ 541, 542, 543, 545, 547, 544, 556, 557, 558, 559,
+ 560, 569, 572, 574, 578, 581, 579, 583, 588, 590,
+ 600, 601, 602, 607, 611, 613, 612, 618, 622, 629,
+ 41, 634, 636, 638, 639, 643, 645, 648, 649, 650,
+ 655, 659, 661, 660, 670, 675, 676, 679, 680, 682,
+ 686, 689, 691, 696, 693, 700, 705, 706, 709, 711,
+ 712, 716, 722, 723, 726, 72, 727, 736, 737, 738,
+ 739, 740, 742, 743, 752, 753, 755, 757, 758, 759,
+ 764, 770, 769, 771, 774, 784, 785, 786, 787, 789,
+ 790, 791, 796, 801, 802, 803, 806, 807, 812, 817,
+
+ 816, 823, 826, 828, 832, 960, 872, 881, 890, 893,
+ 896, 900, 909, 918, 927, 936, 943, 947, 950
} ;
-static const flex_int16_t yy_def[417] =
+static const flex_int16_t yy_def[320] =
{ 0,
- 403, 1, 404, 404, 405, 405, 406, 406, 403, 403,
- 403, 403, 403, 407, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 408, 403, 403, 403, 403,
- 403, 409, 409, 409, 409, 409, 34, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 403, 403, 410, 411, 412, 403, 413, 403, 403, 407,
- 403, 403, 403, 403, 408, 403, 403, 403, 403, 414,
- 409, 415, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
-
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 410, 411, 411, 403, 412, 403,
- 413, 403, 403, 403, 416, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
-
- 403, 416, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 403, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
-
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 403, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
- 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
-
- 409, 409, 0, 403, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403
+ 306, 1, 307, 307, 308, 308, 309, 309, 306, 306,
+ 306, 306, 306, 310, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 311, 306, 306, 306, 306,
+ 306, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 306, 306, 313, 314, 315, 306, 316, 306, 306, 310,
+ 306, 306, 306, 306, 311, 306, 306, 306, 306, 317,
+ 312, 318, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 313, 314,
+ 314, 306, 315, 306, 316, 306, 306, 306, 319, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 306, 319, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 306, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 306, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+
+ 312, 312, 312, 312, 312, 0, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306
} ;
-static const flex_int16_t yy_nxt[1342] =
+static const flex_int16_t yy_nxt[1016] =
{ 0,
10, 11, 12, 13, 10, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 10, 32, 33, 34, 35, 36, 37,
38, 38, 39, 38, 38, 40, 41, 42, 43, 44,
38, 45, 46, 47, 48, 49, 50, 38, 38, 38,
- 38, 38, 38, 38, 51, 52, 59, 59, 59, 59,
- 63, 70, 64, 67, 68, 70, 70, 70, 70, 72,
- 63, 70, 64, 72, 72, 72, 72, 122, 75, 72,
- 84, 70, 76, 73, 85, 77, 135, 79, 74, 72,
- 318, 80, 89, 268, 81, 71, 70, 82, 78, 90,
-
- 83, 86, 91, 87, 72, 92, 70, 70, 93, 70,
- 94, 70, 201, 88, 72, 72, 127, 72, 95, 72,
- 97, 128, 403, 96, 98, 103, 70, 403, 70, 100,
- 99, 70, 101, 104, 72, 105, 72, 106, 102, 72,
- 107, 109, 59, 59, 112, 70, 133, 113, 132, 70,
- 110, 111, 108, 72, 117, 70, 114, 72, 70, 130,
- 115, 118, 70, 72, 116, 134, 72, 70, 119, 70,
- 70, 120, 403, 121, 123, 72, 70, 72, 72, 136,
- 137, 124, 70, 127, 72, 139, 70, 70, 128, 70,
- 72, 140, 70, 133, 72, 72, 138, 72, 141, 70,
-
- 72, 143, 149, 70, 70, 142, 70, 72, 132, 70,
- 144, 72, 72, 130, 72, 151, 145, 72, 70, 69,
- 146, 147, 66, 62, 152, 61, 72, 70, 148, 150,
- 156, 153, 70, 154, 70, 72, 155, 70, 70, 70,
- 72, 70, 72, 70, 157, 72, 72, 72, 70, 72,
- 70, 72, 403, 163, 70, 58, 72, 159, 72, 70,
- 158, 161, 72, 160, 58, 162, 70, 72, 164, 165,
- 168, 70, 166, 167, 72, 70, 70, 70, 170, 72,
- 70, 70, 169, 72, 72, 72, 70, 56, 72, 72,
- 56, 54, 70, 173, 72, 172, 70, 70, 174, 171,
-
- 72, 178, 70, 70, 72, 72, 54, 70, 403, 175,
- 72, 72, 403, 176, 181, 72, 179, 182, 70, 177,
- 180, 70, 70, 184, 403, 70, 72, 186, 183, 72,
- 72, 185, 188, 72, 190, 191, 70, 70, 70, 70,
- 70, 187, 403, 189, 72, 72, 72, 72, 72, 192,
- 70, 196, 403, 70, 70, 194, 70, 403, 72, 403,
- 197, 72, 72, 198, 72, 195, 70, 199, 70, 70,
- 70, 403, 193, 403, 72, 403, 72, 72, 72, 200,
- 70, 203, 70, 204, 403, 403, 205, 70, 72, 206,
- 72, 70, 207, 208, 70, 72, 209, 403, 70, 72,
-
- 70, 70, 72, 70, 403, 214, 72, 70, 72, 72,
- 403, 72, 216, 70, 210, 72, 70, 70, 211, 212,
- 220, 72, 213, 215, 72, 72, 217, 218, 221, 70,
- 70, 70, 70, 219, 403, 403, 403, 72, 72, 72,
- 72, 70, 223, 226, 222, 70, 224, 70, 70, 72,
- 227, 403, 70, 72, 70, 72, 72, 70, 70, 225,
- 72, 230, 72, 229, 70, 72, 72, 231, 228, 403,
- 233, 70, 72, 235, 403, 70, 70, 236, 70, 72,
- 234, 403, 232, 72, 72, 70, 72, 70, 70, 239,
- 237, 403, 240, 72, 70, 72, 72, 403, 70, 238,
-
- 70, 243, 72, 403, 70, 241, 72, 70, 72, 242,
- 70, 245, 72, 70, 70, 72, 246, 70, 72, 403,
- 244, 72, 72, 70, 70, 72, 403, 247, 403, 70,
- 70, 72, 72, 70, 250, 70, 252, 72, 72, 248,
- 403, 72, 70, 72, 403, 70, 403, 403, 249, 70,
- 72, 70, 251, 72, 255, 253, 70, 72, 70, 72,
- 254, 258, 259, 403, 72, 256, 72, 403, 70, 403,
- 70, 257, 70, 260, 70, 262, 72, 263, 72, 70,
- 72, 261, 72, 70, 70, 70, 403, 72, 70, 70,
- 403, 72, 72, 72, 266, 70, 72, 72, 265, 264,
-
- 70, 70, 267, 72, 70, 269, 270, 271, 72, 72,
- 70, 403, 72, 70, 272, 70, 403, 274, 72, 273,
- 70, 72, 277, 72, 278, 70, 70, 276, 72, 275,
- 70, 403, 70, 72, 72, 70, 403, 70, 72, 281,
- 72, 70, 70, 72, 283, 72, 70, 403, 279, 72,
- 72, 403, 403, 280, 72, 282, 70, 70, 284, 285,
- 286, 70, 70, 70, 72, 72, 70, 70, 70, 72,
- 72, 72, 70, 287, 72, 72, 72, 70, 70, 403,
- 72, 403, 70, 403, 70, 72, 72, 293, 70, 288,
- 72, 289, 72, 291, 292, 70, 72, 70, 290, 70,
-
- 70, 70, 70, 72, 70, 72, 294, 72, 72, 72,
- 72, 70, 72, 70, 70, 70, 70, 298, 70, 72,
- 295, 72, 72, 72, 72, 70, 72, 296, 302, 70,
- 297, 70, 403, 72, 403, 403, 304, 72, 303, 72,
- 299, 300, 305, 301, 70, 403, 70, 70, 70, 70,
- 70, 403, 72, 307, 72, 72, 72, 72, 72, 306,
- 308, 70, 70, 70, 70, 309, 310, 70, 70, 72,
- 72, 72, 72, 403, 70, 72, 72, 313, 311, 403,
- 315, 316, 72, 403, 70, 70, 70, 317, 70, 70,
- 312, 314, 72, 72, 72, 70, 72, 72, 70, 70,
-
- 70, 70, 70, 72, 403, 403, 72, 72, 72, 72,
- 72, 323, 319, 325, 320, 70, 403, 70, 70, 403,
- 403, 321, 403, 72, 322, 72, 72, 324, 326, 403,
- 327, 70, 70, 70, 70, 70, 403, 328, 70, 72,
- 72, 72, 72, 72, 329, 331, 72, 403, 70, 403,
- 70, 70, 70, 70, 70, 332, 72, 330, 72, 72,
- 72, 72, 72, 70, 70, 333, 335, 70, 70, 70,
- 336, 72, 72, 403, 70, 72, 72, 72, 70, 334,
- 339, 338, 72, 70, 403, 70, 72, 70, 403, 403,
- 70, 72, 337, 72, 343, 72, 341, 340, 72, 70,
-
- 70, 403, 70, 70, 70, 70, 342, 72, 72, 344,
- 72, 72, 72, 72, 349, 345, 403, 403, 403, 70,
- 403, 70, 70, 70, 350, 346, 348, 72, 347, 72,
- 72, 72, 351, 70, 70, 353, 70, 70, 70, 70,
- 403, 72, 72, 352, 72, 72, 72, 72, 70, 70,
- 354, 70, 70, 70, 70, 70, 72, 72, 403, 72,
- 72, 72, 72, 72, 70, 403, 356, 70, 70, 403,
- 70, 403, 72, 355, 357, 72, 72, 360, 72, 358,
- 70, 361, 359, 403, 70, 70, 70, 70, 72, 70,
- 70, 362, 72, 72, 72, 72, 70, 72, 72, 70,
-
- 403, 70, 403, 70, 72, 70, 70, 72, 364, 72,
- 363, 72, 368, 72, 72, 70, 366, 403, 365, 70,
- 369, 70, 403, 72, 70, 367, 403, 72, 370, 72,
- 371, 70, 72, 70, 373, 70, 70, 403, 403, 72,
- 70, 72, 70, 72, 72, 372, 374, 70, 72, 70,
- 72, 403, 403, 70, 70, 72, 70, 72, 70, 376,
- 377, 72, 72, 70, 72, 70, 72, 70, 375, 403,
- 70, 72, 403, 72, 70, 72, 403, 380, 72, 70,
- 379, 70, 72, 70, 378, 403, 70, 72, 70, 72,
- 403, 72, 70, 381, 72, 403, 72, 403, 382, 70,
-
- 72, 70, 70, 383, 403, 385, 70, 72, 70, 72,
- 72, 386, 384, 70, 72, 70, 72, 70, 389, 70,
- 70, 72, 403, 72, 387, 72, 70, 72, 72, 70,
- 390, 70, 70, 70, 72, 70, 388, 72, 403, 72,
- 72, 72, 70, 72, 70, 70, 395, 403, 391, 70,
- 72, 403, 72, 72, 70, 393, 70, 72, 396, 392,
- 70, 70, 72, 70, 72, 70, 70, 394, 72, 72,
- 70, 72, 70, 72, 72, 400, 397, 403, 72, 401,
- 72, 403, 403, 403, 399, 403, 403, 403, 403, 403,
- 398, 403, 403, 403, 403, 403, 402, 53, 53, 53,
-
- 53, 53, 53, 53, 53, 53, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 60, 403, 60, 65, 65, 65,
- 71, 71, 403, 71, 125, 125, 125, 125, 403, 125,
- 125, 125, 125, 126, 126, 126, 126, 126, 126, 126,
- 126, 126, 129, 129, 129, 403, 129, 129, 129, 129,
- 129, 131, 403, 131, 131, 131, 131, 131, 131, 131,
- 135, 403, 403, 403, 403, 403, 135, 72, 72, 403,
- 72, 202, 403, 202, 9, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
-
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- 403
+ 38, 38, 38, 51, 52, 59, 59, 59, 59, 63,
+ 70, 64, 67, 68, 70, 70, 70, 63, 72, 64,
+ 70, 121, 72, 72, 72, 70, 122, 75, 72, 83,
+ 70, 76, 73, 72, 70, 129, 78, 74, 72, 306,
+ 79, 266, 72, 80, 306, 70, 81, 77, 91, 82,
+
+ 84, 104, 85, 72, 231, 70, 92, 70, 87, 70,
+ 181, 93, 86, 72, 127, 72, 126, 72, 88, 70,
+ 121, 89, 94, 124, 90, 122, 95, 72, 97, 70,
+ 98, 70, 96, 100, 59, 59, 99, 72, 70, 72,
+ 70, 101, 105, 102, 107, 103, 70, 108, 72, 70,
+ 70, 128, 106, 70, 72, 111, 109, 72, 72, 116,
+ 110, 72, 112, 306, 70, 130, 70, 70, 70, 113,
+ 70, 114, 72, 115, 72, 72, 72, 131, 72, 127,
+ 117, 70, 132, 133, 70, 70, 70, 118, 70, 72,
+ 134, 70, 72, 72, 72, 70, 72, 70, 140, 72,
+
+ 126, 124, 142, 72, 69, 72, 66, 135, 70, 137,
+ 138, 143, 141, 136, 147, 70, 72, 139, 144, 70,
+ 146, 70, 145, 72, 70, 70, 70, 72, 70, 72,
+ 62, 61, 72, 72, 72, 306, 72, 58, 152, 70,
+ 70, 70, 58, 148, 150, 149, 151, 72, 72, 72,
+ 70, 56, 157, 153, 154, 70, 56, 70, 72, 156,
+ 70, 155, 159, 72, 158, 72, 70, 70, 72, 54,
+ 70, 70, 54, 70, 72, 72, 70, 161, 72, 72,
+ 162, 72, 163, 160, 72, 70, 306, 70, 306, 70,
+ 306, 70, 70, 72, 164, 72, 166, 72, 169, 72,
+
+ 72, 165, 171, 70, 70, 167, 306, 170, 306, 70,
+ 70, 72, 72, 168, 172, 70, 173, 72, 72, 70,
+ 70, 70, 176, 72, 306, 174, 175, 72, 72, 72,
+ 70, 70, 178, 70, 70, 177, 179, 70, 72, 72,
+ 306, 72, 72, 70, 70, 72, 180, 70, 183, 70,
+ 184, 72, 72, 70, 306, 72, 306, 72, 189, 70,
+ 185, 72, 191, 306, 186, 188, 70, 72, 70, 70,
+ 187, 190, 306, 306, 72, 70, 72, 72, 306, 195,
+ 196, 70, 70, 72, 70, 192, 193, 306, 194, 72,
+ 72, 70, 72, 70, 197, 200, 70, 70, 198, 72,
+
+ 70, 72, 306, 70, 72, 72, 306, 202, 72, 70,
+ 199, 72, 306, 203, 201, 70, 204, 72, 70, 70,
+ 206, 70, 70, 72, 207, 70, 72, 72, 208, 72,
+ 72, 205, 70, 72, 211, 306, 212, 209, 70, 70,
+ 72, 70, 306, 210, 70, 213, 72, 72, 70, 72,
+ 216, 215, 72, 306, 214, 70, 72, 70, 70, 70,
+ 70, 219, 306, 72, 218, 72, 72, 72, 72, 70,
+ 217, 70, 306, 306, 70, 306, 70, 72, 306, 72,
+ 222, 224, 72, 220, 72, 226, 221, 70, 70, 70,
+ 70, 223, 70, 70, 70, 72, 72, 72, 72, 225,
+
+ 72, 72, 72, 306, 306, 70, 306, 306, 306, 229,
+ 306, 230, 232, 72, 228, 233, 227, 70, 234, 70,
+ 70, 306, 70, 70, 70, 72, 70, 72, 72, 237,
+ 72, 72, 72, 70, 72, 70, 236, 240, 70, 70,
+ 70, 72, 242, 72, 70, 235, 72, 72, 72, 241,
+ 238, 239, 72, 70, 244, 306, 70, 70, 70, 70,
+ 70, 72, 70, 243, 72, 72, 72, 72, 72, 245,
+ 72, 70, 70, 70, 70, 70, 306, 306, 306, 72,
+ 72, 72, 72, 72, 70, 246, 248, 70, 249, 70,
+ 247, 306, 72, 70, 70, 72, 70, 72, 70, 250,
+
+ 306, 72, 72, 70, 72, 70, 72, 251, 255, 253,
+ 306, 72, 306, 72, 256, 70, 70, 70, 257, 252,
+ 254, 306, 70, 72, 72, 72, 70, 70, 70, 259,
+ 72, 306, 306, 70, 72, 72, 72, 70, 306, 260,
+ 263, 72, 306, 258, 70, 72, 264, 306, 306, 70,
+ 265, 70, 72, 70, 70, 261, 262, 72, 70, 72,
+ 70, 72, 72, 70, 70, 70, 72, 268, 72, 306,
+ 70, 72, 72, 72, 70, 70, 70, 271, 72, 267,
+ 306, 306, 72, 72, 72, 70, 269, 272, 270, 275,
+ 70, 70, 306, 72, 70, 70, 273, 70, 72, 72,
+
+ 274, 70, 72, 72, 70, 72, 70, 276, 70, 72,
+ 306, 70, 72, 278, 72, 70, 72, 282, 280, 72,
+ 70, 70, 277, 72, 70, 306, 70, 70, 72, 72,
+ 279, 70, 72, 281, 72, 72, 306, 70, 70, 72,
+ 286, 70, 70, 283, 287, 72, 72, 284, 285, 72,
+ 72, 70, 70, 70, 70, 70, 306, 70, 70, 72,
+ 72, 72, 72, 72, 288, 72, 72, 70, 70, 306,
+ 70, 291, 70, 70, 70, 72, 72, 289, 72, 70,
+ 72, 72, 72, 290, 70, 70, 70, 72, 306, 70,
+ 306, 292, 72, 72, 72, 293, 295, 72, 296, 70,
+
+ 70, 70, 70, 294, 70, 70, 70, 72, 72, 72,
+ 72, 70, 72, 72, 72, 297, 70, 70, 70, 72,
+ 306, 70, 70, 299, 72, 72, 72, 70, 298, 72,
+ 72, 70, 70, 303, 306, 72, 301, 306, 70, 72,
+ 72, 70, 300, 70, 302, 304, 72, 70, 306, 72,
+ 306, 72, 306, 306, 306, 72, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 305, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 60,
+
+ 306, 60, 65, 65, 65, 71, 71, 306, 71, 119,
+ 119, 119, 119, 306, 119, 119, 119, 119, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 123, 123, 123,
+ 306, 123, 123, 123, 123, 123, 125, 306, 125, 125,
+ 125, 125, 125, 125, 125, 129, 306, 306, 306, 306,
+ 306, 129, 72, 72, 306, 72, 182, 306, 182, 9,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306
} ;
-static const flex_int16_t yy_chk[1342] =
+static const flex_int16_t yy_chk[1016] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 11, 11, 12, 12,
- 25, 32, 25, 28, 28, 33, 38, 35, 49, 32,
- 64, 34, 64, 33, 38, 35, 49, 49, 33, 34,
- 35, 36, 33, 32, 35, 33, 318, 34, 32, 36,
- 268, 34, 37, 201, 34, 37, 39, 34, 33, 37,
-
- 34, 36, 37, 36, 39, 37, 41, 40, 37, 42,
- 39, 43, 134, 36, 41, 40, 54, 42, 39, 43,
- 40, 54, 126, 39, 40, 43, 44, 126, 45, 41,
- 40, 46, 42, 43, 44, 43, 45, 43, 42, 46,
- 43, 45, 59, 59, 46, 47, 133, 46, 132, 48,
- 45, 45, 44, 47, 47, 71, 46, 48, 50, 130,
- 46, 47, 72, 71, 46, 70, 50, 73, 47, 74,
- 75, 48, 65, 48, 50, 73, 76, 74, 75, 73,
- 74, 50, 77, 127, 76, 75, 78, 80, 127, 82,
- 77, 76, 79, 63, 78, 80, 74, 82, 76, 81,
-
- 79, 79, 82, 83, 84, 77, 85, 81, 58, 86,
- 80, 83, 84, 56, 85, 84, 80, 86, 87, 30,
- 81, 81, 26, 24, 84, 23, 87, 88, 81, 83,
- 87, 84, 89, 85, 90, 88, 86, 91, 92, 94,
- 89, 95, 90, 93, 88, 91, 92, 94, 96, 95,
- 97, 93, 9, 95, 98, 8, 96, 90, 97, 99,
- 89, 92, 98, 91, 7, 93, 100, 99, 95, 95,
- 99, 101, 97, 98, 100, 102, 103, 104, 100, 101,
- 105, 107, 99, 102, 103, 104, 106, 6, 105, 107,
- 5, 4, 109, 105, 106, 102, 108, 111, 106, 101,
-
- 109, 109, 110, 112, 108, 111, 3, 116, 0, 107,
- 110, 112, 0, 108, 110, 116, 109, 111, 113, 108,
- 109, 114, 115, 112, 0, 117, 113, 113, 111, 114,
- 115, 112, 115, 117, 116, 117, 118, 119, 120, 121,
- 122, 114, 0, 115, 118, 119, 120, 121, 122, 118,
- 123, 121, 0, 124, 136, 120, 137, 0, 123, 0,
- 122, 124, 136, 123, 137, 120, 139, 123, 138, 140,
- 143, 0, 119, 0, 139, 0, 138, 140, 143, 124,
- 141, 138, 142, 139, 0, 0, 140, 144, 141, 141,
- 142, 145, 142, 142, 147, 144, 143, 0, 146, 145,
-
- 150, 148, 147, 149, 0, 147, 146, 152, 150, 148,
- 0, 149, 149, 151, 144, 152, 154, 153, 145, 146,
- 152, 151, 146, 148, 154, 153, 150, 150, 153, 155,
- 156, 157, 158, 151, 0, 0, 0, 155, 156, 157,
- 158, 159, 155, 158, 154, 160, 155, 161, 163, 159,
- 159, 0, 162, 160, 164, 161, 163, 165, 166, 157,
- 162, 163, 164, 162, 167, 165, 166, 164, 161, 0,
- 165, 168, 167, 166, 0, 169, 170, 167, 171, 168,
- 165, 0, 164, 169, 170, 172, 171, 173, 174, 170,
- 168, 0, 171, 172, 175, 173, 174, 0, 176, 169,
-
- 177, 174, 175, 0, 178, 172, 176, 179, 177, 173,
- 180, 177, 178, 181, 182, 179, 178, 183, 180, 0,
- 176, 181, 182, 184, 185, 183, 0, 179, 0, 186,
- 187, 184, 185, 188, 182, 189, 184, 186, 187, 180,
- 0, 188, 190, 189, 0, 191, 0, 0, 181, 192,
- 190, 193, 183, 191, 190, 186, 194, 192, 195, 193,
- 188, 193, 193, 0, 194, 191, 195, 0, 196, 0,
- 197, 192, 198, 193, 199, 195, 196, 196, 197, 203,
- 198, 194, 199, 200, 204, 205, 0, 203, 206, 207,
- 0, 200, 204, 205, 199, 209, 206, 207, 198, 197,
-
- 208, 211, 200, 209, 210, 203, 204, 205, 208, 211,
- 212, 0, 210, 213, 206, 214, 0, 210, 212, 208,
- 215, 213, 213, 214, 214, 216, 217, 212, 215, 211,
- 220, 0, 218, 216, 217, 219, 0, 221, 220, 217,
- 218, 223, 222, 219, 219, 221, 224, 0, 215, 223,
- 222, 0, 0, 216, 224, 218, 225, 226, 220, 222,
- 224, 227, 228, 229, 225, 226, 230, 231, 232, 227,
- 228, 229, 233, 226, 230, 231, 232, 234, 235, 0,
- 233, 0, 236, 0, 237, 234, 235, 233, 238, 227,
- 236, 229, 237, 231, 232, 239, 238, 240, 230, 241,
-
- 242, 243, 244, 239, 245, 240, 235, 241, 242, 243,
- 244, 246, 245, 247, 251, 248, 249, 245, 250, 246,
- 240, 247, 251, 248, 249, 252, 250, 243, 250, 253,
- 244, 254, 0, 252, 0, 0, 252, 253, 251, 254,
- 247, 248, 253, 249, 255, 0, 257, 256, 258, 260,
- 259, 0, 255, 255, 257, 256, 258, 260, 259, 254,
- 256, 261, 262, 263, 267, 258, 259, 264, 265, 261,
- 262, 263, 267, 0, 266, 264, 265, 262, 260, 0,
- 264, 265, 266, 0, 269, 270, 271, 266, 272, 273,
- 261, 263, 269, 270, 271, 274, 272, 273, 275, 276,
-
- 278, 279, 277, 274, 0, 0, 275, 276, 278, 279,
- 277, 275, 269, 277, 271, 281, 0, 280, 282, 0,
- 0, 272, 0, 281, 273, 280, 282, 276, 278, 0,
- 280, 283, 284, 285, 286, 287, 0, 281, 288, 283,
- 284, 285, 286, 287, 282, 284, 288, 0, 289, 0,
- 290, 291, 292, 293, 294, 285, 289, 283, 290, 291,
- 292, 293, 294, 295, 296, 289, 293, 297, 298, 299,
- 294, 295, 296, 0, 300, 297, 298, 299, 301, 291,
- 298, 297, 300, 303, 0, 302, 301, 304, 0, 0,
- 305, 303, 295, 302, 302, 304, 300, 299, 305, 306,
-
- 307, 0, 308, 311, 309, 310, 301, 306, 307, 303,
- 308, 311, 309, 310, 310, 304, 0, 0, 0, 312,
- 0, 313, 314, 315, 311, 306, 309, 312, 307, 313,
- 314, 315, 312, 316, 317, 314, 319, 320, 321, 322,
- 0, 316, 317, 313, 319, 320, 321, 322, 323, 324,
- 315, 325, 326, 327, 328, 329, 323, 324, 0, 325,
- 326, 327, 328, 329, 330, 0, 322, 331, 333, 0,
- 332, 0, 330, 321, 323, 331, 333, 330, 332, 325,
- 334, 332, 328, 0, 335, 336, 337, 338, 334, 339,
- 340, 333, 335, 336, 337, 338, 341, 339, 340, 342,
-
- 0, 343, 0, 344, 341, 345, 346, 342, 337, 343,
- 335, 344, 343, 345, 346, 347, 340, 0, 339, 349,
- 344, 348, 0, 347, 350, 342, 0, 349, 347, 348,
- 348, 351, 350, 352, 350, 353, 354, 0, 0, 351,
- 355, 352, 356, 353, 354, 349, 352, 357, 355, 358,
- 356, 0, 0, 359, 360, 357, 361, 358, 362, 356,
- 357, 359, 360, 363, 361, 364, 362, 365, 355, 0,
- 366, 363, 0, 364, 367, 365, 0, 364, 366, 368,
- 362, 369, 367, 370, 361, 0, 371, 368, 372, 369,
- 0, 370, 373, 365, 371, 0, 372, 0, 368, 374,
-
- 373, 375, 376, 369, 0, 373, 377, 374, 378, 375,
- 376, 374, 371, 379, 377, 380, 378, 381, 377, 382,
- 383, 379, 0, 380, 375, 381, 384, 382, 383, 385,
- 381, 386, 387, 388, 384, 389, 376, 385, 0, 386,
- 387, 388, 390, 389, 391, 392, 388, 0, 383, 393,
- 390, 0, 391, 392, 394, 385, 395, 393, 391, 384,
- 396, 397, 394, 398, 395, 399, 400, 387, 396, 397,
- 401, 398, 402, 399, 400, 399, 394, 0, 401, 400,
- 402, 0, 0, 0, 398, 0, 0, 0, 0, 0,
- 397, 0, 0, 0, 0, 0, 401, 404, 404, 404,
-
- 404, 404, 404, 404, 404, 404, 405, 405, 405, 405,
- 405, 405, 405, 405, 405, 406, 406, 406, 406, 406,
- 406, 406, 406, 406, 407, 0, 407, 408, 408, 408,
- 409, 409, 0, 409, 410, 410, 410, 410, 0, 410,
- 410, 410, 410, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 412, 412, 412, 0, 412, 412, 412, 412,
- 412, 413, 0, 413, 413, 413, 413, 413, 413, 413,
- 414, 0, 0, 0, 0, 0, 414, 415, 415, 0,
- 415, 416, 0, 416, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
-
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- 403
+ 1, 1, 1, 1, 1, 11, 11, 12, 12, 25,
+ 32, 25, 28, 28, 33, 38, 35, 64, 32, 64,
+ 34, 54, 33, 38, 35, 44, 54, 33, 34, 35,
+ 36, 33, 32, 44, 39, 266, 34, 32, 36, 120,
+ 34, 231, 39, 34, 120, 37, 34, 33, 39, 34,
+
+ 36, 44, 36, 37, 181, 41, 39, 42, 37, 40,
+ 128, 39, 36, 41, 127, 42, 126, 40, 37, 43,
+ 121, 37, 40, 124, 37, 121, 40, 43, 41, 45,
+ 42, 46, 40, 43, 59, 59, 42, 45, 72, 46,
+ 71, 43, 45, 43, 46, 43, 47, 46, 71, 48,
+ 49, 70, 45, 73, 47, 47, 46, 48, 49, 49,
+ 46, 73, 47, 65, 50, 73, 74, 75, 76, 47,
+ 77, 48, 50, 48, 74, 75, 76, 74, 77, 63,
+ 50, 78, 75, 76, 79, 81, 82, 50, 80, 78,
+ 78, 83, 79, 81, 82, 84, 80, 86, 81, 83,
+
+ 58, 56, 83, 84, 30, 86, 26, 79, 85, 80,
+ 80, 83, 82, 79, 86, 87, 85, 80, 83, 88,
+ 85, 89, 84, 87, 90, 91, 92, 88, 93, 89,
+ 24, 23, 90, 91, 92, 9, 93, 8, 92, 94,
+ 95, 96, 7, 87, 89, 88, 90, 94, 95, 96,
+ 97, 6, 96, 92, 92, 98, 5, 99, 97, 95,
+ 100, 94, 97, 98, 96, 99, 101, 102, 100, 4,
+ 103, 104, 3, 105, 101, 102, 106, 99, 103, 104,
+ 102, 105, 103, 98, 106, 107, 0, 109, 0, 108,
+ 0, 113, 110, 107, 104, 109, 106, 108, 108, 113,
+
+ 110, 105, 110, 112, 111, 107, 0, 109, 0, 114,
+ 115, 112, 111, 107, 111, 116, 112, 114, 115, 117,
+ 118, 130, 115, 116, 0, 113, 114, 117, 118, 130,
+ 131, 132, 117, 133, 134, 116, 117, 135, 131, 132,
+ 0, 133, 134, 136, 137, 135, 118, 138, 132, 139,
+ 133, 136, 137, 140, 0, 138, 0, 139, 138, 141,
+ 134, 140, 140, 0, 135, 137, 143, 141, 142, 144,
+ 136, 139, 0, 0, 143, 146, 142, 144, 0, 143,
+ 144, 145, 147, 146, 148, 141, 141, 0, 142, 145,
+ 147, 149, 148, 150, 145, 148, 151, 154, 145, 149,
+
+ 152, 150, 0, 153, 151, 154, 0, 151, 152, 155,
+ 147, 153, 0, 152, 150, 156, 153, 155, 157, 158,
+ 154, 159, 160, 156, 155, 161, 157, 158, 156, 159,
+ 160, 153, 162, 161, 159, 0, 160, 157, 163, 164,
+ 162, 165, 0, 158, 166, 161, 163, 164, 167, 165,
+ 164, 163, 166, 0, 162, 168, 167, 169, 170, 171,
+ 172, 167, 0, 168, 166, 169, 170, 171, 172, 173,
+ 165, 174, 0, 0, 175, 0, 176, 173, 0, 174,
+ 172, 174, 175, 169, 176, 176, 171, 177, 178, 179,
+ 183, 173, 180, 184, 185, 177, 178, 179, 183, 175,
+
+ 180, 184, 185, 0, 0, 186, 0, 0, 0, 179,
+ 0, 180, 183, 186, 178, 184, 177, 187, 186, 188,
+ 189, 0, 190, 191, 192, 187, 193, 188, 189, 189,
+ 190, 191, 192, 194, 193, 195, 188, 192, 196, 197,
+ 198, 194, 194, 195, 199, 187, 196, 197, 198, 193,
+ 190, 191, 199, 200, 198, 0, 201, 202, 203, 206,
+ 204, 200, 205, 195, 201, 202, 203, 206, 204, 200,
+ 205, 207, 208, 209, 210, 211, 0, 0, 0, 207,
+ 208, 209, 210, 211, 212, 202, 204, 213, 205, 214,
+ 203, 0, 212, 215, 217, 213, 216, 214, 218, 207,
+
+ 0, 215, 217, 219, 216, 220, 218, 212, 218, 216,
+ 0, 219, 0, 220, 219, 221, 222, 223, 220, 215,
+ 217, 0, 224, 221, 222, 223, 225, 227, 226, 222,
+ 224, 0, 0, 228, 225, 227, 226, 229, 0, 224,
+ 227, 228, 0, 221, 230, 229, 228, 0, 0, 232,
+ 229, 233, 230, 234, 235, 225, 226, 232, 236, 233,
+ 237, 234, 235, 238, 239, 240, 236, 235, 237, 0,
+ 241, 238, 239, 240, 242, 244, 243, 239, 241, 233,
+ 0, 0, 242, 244, 243, 245, 236, 240, 237, 243,
+ 246, 247, 0, 245, 248, 249, 241, 250, 246, 247,
+
+ 242, 251, 248, 249, 252, 250, 253, 246, 255, 251,
+ 0, 254, 252, 250, 253, 256, 255, 255, 253, 254,
+ 257, 258, 248, 256, 259, 0, 260, 261, 257, 258,
+ 251, 262, 259, 254, 260, 261, 0, 263, 264, 262,
+ 261, 265, 267, 256, 262, 263, 264, 258, 260, 265,
+ 267, 268, 269, 270, 271, 272, 0, 273, 274, 268,
+ 269, 270, 271, 272, 263, 273, 274, 275, 276, 0,
+ 277, 274, 278, 279, 280, 275, 276, 268, 277, 281,
+ 278, 279, 280, 272, 283, 282, 284, 281, 0, 285,
+ 0, 276, 283, 282, 284, 279, 282, 285, 285, 286,
+
+ 287, 288, 289, 280, 290, 291, 292, 286, 287, 288,
+ 289, 293, 290, 291, 292, 289, 294, 295, 296, 293,
+ 0, 297, 298, 293, 294, 295, 296, 299, 292, 297,
+ 298, 301, 300, 297, 0, 299, 295, 0, 302, 301,
+ 300, 303, 294, 304, 296, 300, 302, 305, 0, 303,
+ 0, 304, 0, 0, 0, 305, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 302, 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 308, 308, 308, 308, 308, 308, 308, 308, 308,
+ 309, 309, 309, 309, 309, 309, 309, 309, 309, 310,
+
+ 0, 310, 311, 311, 311, 312, 312, 0, 312, 313,
+ 313, 313, 313, 0, 313, 313, 313, 313, 314, 314,
+ 314, 314, 314, 314, 314, 314, 314, 315, 315, 315,
+ 0, 315, 315, 315, 315, 315, 316, 0, 316, 316,
+ 316, 316, 316, 316, 316, 317, 0, 0, 0, 0,
+ 0, 317, 318, 318, 0, 318, 319, 0, 319, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+
+ 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+ 306, 306, 306, 306, 306
} ;
static yy_state_type yy_last_accepting_state;
@@ -961,9 +856,9 @@ string_append(
stringbuf_len += len;
}
-#line 964 "lexyy.cc"
+#line 859 "lexyy.cc"
-#line 966 "lexyy.cc"
+#line 861 "lexyy.cc"
#define INITIAL 0
#define comment 1
@@ -1184,7 +1079,7 @@ YY_DECL
#line 112 "pars0lex.l"
-#line 1187 "lexyy.cc"
+#line 1082 "lexyy.cc"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -1211,13 +1106,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 404 )
+ if ( yy_current_state >= 307 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
- while ( yy_current_state != 403 );
+ while ( yy_current_state != 306 );
yy_cp = (yy_last_accepting_cpos);
yy_current_state = (yy_last_accepting_state);
@@ -1436,554 +1331,407 @@ case 18:
YY_RULE_SETUP
#line 252 "pars0lex.l"
{
- return(PARS_OUT_TOKEN);
+ return(PARS_INT_TOKEN);
}
YY_BREAK
case 19:
YY_RULE_SETUP
#line 256 "pars0lex.l"
{
- return(PARS_BINARY_TOKEN);
+ return(PARS_CHAR_TOKEN);
}
YY_BREAK
case 20:
YY_RULE_SETUP
#line 260 "pars0lex.l"
{
- return(PARS_BLOB_TOKEN);
+ return(PARS_IS_TOKEN);
}
YY_BREAK
case 21:
YY_RULE_SETUP
#line 264 "pars0lex.l"
{
- return(PARS_INT_TOKEN);
+ return(PARS_BEGIN_TOKEN);
}
YY_BREAK
case 22:
YY_RULE_SETUP
#line 268 "pars0lex.l"
{
- return(PARS_INT_TOKEN);
+ return(PARS_END_TOKEN);
}
YY_BREAK
case 23:
YY_RULE_SETUP
#line 272 "pars0lex.l"
{
- return(PARS_FLOAT_TOKEN);
+ return(PARS_IF_TOKEN);
}
YY_BREAK
case 24:
YY_RULE_SETUP
#line 276 "pars0lex.l"
{
- return(PARS_CHAR_TOKEN);
+ return(PARS_THEN_TOKEN);
}
YY_BREAK
case 25:
YY_RULE_SETUP
#line 280 "pars0lex.l"
{
- return(PARS_IS_TOKEN);
+ return(PARS_ELSE_TOKEN);
}
YY_BREAK
case 26:
YY_RULE_SETUP
#line 284 "pars0lex.l"
{
- return(PARS_BEGIN_TOKEN);
+ return(PARS_ELSIF_TOKEN);
}
YY_BREAK
case 27:
YY_RULE_SETUP
#line 288 "pars0lex.l"
{
- return(PARS_END_TOKEN);
+ return(PARS_LOOP_TOKEN);
}
YY_BREAK
case 28:
YY_RULE_SETUP
#line 292 "pars0lex.l"
{
- return(PARS_IF_TOKEN);
+ return(PARS_WHILE_TOKEN);
}
YY_BREAK
case 29:
YY_RULE_SETUP
#line 296 "pars0lex.l"
{
- return(PARS_THEN_TOKEN);
+ return(PARS_RETURN_TOKEN);
}
YY_BREAK
case 30:
YY_RULE_SETUP
#line 300 "pars0lex.l"
{
- return(PARS_ELSE_TOKEN);
+ return(PARS_SELECT_TOKEN);
}
YY_BREAK
case 31:
YY_RULE_SETUP
#line 304 "pars0lex.l"
{
- return(PARS_ELSIF_TOKEN);
+ return(PARS_COUNT_TOKEN);
}
YY_BREAK
case 32:
YY_RULE_SETUP
#line 308 "pars0lex.l"
{
- return(PARS_LOOP_TOKEN);
+ return(PARS_FROM_TOKEN);
}
YY_BREAK
case 33:
YY_RULE_SETUP
#line 312 "pars0lex.l"
{
- return(PARS_WHILE_TOKEN);
+ return(PARS_WHERE_TOKEN);
}
YY_BREAK
case 34:
YY_RULE_SETUP
#line 316 "pars0lex.l"
{
- return(PARS_RETURN_TOKEN);
+ return(PARS_FOR_TOKEN);
}
YY_BREAK
case 35:
YY_RULE_SETUP
#line 320 "pars0lex.l"
{
- return(PARS_SELECT_TOKEN);
+ return(PARS_ORDER_TOKEN);
}
YY_BREAK
case 36:
YY_RULE_SETUP
#line 324 "pars0lex.l"
{
- return(PARS_SUM_TOKEN);
+ return(PARS_BY_TOKEN);
}
YY_BREAK
case 37:
YY_RULE_SETUP
#line 328 "pars0lex.l"
{
- return(PARS_COUNT_TOKEN);
+ return(PARS_ASC_TOKEN);
}
YY_BREAK
case 38:
YY_RULE_SETUP
#line 332 "pars0lex.l"
{
- return(PARS_DISTINCT_TOKEN);
+ return(PARS_DESC_TOKEN);
}
YY_BREAK
case 39:
YY_RULE_SETUP
#line 336 "pars0lex.l"
{
- return(PARS_FROM_TOKEN);
+ return(PARS_INSERT_TOKEN);
}
YY_BREAK
case 40:
YY_RULE_SETUP
#line 340 "pars0lex.l"
{
- return(PARS_WHERE_TOKEN);
+ return(PARS_INTO_TOKEN);
}
YY_BREAK
case 41:
YY_RULE_SETUP
#line 344 "pars0lex.l"
{
- return(PARS_FOR_TOKEN);
+ return(PARS_VALUES_TOKEN);
}
YY_BREAK
case 42:
YY_RULE_SETUP
#line 348 "pars0lex.l"
{
- return(PARS_READ_TOKEN);
+ return(PARS_UPDATE_TOKEN);
}
YY_BREAK
case 43:
YY_RULE_SETUP
#line 352 "pars0lex.l"
{
- return(PARS_ORDER_TOKEN);
+ return(PARS_SET_TOKEN);
}
YY_BREAK
case 44:
YY_RULE_SETUP
#line 356 "pars0lex.l"
{
- return(PARS_BY_TOKEN);
+ return(PARS_DELETE_TOKEN);
}
YY_BREAK
case 45:
YY_RULE_SETUP
#line 360 "pars0lex.l"
{
- return(PARS_ASC_TOKEN);
+ return(PARS_CURRENT_TOKEN);
}
YY_BREAK
case 46:
YY_RULE_SETUP
#line 364 "pars0lex.l"
{
- return(PARS_DESC_TOKEN);
+ return(PARS_OF_TOKEN);
}
YY_BREAK
case 47:
YY_RULE_SETUP
#line 368 "pars0lex.l"
{
- return(PARS_INSERT_TOKEN);
+ return(PARS_CREATE_TOKEN);
}
YY_BREAK
case 48:
YY_RULE_SETUP
#line 372 "pars0lex.l"
{
- return(PARS_INTO_TOKEN);
+ return(PARS_TABLE_TOKEN);
}
YY_BREAK
case 49:
YY_RULE_SETUP
#line 376 "pars0lex.l"
{
- return(PARS_VALUES_TOKEN);
+ return(PARS_INDEX_TOKEN);
}
YY_BREAK
case 50:
YY_RULE_SETUP
#line 380 "pars0lex.l"
{
- return(PARS_UPDATE_TOKEN);
+ return(PARS_UNIQUE_TOKEN);
}
YY_BREAK
case 51:
YY_RULE_SETUP
#line 384 "pars0lex.l"
{
- return(PARS_SET_TOKEN);
+ return(PARS_CLUSTERED_TOKEN);
}
YY_BREAK
case 52:
YY_RULE_SETUP
#line 388 "pars0lex.l"
{
- return(PARS_DELETE_TOKEN);
+ return(PARS_ON_TOKEN);
}
YY_BREAK
case 53:
YY_RULE_SETUP
#line 392 "pars0lex.l"
{
- return(PARS_CURRENT_TOKEN);
+ return(PARS_DECLARE_TOKEN);
}
YY_BREAK
case 54:
YY_RULE_SETUP
#line 396 "pars0lex.l"
{
- return(PARS_OF_TOKEN);
+ return(PARS_CURSOR_TOKEN);
}
YY_BREAK
case 55:
YY_RULE_SETUP
#line 400 "pars0lex.l"
{
- return(PARS_CREATE_TOKEN);
+ return(PARS_OPEN_TOKEN);
}
YY_BREAK
case 56:
YY_RULE_SETUP
#line 404 "pars0lex.l"
{
- return(PARS_TABLE_TOKEN);
+ return(PARS_FETCH_TOKEN);
}
YY_BREAK
case 57:
YY_RULE_SETUP
#line 408 "pars0lex.l"
{
- return(PARS_COMPACT_TOKEN);
+ return(PARS_CLOSE_TOKEN);
}
YY_BREAK
case 58:
YY_RULE_SETUP
#line 412 "pars0lex.l"
{
- return(PARS_BLOCK_SIZE_TOKEN);
+ return(PARS_NOTFOUND_TOKEN);
}
YY_BREAK
case 59:
YY_RULE_SETUP
#line 416 "pars0lex.l"
{
- return(PARS_INDEX_TOKEN);
+ return(PARS_TO_BINARY_TOKEN);
}
YY_BREAK
case 60:
YY_RULE_SETUP
#line 420 "pars0lex.l"
{
- return(PARS_UNIQUE_TOKEN);
+ return(PARS_SUBSTR_TOKEN);
}
YY_BREAK
case 61:
YY_RULE_SETUP
#line 424 "pars0lex.l"
{
- return(PARS_CLUSTERED_TOKEN);
+ return(PARS_CONCAT_TOKEN);
}
YY_BREAK
case 62:
YY_RULE_SETUP
#line 428 "pars0lex.l"
{
- return(PARS_ON_TOKEN);
+ return(PARS_INSTR_TOKEN);
}
YY_BREAK
case 63:
YY_RULE_SETUP
#line 432 "pars0lex.l"
{
- return(PARS_DECLARE_TOKEN);
+ return(PARS_LENGTH_TOKEN);
}
YY_BREAK
case 64:
YY_RULE_SETUP
#line 436 "pars0lex.l"
{
- return(PARS_CURSOR_TOKEN);
+ return(PARS_COMMIT_TOKEN);
}
YY_BREAK
case 65:
YY_RULE_SETUP
#line 440 "pars0lex.l"
{
- return(PARS_OPEN_TOKEN);
+ return(PARS_ROLLBACK_TOKEN);
}
YY_BREAK
case 66:
YY_RULE_SETUP
#line 444 "pars0lex.l"
{
- return(PARS_FETCH_TOKEN);
+ return(PARS_WORK_TOKEN);
}
YY_BREAK
case 67:
YY_RULE_SETUP
#line 448 "pars0lex.l"
{
- return(PARS_CLOSE_TOKEN);
+ return(PARS_EXIT_TOKEN);
}
YY_BREAK
case 68:
YY_RULE_SETUP
#line 452 "pars0lex.l"
{
- return(PARS_NOTFOUND_TOKEN);
+ return(PARS_FUNCTION_TOKEN);
}
YY_BREAK
case 69:
YY_RULE_SETUP
#line 456 "pars0lex.l"
{
- return(PARS_TO_CHAR_TOKEN);
+ return(PARS_LOCK_TOKEN);
}
YY_BREAK
case 70:
YY_RULE_SETUP
#line 460 "pars0lex.l"
{
- return(PARS_TO_NUMBER_TOKEN);
+ return(PARS_SHARE_TOKEN);
}
YY_BREAK
case 71:
YY_RULE_SETUP
#line 464 "pars0lex.l"
{
- return(PARS_TO_BINARY_TOKEN);
+ return(PARS_MODE_TOKEN);
}
YY_BREAK
case 72:
YY_RULE_SETUP
#line 468 "pars0lex.l"
{
- return(PARS_BINARY_TO_NUMBER_TOKEN);
+ return(PARS_LIKE_TOKEN);
}
YY_BREAK
case 73:
YY_RULE_SETUP
#line 472 "pars0lex.l"
{
- return(PARS_SUBSTR_TOKEN);
+ return(PARS_BIGINT_TOKEN);
}
YY_BREAK
case 74:
YY_RULE_SETUP
#line 476 "pars0lex.l"
{
- return(PARS_REPLSTR_TOKEN);
-}
- YY_BREAK
-case 75:
-YY_RULE_SETUP
-#line 480 "pars0lex.l"
-{
- return(PARS_CONCAT_TOKEN);
-}
- YY_BREAK
-case 76:
-YY_RULE_SETUP
-#line 484 "pars0lex.l"
-{
- return(PARS_INSTR_TOKEN);
-}
- YY_BREAK
-case 77:
-YY_RULE_SETUP
-#line 488 "pars0lex.l"
-{
- return(PARS_LENGTH_TOKEN);
-}
- YY_BREAK
-case 78:
-YY_RULE_SETUP
-#line 492 "pars0lex.l"
-{
- return(PARS_SYSDATE_TOKEN);
-}
- YY_BREAK
-case 79:
-YY_RULE_SETUP
-#line 496 "pars0lex.l"
-{
- return(PARS_PRINTF_TOKEN);
-}
- YY_BREAK
-case 80:
-YY_RULE_SETUP
-#line 500 "pars0lex.l"
-{
- return(PARS_ASSERT_TOKEN);
-}
- YY_BREAK
-case 81:
-YY_RULE_SETUP
-#line 504 "pars0lex.l"
-{
- return(PARS_RND_TOKEN);
-}
- YY_BREAK
-case 82:
-YY_RULE_SETUP
-#line 508 "pars0lex.l"
-{
- return(PARS_RND_STR_TOKEN);
-}
- YY_BREAK
-case 83:
-YY_RULE_SETUP
-#line 512 "pars0lex.l"
-{
- return(PARS_ROW_PRINTF_TOKEN);
-}
- YY_BREAK
-case 84:
-YY_RULE_SETUP
-#line 516 "pars0lex.l"
-{
- return(PARS_COMMIT_TOKEN);
-}
- YY_BREAK
-case 85:
-YY_RULE_SETUP
-#line 520 "pars0lex.l"
-{
- return(PARS_ROLLBACK_TOKEN);
-}
- YY_BREAK
-case 86:
-YY_RULE_SETUP
-#line 524 "pars0lex.l"
-{
- return(PARS_WORK_TOKEN);
-}
- YY_BREAK
-case 87:
-YY_RULE_SETUP
-#line 528 "pars0lex.l"
-{
- return(PARS_UNSIGNED_TOKEN);
-}
- YY_BREAK
-case 88:
-YY_RULE_SETUP
-#line 532 "pars0lex.l"
-{
- return(PARS_EXIT_TOKEN);
-}
- YY_BREAK
-case 89:
-YY_RULE_SETUP
-#line 536 "pars0lex.l"
-{
- return(PARS_FUNCTION_TOKEN);
-}
- YY_BREAK
-case 90:
-YY_RULE_SETUP
-#line 540 "pars0lex.l"
-{
- return(PARS_LOCK_TOKEN);
-}
- YY_BREAK
-case 91:
-YY_RULE_SETUP
-#line 544 "pars0lex.l"
-{
- return(PARS_SHARE_TOKEN);
-}
- YY_BREAK
-case 92:
-YY_RULE_SETUP
-#line 548 "pars0lex.l"
-{
- return(PARS_MODE_TOKEN);
-}
- YY_BREAK
-case 93:
-YY_RULE_SETUP
-#line 552 "pars0lex.l"
-{
- return(PARS_LIKE_TOKEN);
-}
- YY_BREAK
-case 94:
-YY_RULE_SETUP
-#line 556 "pars0lex.l"
-{
- return(PARS_BIGINT_TOKEN);
-}
- YY_BREAK
-case 95:
-YY_RULE_SETUP
-#line 560 "pars0lex.l"
-{
yylval = sym_tab_add_id(pars_sym_tab_global,
(byte*) yytext,
ut_strlen(yytext));
return(PARS_ID_TOKEN);
}
YY_BREAK
-case 96:
+case 75:
YY_RULE_SETUP
-#line 567 "pars0lex.l"
+#line 483 "pars0lex.l"
{
yylval = sym_tab_add_id(pars_sym_tab_global,
(byte*) yytext,
@@ -1991,192 +1739,192 @@ YY_RULE_SETUP
return(PARS_TABLE_NAME_TOKEN);
}
YY_BREAK
-case 97:
+case 76:
YY_RULE_SETUP
-#line 574 "pars0lex.l"
+#line 490 "pars0lex.l"
{
return(PARS_DDOT_TOKEN);
}
YY_BREAK
-case 98:
+case 77:
YY_RULE_SETUP
-#line 578 "pars0lex.l"
+#line 494 "pars0lex.l"
{
return(PARS_ASSIGN_TOKEN);
}
YY_BREAK
-case 99:
+case 78:
YY_RULE_SETUP
-#line 582 "pars0lex.l"
+#line 498 "pars0lex.l"
{
return(PARS_LE_TOKEN);
}
YY_BREAK
-case 100:
+case 79:
YY_RULE_SETUP
-#line 586 "pars0lex.l"
+#line 502 "pars0lex.l"
{
return(PARS_GE_TOKEN);
}
YY_BREAK
-case 101:
+case 80:
YY_RULE_SETUP
-#line 590 "pars0lex.l"
+#line 506 "pars0lex.l"
{
return(PARS_NE_TOKEN);
}
YY_BREAK
-case 102:
+case 81:
YY_RULE_SETUP
-#line 594 "pars0lex.l"
+#line 510 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 103:
+case 82:
YY_RULE_SETUP
-#line 599 "pars0lex.l"
+#line 515 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 104:
+case 83:
YY_RULE_SETUP
-#line 604 "pars0lex.l"
+#line 520 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 105:
+case 84:
YY_RULE_SETUP
-#line 609 "pars0lex.l"
+#line 525 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 106:
+case 85:
YY_RULE_SETUP
-#line 614 "pars0lex.l"
+#line 530 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 107:
+case 86:
YY_RULE_SETUP
-#line 619 "pars0lex.l"
+#line 535 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 108:
+case 87:
YY_RULE_SETUP
-#line 624 "pars0lex.l"
+#line 540 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 109:
+case 88:
YY_RULE_SETUP
-#line 629 "pars0lex.l"
+#line 545 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 110:
+case 89:
YY_RULE_SETUP
-#line 634 "pars0lex.l"
+#line 550 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 111:
+case 90:
YY_RULE_SETUP
-#line 639 "pars0lex.l"
+#line 555 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 112:
+case 91:
YY_RULE_SETUP
-#line 644 "pars0lex.l"
+#line 560 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 113:
+case 92:
YY_RULE_SETUP
-#line 649 "pars0lex.l"
+#line 565 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 114:
+case 93:
YY_RULE_SETUP
-#line 654 "pars0lex.l"
+#line 570 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 115:
+case 94:
YY_RULE_SETUP
-#line 659 "pars0lex.l"
+#line 575 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 116:
+case 95:
YY_RULE_SETUP
-#line 664 "pars0lex.l"
+#line 580 "pars0lex.l"
{
return((int)(*yytext));
}
YY_BREAK
-case 117:
+case 96:
YY_RULE_SETUP
-#line 669 "pars0lex.l"
+#line 585 "pars0lex.l"
BEGIN(comment); /* eat up comment */
YY_BREAK
-case 118:
-/* rule 118 can match eol */
+case 97:
+/* rule 97 can match eol */
YY_RULE_SETUP
-#line 671 "pars0lex.l"
+#line 587 "pars0lex.l"
YY_BREAK
-case 119:
-/* rule 119 can match eol */
+case 98:
+/* rule 98 can match eol */
YY_RULE_SETUP
-#line 672 "pars0lex.l"
+#line 588 "pars0lex.l"
YY_BREAK
-case 120:
+case 99:
YY_RULE_SETUP
-#line 673 "pars0lex.l"
+#line 589 "pars0lex.l"
BEGIN(INITIAL);
YY_BREAK
-case 121:
-/* rule 121 can match eol */
+case 100:
+/* rule 100 can match eol */
YY_RULE_SETUP
-#line 675 "pars0lex.l"
+#line 591 "pars0lex.l"
/* eat up whitespace */
YY_BREAK
-case 122:
+case 101:
YY_RULE_SETUP
-#line 678 "pars0lex.l"
+#line 594 "pars0lex.l"
{
fprintf(stderr,"Unrecognized character: %02x\n",
*yytext);
@@ -2186,12 +1934,12 @@ YY_RULE_SETUP
return(0);
}
YY_BREAK
-case 123:
+case 102:
YY_RULE_SETUP
-#line 687 "pars0lex.l"
+#line 603 "pars0lex.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 2194 "lexyy.cc"
+#line 1942 "lexyy.cc"
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(comment):
case YY_STATE_EOF(quoted):
@@ -2492,7 +2240,7 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 404 )
+ if ( yy_current_state >= 307 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -2520,11 +2268,11 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 404 )
+ if ( yy_current_state >= 307 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
- yy_is_jam = (yy_current_state == 403);
+ yy_is_jam = (yy_current_state == 306);
return yy_is_jam ? 0 : yy_current_state;
}
@@ -3077,7 +2825,7 @@ static void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
-#line 687 "pars0lex.l"
+#line 603 "pars0lex.l"
/**********************************************************************
diff --git a/storage/innobase/pars/pars0grm.cc b/storage/innobase/pars/pars0grm.cc
index a0a09771106..7e10a783310 100644
--- a/storage/innobase/pars/pars0grm.cc
+++ b/storage/innobase/pars/pars0grm.cc
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
/* Identify Bison output. */
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -61,8 +65,8 @@
-/* Copy the first part of user declarations. */
-#line 29 "pars0grm.y" /* yacc.c:339 */
+/* First part of user prologue. */
+#line 29 "pars0grm.y"
/* The value of the semantic attribute is a pointer to a query tree node
que_node_t */
@@ -81,13 +85,17 @@ que_node_t */
int
yylex(void);
-#line 85 "pars0grm.cc" /* yacc.c:339 */
+#line 89 "pars0grm.cc"
# ifndef YY_NULLPTR
-# if defined __cplusplus && 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
# else
-# define YY_NULLPTR 0
+# define YY_NULLPTR ((void*)0)
# endif
# endif
@@ -99,8 +107,8 @@ yylex(void);
# define YYERROR_VERBOSE 0
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "pars0grm.tab.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_YY_PARS0GRM_TAB_H_INCLUDED
# define YY_YY_PARS0GRM_TAB_H_INCLUDED
/* Debug traces. */
@@ -129,91 +137,71 @@ extern int yydebug;
PARS_NE_TOKEN = 268,
PARS_PROCEDURE_TOKEN = 269,
PARS_IN_TOKEN = 270,
- PARS_OUT_TOKEN = 271,
- PARS_BINARY_TOKEN = 272,
- PARS_BLOB_TOKEN = 273,
- PARS_INT_TOKEN = 274,
- PARS_FLOAT_TOKEN = 275,
- PARS_CHAR_TOKEN = 276,
- PARS_IS_TOKEN = 277,
- PARS_BEGIN_TOKEN = 278,
- PARS_END_TOKEN = 279,
- PARS_IF_TOKEN = 280,
- PARS_THEN_TOKEN = 281,
- PARS_ELSE_TOKEN = 282,
- PARS_ELSIF_TOKEN = 283,
- PARS_LOOP_TOKEN = 284,
- PARS_WHILE_TOKEN = 285,
- PARS_RETURN_TOKEN = 286,
- PARS_SELECT_TOKEN = 287,
- PARS_SUM_TOKEN = 288,
- PARS_COUNT_TOKEN = 289,
- PARS_DISTINCT_TOKEN = 290,
- PARS_FROM_TOKEN = 291,
- PARS_WHERE_TOKEN = 292,
- PARS_FOR_TOKEN = 293,
- PARS_DDOT_TOKEN = 294,
- PARS_READ_TOKEN = 295,
- PARS_ORDER_TOKEN = 296,
- PARS_BY_TOKEN = 297,
- PARS_ASC_TOKEN = 298,
- PARS_DESC_TOKEN = 299,
- PARS_INSERT_TOKEN = 300,
- PARS_INTO_TOKEN = 301,
- PARS_VALUES_TOKEN = 302,
- PARS_UPDATE_TOKEN = 303,
- PARS_SET_TOKEN = 304,
- PARS_DELETE_TOKEN = 305,
- PARS_CURRENT_TOKEN = 306,
- PARS_OF_TOKEN = 307,
- PARS_CREATE_TOKEN = 308,
- PARS_TABLE_TOKEN = 309,
- PARS_INDEX_TOKEN = 310,
- PARS_UNIQUE_TOKEN = 311,
- PARS_CLUSTERED_TOKEN = 312,
- PARS_ON_TOKEN = 313,
- PARS_ASSIGN_TOKEN = 314,
- PARS_DECLARE_TOKEN = 315,
- PARS_CURSOR_TOKEN = 316,
- PARS_SQL_TOKEN = 317,
- PARS_OPEN_TOKEN = 318,
- PARS_FETCH_TOKEN = 319,
- PARS_CLOSE_TOKEN = 320,
- PARS_NOTFOUND_TOKEN = 321,
- PARS_TO_CHAR_TOKEN = 322,
- PARS_TO_NUMBER_TOKEN = 323,
- PARS_TO_BINARY_TOKEN = 324,
- PARS_BINARY_TO_NUMBER_TOKEN = 325,
- PARS_SUBSTR_TOKEN = 326,
- PARS_REPLSTR_TOKEN = 327,
- PARS_CONCAT_TOKEN = 328,
- PARS_INSTR_TOKEN = 329,
- PARS_LENGTH_TOKEN = 330,
- PARS_SYSDATE_TOKEN = 331,
- PARS_PRINTF_TOKEN = 332,
- PARS_ASSERT_TOKEN = 333,
- PARS_RND_TOKEN = 334,
- PARS_RND_STR_TOKEN = 335,
- PARS_ROW_PRINTF_TOKEN = 336,
- PARS_COMMIT_TOKEN = 337,
- PARS_ROLLBACK_TOKEN = 338,
- PARS_WORK_TOKEN = 339,
- PARS_UNSIGNED_TOKEN = 340,
- PARS_EXIT_TOKEN = 341,
- PARS_FUNCTION_TOKEN = 342,
- PARS_LOCK_TOKEN = 343,
- PARS_SHARE_TOKEN = 344,
- PARS_MODE_TOKEN = 345,
- PARS_LIKE_TOKEN = 346,
- PARS_LIKE_TOKEN_EXACT = 347,
- PARS_LIKE_TOKEN_PREFIX = 348,
- PARS_LIKE_TOKEN_SUFFIX = 349,
- PARS_LIKE_TOKEN_SUBSTR = 350,
- PARS_TABLE_NAME_TOKEN = 351,
- PARS_COMPACT_TOKEN = 352,
- PARS_BLOCK_SIZE_TOKEN = 353,
- PARS_BIGINT_TOKEN = 354,
- NEG = 355
+ PARS_INT_TOKEN = 271,
+ PARS_CHAR_TOKEN = 272,
+ PARS_IS_TOKEN = 273,
+ PARS_BEGIN_TOKEN = 274,
+ PARS_END_TOKEN = 275,
+ PARS_IF_TOKEN = 276,
+ PARS_THEN_TOKEN = 277,
+ PARS_ELSE_TOKEN = 278,
+ PARS_ELSIF_TOKEN = 279,
+ PARS_LOOP_TOKEN = 280,
+ PARS_WHILE_TOKEN = 281,
+ PARS_RETURN_TOKEN = 282,
+ PARS_SELECT_TOKEN = 283,
+ PARS_COUNT_TOKEN = 284,
+ PARS_FROM_TOKEN = 285,
+ PARS_WHERE_TOKEN = 286,
+ PARS_FOR_TOKEN = 287,
+ PARS_DDOT_TOKEN = 288,
+ PARS_ORDER_TOKEN = 289,
+ PARS_BY_TOKEN = 290,
+ PARS_ASC_TOKEN = 291,
+ PARS_DESC_TOKEN = 292,
+ PARS_INSERT_TOKEN = 293,
+ PARS_INTO_TOKEN = 294,
+ PARS_VALUES_TOKEN = 295,
+ PARS_UPDATE_TOKEN = 296,
+ PARS_SET_TOKEN = 297,
+ PARS_DELETE_TOKEN = 298,
+ PARS_CURRENT_TOKEN = 299,
+ PARS_OF_TOKEN = 300,
+ PARS_CREATE_TOKEN = 301,
+ PARS_TABLE_TOKEN = 302,
+ PARS_INDEX_TOKEN = 303,
+ PARS_UNIQUE_TOKEN = 304,
+ PARS_CLUSTERED_TOKEN = 305,
+ PARS_ON_TOKEN = 306,
+ PARS_ASSIGN_TOKEN = 307,
+ PARS_DECLARE_TOKEN = 308,
+ PARS_CURSOR_TOKEN = 309,
+ PARS_SQL_TOKEN = 310,
+ PARS_OPEN_TOKEN = 311,
+ PARS_FETCH_TOKEN = 312,
+ PARS_CLOSE_TOKEN = 313,
+ PARS_NOTFOUND_TOKEN = 314,
+ PARS_TO_BINARY_TOKEN = 315,
+ PARS_SUBSTR_TOKEN = 316,
+ PARS_CONCAT_TOKEN = 317,
+ PARS_INSTR_TOKEN = 318,
+ PARS_LENGTH_TOKEN = 319,
+ PARS_COMMIT_TOKEN = 320,
+ PARS_ROLLBACK_TOKEN = 321,
+ PARS_WORK_TOKEN = 322,
+ PARS_EXIT_TOKEN = 323,
+ PARS_FUNCTION_TOKEN = 324,
+ PARS_LOCK_TOKEN = 325,
+ PARS_SHARE_TOKEN = 326,
+ PARS_MODE_TOKEN = 327,
+ PARS_LIKE_TOKEN = 328,
+ PARS_LIKE_TOKEN_EXACT = 329,
+ PARS_LIKE_TOKEN_PREFIX = 330,
+ PARS_LIKE_TOKEN_SUFFIX = 331,
+ PARS_LIKE_TOKEN_SUBSTR = 332,
+ PARS_TABLE_NAME_TOKEN = 333,
+ PARS_BIGINT_TOKEN = 334,
+ NEG = 335
};
#endif
@@ -231,9 +219,7 @@ int yyparse (void);
#endif /* !YY_YY_PARS0GRM_TAB_H_INCLUDED */
-/* Copy the second part of user declarations. */
-#line 237 "pars0grm.cc" /* yacc.c:358 */
#ifdef short
# undef short
@@ -254,13 +240,13 @@ typedef signed char yytype_int8;
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
-typedef short int yytype_int16;
+typedef short yytype_int16;
#endif
#ifndef YYSIZE_T
@@ -272,7 +258,7 @@ typedef short int yytype_int16;
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
-# define YYSIZE_T unsigned int
+# define YYSIZE_T unsigned
# endif
#endif
@@ -308,15 +294,6 @@ typedef short int yytype_int16;
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
#endif
-#if !defined _Noreturn \
- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-# define _Noreturn __declspec (noreturn)
-# else
-# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
@@ -324,7 +301,7 @@ typedef short int yytype_int16;
# define YYUSE(E) /* empty */
#endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
@@ -344,6 +321,8 @@ typedef short int yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -475,42 +454,42 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 5
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 780
+#define YYLAST 603
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 116
+#define YYNTOKENS 96
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 72
+#define YYNNTS 64
/* YYNRULES -- Number of rules. */
-#define YYNRULES 178
+#define YYNRULES 150
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 345
+#define YYNSTATES 300
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
- by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 355
+#define YYMAXUTOK 335
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+ ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
- as returned by yylex, without out-of-bounds checking. */
+ as returned by yylex. */
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 108, 2, 2,
- 110, 111, 105, 104, 113, 103, 2, 106, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 109,
- 101, 100, 102, 112, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 88, 2, 2,
+ 90, 91, 85, 84, 93, 83, 2, 86, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 89,
+ 81, 80, 82, 92, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 114, 2, 115, 2, 2, 2, 2,
+ 2, 2, 2, 94, 2, 95, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -531,33 +510,29 @@ static const yytype_uint8 yytranslate[] =
45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- 95, 96, 97, 98, 99, 107
+ 75, 76, 77, 78, 79, 87
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 160, 160, 163, 164, 165, 166, 167, 168, 169,
- 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
- 180, 181, 182, 183, 184, 188, 189, 194, 195, 197,
- 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
- 208, 209, 211, 212, 213, 214, 215, 216, 217, 218,
- 219, 221, 226, 227, 228, 229, 231, 232, 233, 234,
- 235, 236, 237, 240, 242, 243, 247, 253, 258, 259,
- 260, 264, 268, 269, 274, 275, 276, 281, 282, 283,
- 287, 288, 293, 299, 306, 307, 308, 313, 315, 318,
- 322, 323, 327, 328, 333, 334, 339, 340, 341, 345,
- 346, 353, 368, 373, 376, 384, 390, 391, 396, 402,
- 411, 419, 427, 434, 442, 450, 456, 463, 469, 470,
- 475, 476, 478, 482, 489, 495, 505, 509, 513, 520,
- 527, 531, 539, 548, 549, 554, 555, 560, 561, 567,
- 568, 574, 575, 580, 581, 586, 597, 598, 603, 604,
- 608, 609, 613, 627, 628, 632, 637, 642, 643, 644,
- 645, 646, 650, 655, 663, 664, 665, 670, 676, 678,
- 679, 683, 691, 697, 698, 701, 703, 704, 708
+ 0, 140, 140, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 166, 167, 172, 173, 175, 176, 177,
+ 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
+ 189, 190, 191, 192, 193, 194, 195, 196, 197, 199,
+ 204, 205, 206, 207, 208, 211, 213, 214, 218, 224,
+ 228, 229, 234, 235, 236, 241, 242, 243, 247, 248,
+ 256, 257, 258, 263, 265, 268, 272, 273, 277, 278,
+ 283, 284, 289, 290, 291, 295, 296, 303, 318, 323,
+ 326, 334, 340, 341, 346, 352, 361, 369, 377, 384,
+ 392, 400, 407, 413, 414, 419, 420, 422, 426, 433,
+ 439, 449, 453, 457, 464, 471, 475, 483, 492, 493,
+ 498, 499, 504, 505, 511, 519, 520, 525, 526, 530,
+ 531, 535, 549, 550, 554, 559, 564, 565, 566, 570,
+ 576, 578, 579, 583, 591, 597, 598, 601, 603, 604,
+ 608
};
#endif
@@ -570,39 +545,30 @@ static const char *const yytname[] =
"PARS_STR_LIT", "PARS_NULL_LIT", "PARS_ID_TOKEN", "PARS_AND_TOKEN",
"PARS_OR_TOKEN", "PARS_NOT_TOKEN", "PARS_GE_TOKEN", "PARS_LE_TOKEN",
"PARS_NE_TOKEN", "PARS_PROCEDURE_TOKEN", "PARS_IN_TOKEN",
- "PARS_OUT_TOKEN", "PARS_BINARY_TOKEN", "PARS_BLOB_TOKEN",
- "PARS_INT_TOKEN", "PARS_FLOAT_TOKEN", "PARS_CHAR_TOKEN", "PARS_IS_TOKEN",
- "PARS_BEGIN_TOKEN", "PARS_END_TOKEN", "PARS_IF_TOKEN", "PARS_THEN_TOKEN",
- "PARS_ELSE_TOKEN", "PARS_ELSIF_TOKEN", "PARS_LOOP_TOKEN",
- "PARS_WHILE_TOKEN", "PARS_RETURN_TOKEN", "PARS_SELECT_TOKEN",
- "PARS_SUM_TOKEN", "PARS_COUNT_TOKEN", "PARS_DISTINCT_TOKEN",
+ "PARS_INT_TOKEN", "PARS_CHAR_TOKEN", "PARS_IS_TOKEN", "PARS_BEGIN_TOKEN",
+ "PARS_END_TOKEN", "PARS_IF_TOKEN", "PARS_THEN_TOKEN", "PARS_ELSE_TOKEN",
+ "PARS_ELSIF_TOKEN", "PARS_LOOP_TOKEN", "PARS_WHILE_TOKEN",
+ "PARS_RETURN_TOKEN", "PARS_SELECT_TOKEN", "PARS_COUNT_TOKEN",
"PARS_FROM_TOKEN", "PARS_WHERE_TOKEN", "PARS_FOR_TOKEN",
- "PARS_DDOT_TOKEN", "PARS_READ_TOKEN", "PARS_ORDER_TOKEN",
- "PARS_BY_TOKEN", "PARS_ASC_TOKEN", "PARS_DESC_TOKEN",
- "PARS_INSERT_TOKEN", "PARS_INTO_TOKEN", "PARS_VALUES_TOKEN",
- "PARS_UPDATE_TOKEN", "PARS_SET_TOKEN", "PARS_DELETE_TOKEN",
- "PARS_CURRENT_TOKEN", "PARS_OF_TOKEN", "PARS_CREATE_TOKEN",
- "PARS_TABLE_TOKEN", "PARS_INDEX_TOKEN", "PARS_UNIQUE_TOKEN",
- "PARS_CLUSTERED_TOKEN", "PARS_ON_TOKEN", "PARS_ASSIGN_TOKEN",
- "PARS_DECLARE_TOKEN", "PARS_CURSOR_TOKEN", "PARS_SQL_TOKEN",
- "PARS_OPEN_TOKEN", "PARS_FETCH_TOKEN", "PARS_CLOSE_TOKEN",
- "PARS_NOTFOUND_TOKEN", "PARS_TO_CHAR_TOKEN", "PARS_TO_NUMBER_TOKEN",
- "PARS_TO_BINARY_TOKEN", "PARS_BINARY_TO_NUMBER_TOKEN",
- "PARS_SUBSTR_TOKEN", "PARS_REPLSTR_TOKEN", "PARS_CONCAT_TOKEN",
- "PARS_INSTR_TOKEN", "PARS_LENGTH_TOKEN", "PARS_SYSDATE_TOKEN",
- "PARS_PRINTF_TOKEN", "PARS_ASSERT_TOKEN", "PARS_RND_TOKEN",
- "PARS_RND_STR_TOKEN", "PARS_ROW_PRINTF_TOKEN", "PARS_COMMIT_TOKEN",
- "PARS_ROLLBACK_TOKEN", "PARS_WORK_TOKEN", "PARS_UNSIGNED_TOKEN",
- "PARS_EXIT_TOKEN", "PARS_FUNCTION_TOKEN", "PARS_LOCK_TOKEN",
- "PARS_SHARE_TOKEN", "PARS_MODE_TOKEN", "PARS_LIKE_TOKEN",
- "PARS_LIKE_TOKEN_EXACT", "PARS_LIKE_TOKEN_PREFIX",
+ "PARS_DDOT_TOKEN", "PARS_ORDER_TOKEN", "PARS_BY_TOKEN", "PARS_ASC_TOKEN",
+ "PARS_DESC_TOKEN", "PARS_INSERT_TOKEN", "PARS_INTO_TOKEN",
+ "PARS_VALUES_TOKEN", "PARS_UPDATE_TOKEN", "PARS_SET_TOKEN",
+ "PARS_DELETE_TOKEN", "PARS_CURRENT_TOKEN", "PARS_OF_TOKEN",
+ "PARS_CREATE_TOKEN", "PARS_TABLE_TOKEN", "PARS_INDEX_TOKEN",
+ "PARS_UNIQUE_TOKEN", "PARS_CLUSTERED_TOKEN", "PARS_ON_TOKEN",
+ "PARS_ASSIGN_TOKEN", "PARS_DECLARE_TOKEN", "PARS_CURSOR_TOKEN",
+ "PARS_SQL_TOKEN", "PARS_OPEN_TOKEN", "PARS_FETCH_TOKEN",
+ "PARS_CLOSE_TOKEN", "PARS_NOTFOUND_TOKEN", "PARS_TO_BINARY_TOKEN",
+ "PARS_SUBSTR_TOKEN", "PARS_CONCAT_TOKEN", "PARS_INSTR_TOKEN",
+ "PARS_LENGTH_TOKEN", "PARS_COMMIT_TOKEN", "PARS_ROLLBACK_TOKEN",
+ "PARS_WORK_TOKEN", "PARS_EXIT_TOKEN", "PARS_FUNCTION_TOKEN",
+ "PARS_LOCK_TOKEN", "PARS_SHARE_TOKEN", "PARS_MODE_TOKEN",
+ "PARS_LIKE_TOKEN", "PARS_LIKE_TOKEN_EXACT", "PARS_LIKE_TOKEN_PREFIX",
"PARS_LIKE_TOKEN_SUFFIX", "PARS_LIKE_TOKEN_SUBSTR",
- "PARS_TABLE_NAME_TOKEN", "PARS_COMPACT_TOKEN", "PARS_BLOCK_SIZE_TOKEN",
- "PARS_BIGINT_TOKEN", "'='", "'<'", "'>'", "'-'", "'+'", "'*'", "'/'",
- "NEG", "'%'", "';'", "'('", "')'", "'?'", "','", "'{'", "'}'", "$accept",
- "top_statement", "statement", "statement_list", "exp", "function_name",
- "question_mark_list", "stored_procedure_call",
- "predefined_procedure_call", "predefined_procedure_name",
+ "PARS_TABLE_NAME_TOKEN", "PARS_BIGINT_TOKEN", "'='", "'<'", "'>'", "'-'",
+ "'+'", "'*'", "'/'", "NEG", "'%'", "';'", "'('", "')'", "'?'", "','",
+ "'{'", "'}'", "$accept", "top_statement", "statement", "statement_list",
+ "exp", "function_name", "question_mark_list", "stored_procedure_call",
"user_function_call", "table_list", "variable_list", "exp_list",
"select_item", "select_item_list", "select_list", "search_condition",
"for_update_clause", "lock_shared_clause", "order_direction",
@@ -611,16 +577,14 @@ static const char *const yytname[] =
"cursor_positioned", "update_statement_start",
"update_statement_searched", "update_statement_positioned",
"delete_statement_start", "delete_statement_searched",
- "delete_statement_positioned", "row_printf_statement",
- "assignment_statement", "elsif_element", "elsif_list", "else_part",
- "if_statement", "while_statement", "for_statement", "exit_statement",
- "return_statement", "open_cursor_statement", "close_cursor_statement",
- "fetch_statement", "column_def", "column_def_list", "opt_column_len",
- "opt_unsigned", "opt_not_null", "compact", "block_size", "create_table",
- "column_list", "unique_def", "clustered_def", "create_index",
- "table_name", "commit_statement", "rollback_statement", "type_name",
- "parameter_declaration", "parameter_declaration_list",
- "variable_declaration", "variable_declaration_list",
+ "delete_statement_positioned", "assignment_statement", "elsif_element",
+ "elsif_list", "else_part", "if_statement", "while_statement",
+ "for_statement", "exit_statement", "return_statement",
+ "open_cursor_statement", "close_cursor_statement", "fetch_statement",
+ "column_def", "column_def_list", "opt_column_len", "opt_not_null",
+ "create_table", "column_list", "unique_def", "clustered_def",
+ "create_index", "table_name", "commit_statement", "rollback_statement",
+ "type_name", "variable_declaration", "variable_declaration_list",
"cursor_declaration", "function_declaration", "declaration",
"declaration_list", "procedure_definition", YY_NULLPTR
};
@@ -639,17 +603,15 @@ static const yytype_uint16 yytoknum[] =
305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
- 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
- 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
- 61, 60, 62, 45, 43, 42, 47, 355, 37, 59,
+ 61, 60, 62, 45, 43, 42, 47, 335, 37, 59,
40, 41, 63, 44, 123, 125
};
# endif
-#define YYPACT_NINF -176
+#define YYPACT_NINF -129
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-176)))
+ (!!((Yystate) == (-129)))
#define YYTABLE_NINF -1
@@ -660,41 +622,36 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- 20, 21, 41, -64, -59, -176, -176, 48, 54, -176,
- -74, 12, 12, 45, 48, -176, -176, -176, -176, -176,
- -176, -176, 69, -176, 12, -176, 8, -32, -43, -176,
- -176, -176, -176, -13, -176, 72, 81, 445, -176, 75,
- -11, 42, 530, 530, -176, 16, 99, 67, -3, 78,
- -14, 108, 109, 110, -176, -176, -176, 86, 36, 44,
- -176, 122, -176, 216, -176, 22, 23, 25, 6, 26,
- 93, 27, 33, 93, 46, 51, 53, 56, 61, 63,
- 64, 66, 68, 70, 71, 76, 79, 89, 94, 95,
- 86, -176, 530, -176, -176, -176, -176, 43, 530, 49,
- -176, -176, -176, -176, -176, -176, -176, -176, -176, -176,
- -176, 530, 530, 570, 77, 603, 80, 96, -176, 674,
- -176, -38, 118, 161, -3, -176, -176, 129, -3, -3,
- -176, 148, -176, 163, -176, -176, -176, -176, 97, -176,
- -176, -176, 530, -176, 100, -176, -176, 481, -176, -176,
- -176, -176, -176, -176, -176, -176, -176, -176, -176, -176,
- -176, -176, -176, -176, -176, -176, -176, -176, -176, -176,
- 102, 674, 149, 220, 155, 14, 91, 530, 530, 530,
- 530, 530, 445, 219, 530, 530, 530, 530, 530, 530,
- 530, 530, 445, 530, -24, 218, 267, -3, 530, -176,
- 221, -176, 117, -176, 179, 228, 124, 674, -65, 530,
- 185, 674, -176, -176, -176, -176, 220, 220, 19, 19,
- 674, 136, -176, 19, 19, 19, 3, 3, 14, 14,
- -57, 326, 554, 231, 128, -176, 130, -176, -1, -176,
- 610, 142, -176, 131, 238, 242, 141, -176, 130, -176,
- -52, -176, 530, -51, 246, 445, 530, -176, 227, 233,
- -176, 229, -176, 151, -176, 252, 530, -3, 225, 530,
- 530, 221, 12, -176, -48, 207, 156, 153, 164, 674,
- -176, -176, 445, 626, -176, 250, -176, -176, -176, -176,
- 230, 194, 655, 674, -176, 173, 187, 238, -3, -176,
- -176, -176, 445, -176, -176, 270, 245, 445, 284, 204,
- -176, 192, -176, 181, 445, 203, 253, -176, 386, 193,
- -176, 286, 205, -176, 296, 217, 299, 279, -176, 303,
- -176, 307, -176, -47, -176, 30, -176, -176, -176, -176,
- 305, -176, -176, -176, -176
+ 5, 34, 46, -28, -41, -129, -129, -12, 45, 57,
+ 23, -129, 9, -129, -129, -129, 20, -9, -129, -129,
+ -129, -129, 2, -129, 83, 87, 278, -129, 93, 28,
+ 71, 427, 427, -129, 335, 105, 85, -1, 104, -27,
+ 129, 132, 133, 76, 77, -129, 141, -129, 149, -129,
+ 61, 19, 62, 118, 65, 66, 118, 68, 69, 70,
+ 72, 73, 74, 75, 78, 79, 82, 84, 89, 90,
+ 91, 94, 138, -129, 427, -129, -129, -129, -129, 86,
+ 427, 96, -129, -129, -129, -129, -129, 427, 427, 438,
+ 92, 454, 95, -129, 1, -129, -24, 130, 157, -1,
+ -129, -129, 144, -1, -1, -129, 139, -129, 154, -129,
+ -129, -129, 98, -129, -129, -129, 108, -129, -129, 345,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, 112, 1, 135, 285, 143, -8, 15, 427, 427,
+ 427, 427, 427, 278, 203, 427, 427, 427, 427, 427,
+ 427, 427, 427, 278, 124, 204, 381, -1, 427, -129,
+ 209, -129, 120, -129, 173, 215, 131, 427, 180, 1,
+ -129, -129, -129, -129, 285, 285, 30, 30, 1, 10,
+ -129, 30, 30, 30, 60, 60, -8, -8, 1, -39,
+ 192, 137, -129, 136, -129, -13, -129, 472, 146, -129,
+ 147, 225, 227, 151, -129, 136, -129, -21, 0, 229,
+ 278, 427, -129, 213, 219, -129, 427, 220, -129, 237,
+ 427, -1, 214, 427, 427, 209, 23, -129, 14, 196,
+ 160, 158, 162, -129, -129, 278, 486, -129, 231, 1,
+ -129, -129, -129, 218, 194, 517, 1, -129, 175, -129,
+ 225, -1, -129, -129, -129, 278, -129, -129, 251, 234,
+ 278, 266, 260, -129, 181, 278, 201, 239, -129, 235,
+ 184, 271, -129, 272, 208, 275, 258, -129, -129, -129,
+ 17, -129, -7, -129, -129, 277, -129, -129, -129, -129
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -702,67 +659,60 @@ static const yytype_int16 yypact[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 0, 0, 0, 0, 0, 1, 2, 164, 0, 165,
- 0, 0, 0, 0, 0, 160, 161, 157, 159, 158,
- 162, 163, 168, 166, 0, 169, 175, 0, 0, 170,
- 173, 174, 176, 0, 167, 0, 0, 0, 177, 0,
- 0, 0, 0, 0, 127, 84, 0, 0, 0, 0,
- 148, 0, 0, 0, 68, 69, 70, 0, 0, 0,
- 126, 0, 25, 0, 3, 0, 0, 0, 0, 0,
- 90, 0, 0, 90, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 2, 0, 0, 140,
+ 0, 141, 147, 136, 138, 137, 0, 0, 142, 145,
+ 146, 148, 0, 139, 0, 0, 0, 149, 0, 0,
+ 0, 0, 0, 112, 70, 0, 0, 0, 0, 127,
+ 0, 0, 0, 0, 0, 111, 0, 23, 0, 3,
+ 0, 0, 0, 76, 0, 0, 76, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 172, 0, 29, 30, 31, 32, 27, 0, 33,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 62, 0, 0, 0, 0, 0, 0, 0, 87, 80,
- 85, 89, 0, 0, 0, 153, 154, 0, 0, 0,
- 149, 150, 128, 0, 129, 115, 155, 156, 0, 178,
- 26, 4, 77, 11, 0, 104, 12, 0, 110, 111,
- 16, 17, 113, 114, 14, 15, 13, 10, 8, 5,
- 6, 7, 9, 18, 20, 19, 23, 24, 21, 22,
- 0, 116, 0, 49, 0, 38, 0, 0, 0, 0,
+ 0, 0, 0, 144, 0, 27, 28, 29, 30, 25,
+ 0, 31, 50, 51, 52, 53, 54, 0, 0, 0,
+ 0, 0, 0, 73, 68, 71, 75, 0, 0, 0,
+ 132, 133, 0, 0, 0, 128, 129, 113, 0, 114,
+ 134, 135, 0, 150, 24, 10, 0, 90, 11, 0,
+ 96, 97, 14, 15, 99, 100, 12, 13, 9, 7,
+ 4, 5, 6, 8, 16, 18, 17, 21, 22, 19,
+ 20, 0, 101, 0, 47, 0, 36, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 77, 0, 0, 0, 74, 0, 0, 0, 102,
- 0, 112, 0, 151, 0, 74, 63, 78, 0, 77,
- 0, 91, 171, 50, 51, 39, 47, 48, 44, 45,
- 46, 120, 41, 40, 42, 43, 35, 34, 36, 37,
- 0, 0, 0, 0, 0, 75, 88, 86, 90, 72,
- 0, 0, 106, 109, 0, 0, 75, 131, 130, 64,
- 0, 67, 0, 0, 0, 0, 0, 118, 122, 0,
- 28, 0, 83, 0, 81, 0, 0, 0, 92, 0,
- 0, 0, 0, 133, 0, 0, 0, 0, 0, 79,
- 103, 108, 121, 0, 119, 0, 124, 82, 76, 73,
- 0, 94, 0, 105, 107, 135, 141, 0, 0, 71,
- 66, 65, 0, 123, 93, 0, 99, 0, 0, 137,
- 142, 143, 134, 0, 117, 0, 0, 101, 0, 0,
- 138, 139, 0, 145, 0, 0, 0, 0, 136, 0,
- 132, 0, 146, 0, 95, 96, 125, 140, 144, 152,
- 0, 97, 98, 100, 147
+ 0, 0, 65, 0, 0, 62, 0, 0, 0, 88,
+ 0, 98, 0, 130, 0, 62, 55, 65, 0, 77,
+ 143, 48, 49, 37, 45, 46, 42, 43, 44, 105,
+ 39, 38, 40, 41, 33, 32, 34, 35, 66, 0,
+ 0, 0, 63, 74, 72, 76, 60, 0, 0, 92,
+ 95, 0, 0, 63, 116, 115, 56, 0, 0, 0,
+ 0, 0, 103, 107, 0, 26, 0, 0, 69, 0,
+ 0, 0, 78, 0, 0, 0, 0, 118, 0, 0,
+ 0, 0, 0, 89, 94, 106, 0, 104, 0, 67,
+ 109, 64, 61, 0, 80, 0, 91, 93, 120, 124,
+ 0, 0, 59, 58, 57, 0, 108, 79, 0, 85,
+ 0, 0, 122, 119, 0, 102, 0, 0, 87, 0,
+ 0, 0, 117, 0, 0, 0, 0, 121, 123, 125,
+ 0, 81, 82, 110, 131, 0, 83, 84, 86, 126
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
- -176, -176, -62, -175, -40, -176, -176, -176, -176, -176,
- -176, -176, 111, -166, 119, -176, -176, -67, -176, -176,
- -176, -176, -33, -176, -176, 47, -176, 240, -176, -176,
- -176, -176, -176, -176, -176, -176, 59, -176, -176, -176,
- -176, -176, -176, -176, -176, -176, -176, 17, -176, -176,
- -176, -176, -176, -176, -176, -176, -176, -176, -176, -115,
- -176, -176, -12, 313, -176, 293, -176, -176, -176, 295,
- -176, -176
+ -129, -129, -48, -128, -30, -129, -129, -129, -129, -129,
+ 113, 110, 123, -129, -129, -52, -129, -129, -129, -129,
+ -40, -129, -129, 55, -129, 238, -129, -129, -129, -129,
+ -129, -129, -129, 88, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, 35, -129, -129, -129, -129, -129,
+ -129, -129, -129, -96, -129, -129, 81, 290, -129, -129,
+ -129, 286, -129, -129
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
- -1, 2, 62, 63, 207, 114, 250, 64, 65, 66,
- 247, 238, 236, 208, 120, 121, 122, 148, 291, 306,
- 343, 317, 67, 68, 69, 242, 243, 149, 70, 71,
- 72, 73, 74, 75, 76, 77, 257, 258, 259, 78,
- 79, 80, 81, 82, 83, 84, 85, 273, 274, 309,
- 321, 330, 311, 323, 86, 333, 131, 204, 87, 127,
- 88, 89, 20, 9, 10, 25, 26, 30, 31, 32,
- 33, 3
+ -1, 2, 47, 48, 94, 90, 217, 49, 214, 205,
+ 203, 199, 95, 96, 97, 120, 254, 269, 298, 278,
+ 50, 51, 52, 209, 210, 121, 53, 54, 55, 56,
+ 57, 58, 59, 222, 223, 224, 60, 61, 62, 63,
+ 64, 65, 66, 67, 237, 238, 272, 282, 68, 290,
+ 106, 174, 69, 102, 70, 71, 16, 11, 12, 19,
+ 20, 21, 22, 3
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -770,232 +720,189 @@ static const yytype_int16 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint16 yytable[] =
{
- 21, 140, 113, 115, 125, 119, 152, 221, 195, 199,
- 37, 233, 27, 201, 202, 24, 181, 231, 35, 93,
- 94, 95, 96, 97, 135, 230, 98, 181, 4, 15,
- 16, 17, 181, 18, 1, 145, 266, 13, 45, 14,
- 129, 5, 130, 253, 36, 6, 251, 28, 252, 116,
- 117, 7, 171, 144, 260, 8, 252, 170, 173, 277,
- 280, 278, 252, 296, 339, 297, 340, 22, 28, 11,
- 12, 175, 176, 341, 342, 196, 24, 34, 99, 39,
- 282, 234, 239, 100, 101, 102, 103, 104, 40, 105,
- 106, 107, 108, 126, 183, 109, 110, 90, 91, 177,
- 178, 92, 179, 180, 181, 183, 123, 211, 189, 190,
- 183, 19, 267, 124, 128, 132, 133, 134, 45, 111,
- 136, 118, 187, 188, 189, 190, 112, 314, 137, 138,
- 147, 141, 318, 142, 143, 146, 150, 216, 217, 218,
- 219, 220, 151, 41, 223, 224, 225, 226, 227, 228,
- 229, 172, 289, 232, 197, 154, 119, 174, 240, 140,
- 155, 42, 156, 255, 256, 157, 43, 44, 45, 140,
- 158, 268, 159, 160, 46, 161, 198, 162, 200, 163,
- 164, 47, 183, 313, 48, 165, 49, 191, 166, 50,
- 193, 184, 185, 186, 187, 188, 189, 190, 167, 51,
- 52, 53, 215, 168, 169, 203, 194, 206, 54, 205,
- 209, 212, 279, 55, 56, 213, 283, 57, 58, 59,
- 140, 214, 60, 41, 222, 235, 211, 244, 241, 292,
- 293, 179, 180, 181, 245, 246, 249, 254, 263, 264,
- 139, 42, 270, 265, 271, 272, 43, 44, 45, 275,
- 61, 276, 140, 281, 46, 256, 140, 285, 286, 288,
- 295, 47, 287, 290, 48, 298, 49, 299, 300, 50,
- 93, 94, 95, 96, 97, 303, 301, 98, 304, 51,
- 52, 53, 305, 308, 310, 315, 316, 319, 54, 320,
- 322, 324, 325, 55, 56, 326, 329, 57, 58, 59,
- 116, 117, 60, 332, 328, 331, 335, 334, 336, 337,
- 338, 183, 344, 153, 312, 237, 248, 284, 294, 29,
- 184, 185, 186, 187, 188, 189, 190, 23, 38, 99,
- 61, 0, 0, 41, 100, 101, 102, 103, 104, 0,
- 105, 106, 107, 108, 0, 0, 109, 110, 0, 0,
- 261, 42, 0, 0, 0, 0, 43, 44, 45, 0,
- 0, 0, 0, 0, 46, 0, 0, 0, 0, 0,
- 111, 47, 0, 0, 48, 0, 49, 112, 0, 50,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 51,
- 52, 53, 0, 41, 0, 0, 0, 0, 54, 0,
- 0, 0, 0, 55, 56, 0, 0, 57, 58, 59,
- 327, 42, 60, 0, 0, 0, 43, 44, 45, 0,
- 0, 0, 0, 0, 46, 0, 0, 0, 0, 0,
- 0, 47, 0, 0, 48, 0, 49, 0, 0, 50,
- 61, 0, 0, 0, 0, 0, 0, 0, 0, 51,
- 52, 53, 41, 0, 0, 0, 0, 0, 54, 0,
- 0, 0, 0, 55, 56, 0, 0, 57, 58, 59,
- 42, 0, 60, 0, 0, 43, 44, 45, 0, 0,
- 0, 0, 0, 46, 93, 94, 95, 96, 97, 0,
- 47, 98, 0, 48, 0, 49, 0, 0, 50, 0,
- 61, 0, 0, 0, 0, 0, 0, 0, 51, 52,
- 53, 0, 0, 0, 0, 0, 0, 54, 0, 0,
- 0, 0, 55, 56, 0, 0, 57, 58, 59, 0,
- 0, 60, 210, 93, 94, 95, 96, 97, 0, 0,
- 98, 0, 0, 99, 0, 0, 0, 0, 100, 101,
- 102, 103, 104, 0, 105, 106, 107, 108, 0, 61,
- 109, 110, 177, 178, 0, 179, 180, 181, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 177, 178,
- 0, 179, 180, 181, 111, 0, 0, 0, 0, 0,
- 0, 112, 99, 0, 0, 0, 182, 100, 101, 102,
- 103, 104, 0, 105, 106, 107, 108, 0, 0, 109,
- 110, 177, 178, 0, 179, 180, 181, 0, 177, 178,
- 0, 179, 180, 181, 0, 0, 0, 0, 0, 0,
- 0, 0, 192, 111, 177, 178, 0, 179, 180, 181,
- 112, 0, 0, 0, 0, 183, 0, 0, 0, 269,
- 0, 0, 302, 0, 184, 185, 186, 187, 188, 189,
- 190, 183, 0, 177, 178, 262, 179, 180, 181, 0,
- 184, 185, 186, 187, 188, 189, 190, 0, 0, 0,
- 0, 0, 177, 178, 307, 179, 180, 181, 0, 0,
- 0, 0, 0, 0, 183, 0, 0, 0, 0, 0,
- 0, 183, 0, 184, 185, 186, 187, 188, 189, 190,
- 184, 185, 186, 187, 188, 189, 190, 183, 0, 0,
- 0, 0, 0, 0, 0, 0, 184, 185, 186, 187,
- 188, 189, 190, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 183, 0, 0, 0,
- 0, 0, 0, 0, 0, 184, 185, 186, 187, 188,
- 189, 190, 0, 0, 0, 183, 0, 0, 0, 0,
- 0, 0, 0, 0, 184, 185, 186, 187, 188, 189,
- 190
+ 114, 89, 91, 169, 124, 152, 100, 171, 172, 148,
+ 149, 117, 150, 151, 152, 165, 10, 30, 230, 1,
+ 104, 26, 105, 148, 149, 189, 150, 151, 152, 296,
+ 297, 31, 141, 220, 221, 200, 32, 33, 34, 13,
+ 14, 4, 35, 152, 142, 24, 5, 34, 36, 7,
+ 144, 37, 225, 38, 226, 17, 39, 146, 147, 116,
+ 25, 6, 17, 9, 10, 154, 40, 41, 42, 166,
+ 241, 206, 242, 152, 154, 43, 44, 101, 45, 8,
+ 231, 155, 156, 157, 158, 159, 160, 161, 154, 179,
+ 28, 243, 245, 226, 29, 155, 156, 157, 158, 159,
+ 160, 161, 15, 154, 46, 259, 183, 260, 294, 23,
+ 295, 72, 98, 158, 159, 160, 161, 73, 184, 185,
+ 186, 187, 188, 74, 99, 191, 192, 193, 194, 195,
+ 196, 197, 198, 154, 103, 252, 107, 275, 207, 108,
+ 109, 114, 279, 110, 111, 160, 161, 198, 112, 119,
+ 115, 118, 114, 232, 122, 123, 30, 126, 127, 128,
+ 167, 129, 130, 131, 132, 274, 34, 133, 134, 113,
+ 31, 135, 168, 136, 143, 32, 33, 34, 137, 138,
+ 139, 35, 162, 140, 145, 164, 170, 36, 176, 173,
+ 37, 246, 38, 175, 181, 39, 249, 114, 177, 30,
+ 179, 180, 182, 255, 256, 40, 41, 42, 190, 201,
+ 211, 202, 227, 31, 43, 44, 208, 45, 32, 33,
+ 34, 212, 213, 216, 35, 219, 234, 114, 228, 229,
+ 36, 114, 236, 37, 239, 38, 244, 221, 39, 248,
+ 235, 240, 30, 46, 251, 250, 253, 261, 40, 41,
+ 42, 262, 266, 263, 264, 286, 31, 43, 44, 267,
+ 45, 32, 33, 34, 268, 271, 276, 35, 277, 280,
+ 281, 283, 284, 36, 285, 287, 37, 288, 38, 289,
+ 291, 39, 292, 293, 299, 30, 46, 218, 215, 204,
+ 257, 40, 41, 42, 125, 273, 150, 151, 152, 31,
+ 43, 44, 18, 45, 32, 33, 34, 0, 27, 0,
+ 35, 247, 0, 0, 0, 0, 36, 258, 0, 37,
+ 0, 38, 0, 0, 39, 0, 0, 0, 0, 46,
+ 0, 0, 0, 0, 40, 41, 42, 0, 75, 76,
+ 77, 78, 79, 43, 44, 80, 45, 0, 75, 76,
+ 77, 78, 79, 0, 0, 80, 0, 0, 154, 0,
+ 0, 0, 0, 0, 92, 155, 156, 157, 158, 159,
+ 160, 161, 46, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 75, 76, 77, 78, 79, 178,
+ 81, 80, 0, 0, 0, 82, 83, 84, 85, 86,
+ 81, 0, 0, 0, 0, 82, 83, 84, 85, 86,
+ 92, 0, 0, 0, 0, 0, 0, 0, 87, 0,
+ 93, 0, 0, 0, 0, 88, 0, 0, 87, 0,
+ 75, 76, 77, 78, 79, 88, 81, 80, 0, 0,
+ 0, 82, 83, 84, 85, 86, 148, 149, 0, 150,
+ 151, 152, 0, 0, 0, 0, 0, 0, 0, 0,
+ 153, 0, 148, 149, 87, 150, 151, 152, 0, 0,
+ 0, 88, 0, 0, 0, 0, 0, 0, 0, 163,
+ 148, 149, 81, 150, 151, 152, 0, 82, 83, 84,
+ 85, 86, 0, 0, 148, 149, 0, 150, 151, 152,
+ 0, 0, 0, 0, 0, 233, 0, 0, 265, 0,
+ 87, 154, 0, 0, 0, 0, 0, 88, 155, 156,
+ 157, 158, 159, 160, 161, 148, 149, 154, 150, 151,
+ 152, 0, 0, 0, 155, 156, 157, 158, 159, 160,
+ 161, 0, 270, 0, 0, 154, 0, 0, 0, 0,
+ 0, 0, 155, 156, 157, 158, 159, 160, 161, 154,
+ 0, 0, 0, 0, 0, 0, 155, 156, 157, 158,
+ 159, 160, 161, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 154, 0, 0, 0, 0, 0, 0, 155, 156, 157,
+ 158, 159, 160, 161
};
static const yytype_int16 yycheck[] =
{
- 12, 63, 42, 43, 7, 45, 73, 182, 46, 124,
- 23, 35, 24, 128, 129, 7, 13, 192, 61, 3,
- 4, 5, 6, 7, 57, 191, 10, 13, 7, 17,
- 18, 19, 13, 21, 14, 68, 37, 111, 32, 113,
- 54, 0, 56, 209, 87, 109, 111, 60, 113, 33,
- 34, 110, 92, 47, 111, 7, 113, 90, 98, 111,
- 111, 113, 113, 111, 111, 113, 113, 22, 60, 15,
- 16, 111, 112, 43, 44, 113, 7, 109, 62, 7,
- 255, 105, 197, 67, 68, 69, 70, 71, 7, 73,
- 74, 75, 76, 96, 91, 79, 80, 22, 109, 8,
- 9, 59, 11, 12, 13, 91, 7, 147, 105, 106,
- 91, 99, 113, 46, 36, 7, 7, 7, 32, 103,
- 84, 105, 103, 104, 105, 106, 110, 302, 84, 7,
- 37, 109, 307, 110, 109, 109, 109, 177, 178, 179,
- 180, 181, 109, 7, 184, 185, 186, 187, 188, 189,
- 190, 108, 267, 193, 36, 109, 196, 108, 198, 221,
- 109, 25, 109, 27, 28, 109, 30, 31, 32, 231,
- 109, 238, 109, 109, 38, 109, 15, 109, 49, 109,
- 109, 45, 91, 298, 48, 109, 50, 110, 109, 53,
- 110, 100, 101, 102, 103, 104, 105, 106, 109, 63,
- 64, 65, 111, 109, 109, 57, 110, 110, 72, 46,
- 110, 109, 252, 77, 78, 66, 256, 81, 82, 83,
- 282, 66, 86, 7, 5, 7, 266, 110, 7, 269,
- 270, 11, 12, 13, 55, 7, 112, 52, 7, 111,
- 24, 25, 100, 113, 113, 7, 30, 31, 32, 7,
- 114, 110, 314, 7, 38, 28, 318, 24, 29, 7,
- 272, 45, 111, 38, 48, 58, 50, 111, 115, 53,
- 3, 4, 5, 6, 7, 25, 112, 10, 48, 63,
- 64, 65, 88, 110, 97, 15, 41, 3, 72, 85,
- 98, 110, 89, 77, 78, 42, 10, 81, 82, 83,
- 33, 34, 86, 7, 111, 100, 7, 90, 29, 6,
- 3, 91, 7, 73, 297, 196, 205, 258, 271, 26,
- 100, 101, 102, 103, 104, 105, 106, 14, 33, 62,
- 114, -1, -1, 7, 67, 68, 69, 70, 71, -1,
- 73, 74, 75, 76, -1, -1, 79, 80, -1, -1,
- 24, 25, -1, -1, -1, -1, 30, 31, 32, -1,
- -1, -1, -1, -1, 38, -1, -1, -1, -1, -1,
- 103, 45, -1, -1, 48, -1, 50, 110, -1, 53,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 63,
- 64, 65, -1, 7, -1, -1, -1, -1, 72, -1,
- -1, -1, -1, 77, 78, -1, -1, 81, 82, 83,
- 24, 25, 86, -1, -1, -1, 30, 31, 32, -1,
- -1, -1, -1, -1, 38, -1, -1, -1, -1, -1,
- -1, 45, -1, -1, 48, -1, 50, -1, -1, 53,
- 114, -1, -1, -1, -1, -1, -1, -1, -1, 63,
- 64, 65, 7, -1, -1, -1, -1, -1, 72, -1,
- -1, -1, -1, 77, 78, -1, -1, 81, 82, 83,
- 25, -1, 86, -1, -1, 30, 31, 32, -1, -1,
- -1, -1, -1, 38, 3, 4, 5, 6, 7, -1,
- 45, 10, -1, 48, -1, 50, -1, -1, 53, -1,
- 114, -1, -1, -1, -1, -1, -1, -1, 63, 64,
- 65, -1, -1, -1, -1, -1, -1, 72, -1, -1,
- -1, -1, 77, 78, -1, -1, 81, 82, 83, -1,
- -1, 86, 51, 3, 4, 5, 6, 7, -1, -1,
- 10, -1, -1, 62, -1, -1, -1, -1, 67, 68,
- 69, 70, 71, -1, 73, 74, 75, 76, -1, 114,
- 79, 80, 8, 9, -1, 11, 12, 13, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 8, 9,
- -1, 11, 12, 13, 103, -1, -1, -1, -1, -1,
- -1, 110, 62, -1, -1, -1, 26, 67, 68, 69,
- 70, 71, -1, 73, 74, 75, 76, -1, -1, 79,
- 80, 8, 9, -1, 11, 12, 13, -1, 8, 9,
- -1, 11, 12, 13, -1, -1, -1, -1, -1, -1,
- -1, -1, 29, 103, 8, 9, -1, 11, 12, 13,
- 110, -1, -1, -1, -1, 91, -1, -1, -1, 39,
- -1, -1, 26, -1, 100, 101, 102, 103, 104, 105,
- 106, 91, -1, 8, 9, 111, 11, 12, 13, -1,
- 100, 101, 102, 103, 104, 105, 106, -1, -1, -1,
- -1, -1, 8, 9, 29, 11, 12, 13, -1, -1,
- -1, -1, -1, -1, 91, -1, -1, -1, -1, -1,
- -1, 91, -1, 100, 101, 102, 103, 104, 105, 106,
- 100, 101, 102, 103, 104, 105, 106, 91, -1, -1,
- -1, -1, -1, -1, -1, -1, 100, 101, 102, 103,
- 104, 105, 106, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 91, -1, -1, -1,
- -1, -1, -1, -1, -1, 100, 101, 102, 103, 104,
- 105, 106, -1, -1, -1, 91, -1, -1, -1, -1,
- -1, -1, -1, -1, 100, 101, 102, 103, 104, 105,
- 106
+ 48, 31, 32, 99, 56, 13, 7, 103, 104, 8,
+ 9, 51, 11, 12, 13, 39, 7, 7, 31, 14,
+ 47, 19, 49, 8, 9, 153, 11, 12, 13, 36,
+ 37, 21, 72, 23, 24, 163, 26, 27, 28, 16,
+ 17, 7, 32, 13, 74, 54, 0, 28, 38, 90,
+ 80, 41, 91, 43, 93, 53, 46, 87, 88, 40,
+ 69, 89, 53, 18, 7, 73, 56, 57, 58, 93,
+ 91, 167, 93, 13, 73, 65, 66, 78, 68, 91,
+ 93, 80, 81, 82, 83, 84, 85, 86, 73, 119,
+ 7, 91, 220, 93, 7, 80, 81, 82, 83, 84,
+ 85, 86, 79, 73, 94, 91, 91, 93, 91, 89,
+ 93, 18, 7, 83, 84, 85, 86, 89, 148, 149,
+ 150, 151, 152, 52, 39, 155, 156, 157, 158, 159,
+ 160, 161, 162, 73, 30, 231, 7, 265, 168, 7,
+ 7, 189, 270, 67, 67, 85, 86, 177, 7, 31,
+ 89, 89, 200, 205, 89, 89, 7, 89, 89, 89,
+ 30, 89, 89, 89, 89, 261, 28, 89, 89, 20,
+ 21, 89, 15, 89, 88, 26, 27, 28, 89, 89,
+ 89, 32, 90, 89, 88, 90, 42, 38, 90, 50,
+ 41, 221, 43, 39, 59, 46, 226, 245, 90, 7,
+ 230, 89, 59, 233, 234, 56, 57, 58, 5, 85,
+ 90, 7, 20, 21, 65, 66, 7, 68, 26, 27,
+ 28, 48, 7, 92, 32, 45, 80, 275, 91, 93,
+ 38, 279, 7, 41, 7, 43, 7, 24, 46, 20,
+ 93, 90, 7, 94, 7, 25, 32, 51, 56, 57,
+ 58, 91, 21, 95, 92, 20, 21, 65, 66, 41,
+ 68, 26, 27, 28, 70, 90, 15, 32, 34, 3,
+ 10, 90, 71, 38, 35, 91, 41, 6, 43, 7,
+ 72, 46, 7, 25, 7, 7, 94, 177, 175, 166,
+ 235, 56, 57, 58, 56, 260, 11, 12, 13, 21,
+ 65, 66, 12, 68, 26, 27, 28, -1, 22, -1,
+ 32, 223, -1, -1, -1, -1, 38, 236, -1, 41,
+ -1, 43, -1, -1, 46, -1, -1, -1, -1, 94,
+ -1, -1, -1, -1, 56, 57, 58, -1, 3, 4,
+ 5, 6, 7, 65, 66, 10, 68, -1, 3, 4,
+ 5, 6, 7, -1, -1, 10, -1, -1, 73, -1,
+ -1, -1, -1, -1, 29, 80, 81, 82, 83, 84,
+ 85, 86, 94, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 3, 4, 5, 6, 7, 44,
+ 55, 10, -1, -1, -1, 60, 61, 62, 63, 64,
+ 55, -1, -1, -1, -1, 60, 61, 62, 63, 64,
+ 29, -1, -1, -1, -1, -1, -1, -1, 83, -1,
+ 85, -1, -1, -1, -1, 90, -1, -1, 83, -1,
+ 3, 4, 5, 6, 7, 90, 55, 10, -1, -1,
+ -1, 60, 61, 62, 63, 64, 8, 9, -1, 11,
+ 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
+ 22, -1, 8, 9, 83, 11, 12, 13, -1, -1,
+ -1, 90, -1, -1, -1, -1, -1, -1, -1, 25,
+ 8, 9, 55, 11, 12, 13, -1, 60, 61, 62,
+ 63, 64, -1, -1, 8, 9, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, 33, -1, -1, 22, -1,
+ 83, 73, -1, -1, -1, -1, -1, 90, 80, 81,
+ 82, 83, 84, 85, 86, 8, 9, 73, 11, 12,
+ 13, -1, -1, -1, 80, 81, 82, 83, 84, 85,
+ 86, -1, 25, -1, -1, 73, -1, -1, -1, -1,
+ -1, -1, 80, 81, 82, 83, 84, 85, 86, 73,
+ -1, -1, -1, -1, -1, -1, 80, 81, 82, 83,
+ 84, 85, 86, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 73, -1, -1, -1, -1, -1, -1, 80, 81, 82,
+ 83, 84, 85, 86
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 14, 117, 187, 7, 0, 109, 110, 7, 179,
- 180, 15, 16, 111, 113, 17, 18, 19, 21, 99,
- 178, 178, 22, 179, 7, 181, 182, 178, 60, 181,
- 183, 184, 185, 186, 109, 61, 87, 23, 185, 7,
- 7, 7, 25, 30, 31, 32, 38, 45, 48, 50,
- 53, 63, 64, 65, 72, 77, 78, 81, 82, 83,
- 86, 114, 118, 119, 123, 124, 125, 138, 139, 140,
- 144, 145, 146, 147, 148, 149, 150, 151, 155, 156,
- 157, 158, 159, 160, 161, 162, 170, 174, 176, 177,
- 22, 109, 59, 3, 4, 5, 6, 7, 10, 62,
- 67, 68, 69, 70, 71, 73, 74, 75, 76, 79,
- 80, 103, 110, 120, 121, 120, 33, 34, 105, 120,
- 130, 131, 132, 7, 46, 7, 96, 175, 36, 54,
- 56, 172, 7, 7, 7, 138, 84, 84, 7, 24,
- 118, 109, 110, 109, 47, 138, 109, 37, 133, 143,
- 109, 109, 133, 143, 109, 109, 109, 109, 109, 109,
- 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
- 138, 120, 108, 120, 108, 120, 120, 8, 9, 11,
- 12, 13, 26, 91, 100, 101, 102, 103, 104, 105,
- 106, 110, 29, 110, 110, 46, 113, 36, 15, 175,
- 49, 175, 175, 57, 173, 46, 110, 120, 129, 110,
- 51, 120, 109, 66, 66, 111, 120, 120, 120, 120,
- 120, 119, 5, 120, 120, 120, 120, 120, 120, 120,
- 129, 119, 120, 35, 105, 7, 128, 130, 127, 175,
- 120, 7, 141, 142, 110, 55, 7, 126, 128, 112,
- 122, 111, 113, 129, 52, 27, 28, 152, 153, 154,
- 111, 24, 111, 7, 111, 113, 37, 113, 133, 39,
- 100, 113, 7, 163, 164, 7, 110, 111, 113, 120,
- 111, 7, 119, 120, 152, 24, 29, 111, 7, 175,
- 38, 134, 120, 120, 141, 178, 111, 113, 58, 111,
- 115, 112, 26, 25, 48, 88, 135, 29, 110, 165,
- 97, 168, 163, 175, 119, 15, 41, 137, 119, 3,
- 85, 166, 98, 169, 110, 89, 42, 24, 111, 10,
- 167, 100, 7, 171, 90, 7, 29, 6, 3, 111,
- 113, 43, 44, 136, 7
+ 0, 14, 97, 159, 7, 0, 89, 90, 91, 18,
+ 7, 153, 154, 16, 17, 79, 152, 53, 153, 155,
+ 156, 157, 158, 89, 54, 69, 19, 157, 7, 7,
+ 7, 21, 26, 27, 28, 32, 38, 41, 43, 46,
+ 56, 57, 58, 65, 66, 68, 94, 98, 99, 103,
+ 116, 117, 118, 122, 123, 124, 125, 126, 127, 128,
+ 132, 133, 134, 135, 136, 137, 138, 139, 144, 148,
+ 150, 151, 18, 89, 52, 3, 4, 5, 6, 7,
+ 10, 55, 60, 61, 62, 63, 64, 83, 90, 100,
+ 101, 100, 29, 85, 100, 108, 109, 110, 7, 39,
+ 7, 78, 149, 30, 47, 49, 146, 7, 7, 7,
+ 67, 67, 7, 20, 98, 89, 40, 116, 89, 31,
+ 111, 121, 89, 89, 111, 121, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 116, 100, 88, 100, 88, 100, 100, 8, 9,
+ 11, 12, 13, 22, 73, 80, 81, 82, 83, 84,
+ 85, 86, 90, 25, 90, 39, 93, 30, 15, 149,
+ 42, 149, 149, 50, 147, 39, 90, 90, 44, 100,
+ 89, 59, 59, 91, 100, 100, 100, 100, 100, 99,
+ 5, 100, 100, 100, 100, 100, 100, 100, 100, 107,
+ 99, 85, 7, 106, 108, 105, 149, 100, 7, 119,
+ 120, 90, 48, 7, 104, 106, 92, 102, 107, 45,
+ 23, 24, 129, 130, 131, 91, 93, 20, 91, 93,
+ 31, 93, 111, 33, 80, 93, 7, 140, 141, 7,
+ 90, 91, 93, 91, 7, 99, 100, 129, 20, 100,
+ 25, 7, 149, 32, 112, 100, 100, 119, 152, 91,
+ 93, 51, 91, 95, 92, 22, 21, 41, 70, 113,
+ 25, 90, 142, 140, 149, 99, 15, 34, 115, 99,
+ 3, 10, 143, 90, 71, 35, 20, 91, 6, 7,
+ 145, 72, 7, 25, 91, 93, 36, 37, 114, 7
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 116, 117, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 119, 119, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 121, 121, 121, 121, 121, 121, 121, 121,
- 121, 121, 121, 122, 122, 122, 123, 124, 125, 125,
- 125, 126, 127, 127, 128, 128, 128, 129, 129, 129,
- 130, 130, 130, 130, 131, 131, 131, 132, 132, 132,
- 133, 133, 134, 134, 135, 135, 136, 136, 136, 137,
- 137, 138, 139, 140, 140, 141, 142, 142, 143, 144,
- 145, 146, 147, 148, 149, 150, 151, 152, 153, 153,
- 154, 154, 154, 155, 156, 157, 158, 159, 160, 161,
- 162, 162, 163, 164, 164, 165, 165, 166, 166, 167,
- 167, 168, 168, 169, 169, 170, 171, 171, 172, 172,
- 173, 173, 174, 175, 175, 176, 177, 178, 178, 178,
- 178, 178, 179, 179, 180, 180, 180, 181, 182, 182,
- 182, 183, 184, 185, 185, 186, 186, 186, 187
+ 0, 96, 97, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 99, 99, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 101, 101, 101, 101, 101, 102, 102, 102, 103, 104,
+ 105, 105, 106, 106, 106, 107, 107, 107, 108, 108,
+ 109, 109, 109, 110, 110, 110, 111, 111, 112, 112,
+ 113, 113, 114, 114, 114, 115, 115, 116, 117, 118,
+ 118, 119, 120, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 130, 130, 131, 131, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139, 139, 140, 141, 141,
+ 142, 142, 143, 143, 144, 145, 145, 146, 146, 147,
+ 147, 148, 149, 149, 150, 151, 152, 152, 152, 153,
+ 154, 154, 154, 155, 156, 157, 157, 158, 158, 158,
+ 159
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -1003,22 +910,20 @@ static const yytype_uint8 yyr2[] =
{
0, 2, 2, 1, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 1, 2, 1, 4, 1,
- 1, 1, 1, 1, 3, 3, 3, 3, 2, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 2,
- 3, 3, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 0, 1, 3, 6, 4, 1, 1,
- 1, 3, 1, 3, 0, 1, 3, 0, 1, 3,
- 1, 4, 5, 4, 0, 1, 3, 1, 3, 1,
- 0, 2, 0, 2, 0, 4, 0, 1, 1, 0,
- 4, 8, 3, 5, 2, 3, 1, 3, 4, 4,
- 2, 2, 3, 2, 2, 2, 3, 4, 1, 2,
- 0, 2, 1, 7, 6, 10, 1, 1, 2, 2,
- 4, 4, 5, 1, 3, 0, 3, 0, 1, 0,
- 2, 0, 1, 0, 3, 8, 1, 3, 0, 1,
- 0, 1, 10, 1, 1, 2, 2, 1, 1, 1,
- 1, 1, 3, 3, 0, 1, 3, 3, 0, 1,
- 2, 6, 4, 1, 1, 0, 1, 2, 11
+ 2, 2, 2, 1, 2, 1, 4, 1, 1, 1,
+ 1, 1, 3, 3, 3, 3, 2, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 2, 3, 3,
+ 1, 1, 1, 1, 1, 0, 1, 3, 6, 3,
+ 1, 3, 0, 1, 3, 0, 1, 3, 1, 4,
+ 0, 1, 3, 1, 3, 1, 0, 2, 0, 2,
+ 0, 4, 0, 1, 1, 0, 4, 8, 3, 5,
+ 2, 3, 1, 3, 4, 4, 2, 2, 3, 2,
+ 2, 3, 4, 1, 2, 0, 2, 1, 7, 6,
+ 10, 1, 1, 2, 2, 4, 4, 4, 1, 3,
+ 0, 3, 0, 2, 6, 1, 3, 0, 1, 0,
+ 1, 10, 1, 1, 2, 2, 1, 1, 1, 3,
+ 0, 1, 2, 6, 4, 1, 1, 0, 1, 2,
+ 10
};
@@ -1034,22 +939,22 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (yylen); \
- yystate = *yyssp; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (0)
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
/* Error token number */
#define YYTERROR 1
@@ -1089,37 +994,39 @@ do { \
} while (0)
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT. |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep)
{
- FILE *yyo = yyoutput;
- YYUSE (yyo);
+ FILE *yyoutput = yyo;
+ YYUSE (yyoutput);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+ YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep)
{
- YYFPRINTF (yyoutput, "%s %s (",
+ YYFPRINTF (yyo, "%s %s (",
yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep);
- YYFPRINTF (yyoutput, ")");
+ yy_symbol_value_print (yyo, yytype, yyvaluep);
+ YYFPRINTF (yyo, ")");
}
/*------------------------------------------------------------------.
@@ -1153,7 +1060,7 @@ do { \
static void
yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
{
- unsigned long int yylno = yyrline[yyrule];
+ unsigned long yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -1164,7 +1071,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
yystos[yyssp[yyi + 1 - yynrhs]],
- &(yyvsp[(yyi + 1) - (yynrhs)])
+ &yyvsp[(yyi + 1) - (yynrhs)]
);
YYFPRINTF (stderr, "\n");
}
@@ -1268,7 +1175,10 @@ yytnamerr (char *yyres, const char *yystr)
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
- /* Fall through. */
+ else
+ goto append;
+
+ append:
default:
if (yyres)
yyres[yyn] = *yyp;
@@ -1286,7 +1196,7 @@ yytnamerr (char *yyres, const char *yystr)
if (! yyres)
return yystrlen (yystr);
- return yystpcpy (yyres, yystr) - yyres;
+ return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
}
# endif
@@ -1364,10 +1274,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yyarg[yycount++] = yytname[yyx];
{
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
}
}
@@ -1379,6 +1289,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
case N: \
yyformat = S; \
break
+ default: /* Avoid compiler warnings. */
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -1390,9 +1301,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
{
YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
if (*yymsg_alloc < yysize)
@@ -1518,23 +1430,33 @@ yyparse (void)
yychar = YYEMPTY; /* Cause a token to be read. */
goto yysetstate;
+
/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
+| yynewstate -- push a new state, which is found in yystate. |
`------------------------------------------------------------*/
- yynewstate:
+yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
- yysetstate:
- *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
+ *yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+#else
{
/* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
+ YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
-#ifdef yyoverflow
+# if defined yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
@@ -1550,14 +1472,10 @@ yyparse (void)
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yystacksize);
-
yyss = yyss1;
yyvs = yyvs1;
}
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
@@ -1573,35 +1491,33 @@ yyparse (void)
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-# undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
-#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
+ (unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
if (yystate == YYFINAL)
YYACCEPT;
goto yybackup;
+
/*-----------.
| yybackup. |
`-----------*/
yybackup:
-
/* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */
@@ -1659,7 +1575,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -1674,7 +1589,7 @@ yydefault:
/*-----------------------------.
-| yyreduce -- Do a reduction. |
+| yyreduce -- do a reduction. |
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
@@ -1694,953 +1609,779 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 25:
-#line 188 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 1701 "pars0grm.cc" /* yacc.c:1646 */
+ case 23:
+#line 166 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]); }
+#line 1616 "pars0grm.cc"
+ break;
+
+ case 24:
+#line 168 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); }
+#line 1622 "pars0grm.cc"
+ break;
+
+ case 25:
+#line 172 "pars0grm.y"
+ { yyval = yyvsp[0];}
+#line 1628 "pars0grm.cc"
break;
case 26:
-#line 190 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-1]), (yyvsp[0])); }
-#line 1707 "pars0grm.cc" /* yacc.c:1646 */
+#line 174 "pars0grm.y"
+ { yyval = pars_func(yyvsp[-3], yyvsp[-1]); }
+#line 1634 "pars0grm.cc"
break;
case 27:
-#line 194 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]);}
-#line 1713 "pars0grm.cc" /* yacc.c:1646 */
+#line 175 "pars0grm.y"
+ { yyval = yyvsp[0];}
+#line 1640 "pars0grm.cc"
break;
case 28:
-#line 196 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_func((yyvsp[-3]), (yyvsp[-1])); }
-#line 1719 "pars0grm.cc" /* yacc.c:1646 */
+#line 176 "pars0grm.y"
+ { yyval = yyvsp[0];}
+#line 1646 "pars0grm.cc"
break;
case 29:
-#line 197 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]);}
-#line 1725 "pars0grm.cc" /* yacc.c:1646 */
+#line 177 "pars0grm.y"
+ { yyval = yyvsp[0];}
+#line 1652 "pars0grm.cc"
break;
case 30:
-#line 198 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]);}
-#line 1731 "pars0grm.cc" /* yacc.c:1646 */
+#line 178 "pars0grm.y"
+ { yyval = yyvsp[0];}
+#line 1658 "pars0grm.cc"
break;
case 31:
-#line 199 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]);}
-#line 1737 "pars0grm.cc" /* yacc.c:1646 */
+#line 179 "pars0grm.y"
+ { yyval = yyvsp[0];}
+#line 1664 "pars0grm.cc"
break;
case 32:
-#line 200 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]);}
-#line 1743 "pars0grm.cc" /* yacc.c:1646 */
+#line 180 "pars0grm.y"
+ { yyval = pars_op('+', yyvsp[-2], yyvsp[0]); }
+#line 1670 "pars0grm.cc"
break;
case 33:
-#line 201 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]);}
-#line 1749 "pars0grm.cc" /* yacc.c:1646 */
+#line 181 "pars0grm.y"
+ { yyval = pars_op('-', yyvsp[-2], yyvsp[0]); }
+#line 1676 "pars0grm.cc"
break;
case 34:
-#line 202 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op('+', (yyvsp[-2]), (yyvsp[0])); }
-#line 1755 "pars0grm.cc" /* yacc.c:1646 */
+#line 182 "pars0grm.y"
+ { yyval = pars_op('*', yyvsp[-2], yyvsp[0]); }
+#line 1682 "pars0grm.cc"
break;
case 35:
-#line 203 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op('-', (yyvsp[-2]), (yyvsp[0])); }
-#line 1761 "pars0grm.cc" /* yacc.c:1646 */
+#line 183 "pars0grm.y"
+ { yyval = pars_op('/', yyvsp[-2], yyvsp[0]); }
+#line 1688 "pars0grm.cc"
break;
case 36:
-#line 204 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op('*', (yyvsp[-2]), (yyvsp[0])); }
-#line 1767 "pars0grm.cc" /* yacc.c:1646 */
+#line 184 "pars0grm.y"
+ { yyval = pars_op('-', yyvsp[0], NULL); }
+#line 1694 "pars0grm.cc"
break;
case 37:
-#line 205 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op('/', (yyvsp[-2]), (yyvsp[0])); }
-#line 1773 "pars0grm.cc" /* yacc.c:1646 */
+#line 185 "pars0grm.y"
+ { yyval = yyvsp[-1]; }
+#line 1700 "pars0grm.cc"
break;
case 38:
-#line 206 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op('-', (yyvsp[0]), NULL); }
-#line 1779 "pars0grm.cc" /* yacc.c:1646 */
+#line 186 "pars0grm.y"
+ { yyval = pars_op('=', yyvsp[-2], yyvsp[0]); }
+#line 1706 "pars0grm.cc"
break;
case 39:
-#line 207 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[-1]); }
-#line 1785 "pars0grm.cc" /* yacc.c:1646 */
+#line 188 "pars0grm.y"
+ { yyval = pars_op(PARS_LIKE_TOKEN, yyvsp[-2], yyvsp[0]); }
+#line 1712 "pars0grm.cc"
break;
case 40:
-#line 208 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op('=', (yyvsp[-2]), (yyvsp[0])); }
-#line 1791 "pars0grm.cc" /* yacc.c:1646 */
+#line 189 "pars0grm.y"
+ { yyval = pars_op('<', yyvsp[-2], yyvsp[0]); }
+#line 1718 "pars0grm.cc"
break;
case 41:
-#line 210 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_LIKE_TOKEN, (yyvsp[-2]), (yyvsp[0])); }
-#line 1797 "pars0grm.cc" /* yacc.c:1646 */
+#line 190 "pars0grm.y"
+ { yyval = pars_op('>', yyvsp[-2], yyvsp[0]); }
+#line 1724 "pars0grm.cc"
break;
case 42:
-#line 211 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op('<', (yyvsp[-2]), (yyvsp[0])); }
-#line 1803 "pars0grm.cc" /* yacc.c:1646 */
+#line 191 "pars0grm.y"
+ { yyval = pars_op(PARS_GE_TOKEN, yyvsp[-2], yyvsp[0]); }
+#line 1730 "pars0grm.cc"
break;
case 43:
-#line 212 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op('>', (yyvsp[-2]), (yyvsp[0])); }
-#line 1809 "pars0grm.cc" /* yacc.c:1646 */
+#line 192 "pars0grm.y"
+ { yyval = pars_op(PARS_LE_TOKEN, yyvsp[-2], yyvsp[0]); }
+#line 1736 "pars0grm.cc"
break;
case 44:
-#line 213 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_GE_TOKEN, (yyvsp[-2]), (yyvsp[0])); }
-#line 1815 "pars0grm.cc" /* yacc.c:1646 */
+#line 193 "pars0grm.y"
+ { yyval = pars_op(PARS_NE_TOKEN, yyvsp[-2], yyvsp[0]); }
+#line 1742 "pars0grm.cc"
break;
case 45:
-#line 214 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_LE_TOKEN, (yyvsp[-2]), (yyvsp[0])); }
-#line 1821 "pars0grm.cc" /* yacc.c:1646 */
+#line 194 "pars0grm.y"
+ { yyval = pars_op(PARS_AND_TOKEN, yyvsp[-2], yyvsp[0]); }
+#line 1748 "pars0grm.cc"
break;
case 46:
-#line 215 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_NE_TOKEN, (yyvsp[-2]), (yyvsp[0])); }
-#line 1827 "pars0grm.cc" /* yacc.c:1646 */
+#line 195 "pars0grm.y"
+ { yyval = pars_op(PARS_OR_TOKEN, yyvsp[-2], yyvsp[0]); }
+#line 1754 "pars0grm.cc"
break;
case 47:
-#line 216 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_AND_TOKEN, (yyvsp[-2]), (yyvsp[0])); }
-#line 1833 "pars0grm.cc" /* yacc.c:1646 */
+#line 196 "pars0grm.y"
+ { yyval = pars_op(PARS_NOT_TOKEN, yyvsp[0], NULL); }
+#line 1760 "pars0grm.cc"
break;
case 48:
-#line 217 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_OR_TOKEN, (yyvsp[-2]), (yyvsp[0])); }
-#line 1839 "pars0grm.cc" /* yacc.c:1646 */
+#line 198 "pars0grm.y"
+ { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); }
+#line 1766 "pars0grm.cc"
break;
case 49:
-#line 218 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_NOT_TOKEN, (yyvsp[0]), NULL); }
-#line 1845 "pars0grm.cc" /* yacc.c:1646 */
+#line 200 "pars0grm.y"
+ { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); }
+#line 1772 "pars0grm.cc"
break;
case 50:
-#line 220 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_NOTFOUND_TOKEN, (yyvsp[-2]), NULL); }
-#line 1851 "pars0grm.cc" /* yacc.c:1646 */
+#line 204 "pars0grm.y"
+ { yyval = &pars_to_binary_token; }
+#line 1778 "pars0grm.cc"
break;
case 51:
-#line 222 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_op(PARS_NOTFOUND_TOKEN, (yyvsp[-2]), NULL); }
-#line 1857 "pars0grm.cc" /* yacc.c:1646 */
+#line 205 "pars0grm.y"
+ { yyval = &pars_substr_token; }
+#line 1784 "pars0grm.cc"
break;
case 52:
-#line 226 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_to_char_token; }
-#line 1863 "pars0grm.cc" /* yacc.c:1646 */
+#line 206 "pars0grm.y"
+ { yyval = &pars_concat_token; }
+#line 1790 "pars0grm.cc"
break;
case 53:
-#line 227 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_to_number_token; }
-#line 1869 "pars0grm.cc" /* yacc.c:1646 */
+#line 207 "pars0grm.y"
+ { yyval = &pars_instr_token; }
+#line 1796 "pars0grm.cc"
break;
case 54:
-#line 228 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_to_binary_token; }
-#line 1875 "pars0grm.cc" /* yacc.c:1646 */
+#line 208 "pars0grm.y"
+ { yyval = &pars_length_token; }
+#line 1802 "pars0grm.cc"
break;
- case 55:
-#line 230 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_binary_to_number_token; }
-#line 1881 "pars0grm.cc" /* yacc.c:1646 */
+ case 58:
+#line 219 "pars0grm.y"
+ { yyval = pars_stored_procedure_call(
+ static_cast<sym_node_t*>(yyvsp[-4])); }
+#line 1809 "pars0grm.cc"
break;
- case 56:
-#line 231 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_substr_token; }
-#line 1887 "pars0grm.cc" /* yacc.c:1646 */
+ case 59:
+#line 224 "pars0grm.y"
+ { yyval = yyvsp[-2]; }
+#line 1815 "pars0grm.cc"
break;
- case 57:
-#line 232 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_concat_token; }
-#line 1893 "pars0grm.cc" /* yacc.c:1646 */
+ case 60:
+#line 228 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]); }
+#line 1821 "pars0grm.cc"
break;
- case 58:
-#line 233 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_instr_token; }
-#line 1899 "pars0grm.cc" /* yacc.c:1646 */
+ case 61:
+#line 230 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); }
+#line 1827 "pars0grm.cc"
break;
- case 59:
-#line 234 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_length_token; }
-#line 1905 "pars0grm.cc" /* yacc.c:1646 */
+ case 62:
+#line 234 "pars0grm.y"
+ { yyval = NULL; }
+#line 1833 "pars0grm.cc"
break;
- case 60:
-#line 235 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_sysdate_token; }
-#line 1911 "pars0grm.cc" /* yacc.c:1646 */
+ case 63:
+#line 235 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]); }
+#line 1839 "pars0grm.cc"
break;
- case 61:
-#line 236 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_rnd_token; }
-#line 1917 "pars0grm.cc" /* yacc.c:1646 */
+ case 64:
+#line 237 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); }
+#line 1845 "pars0grm.cc"
break;
- case 62:
-#line 237 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_rnd_str_token; }
-#line 1923 "pars0grm.cc" /* yacc.c:1646 */
+ case 65:
+#line 241 "pars0grm.y"
+ { yyval = NULL; }
+#line 1851 "pars0grm.cc"
break;
case 66:
-#line 248 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_stored_procedure_call(
- static_cast<sym_node_t*>((yyvsp[-4]))); }
-#line 1930 "pars0grm.cc" /* yacc.c:1646 */
+#line 242 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]);}
+#line 1857 "pars0grm.cc"
break;
case 67:
-#line 254 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_procedure_call((yyvsp[-3]), (yyvsp[-1])); }
-#line 1936 "pars0grm.cc" /* yacc.c:1646 */
+#line 243 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); }
+#line 1863 "pars0grm.cc"
break;
case 68:
-#line 258 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_replstr_token; }
-#line 1942 "pars0grm.cc" /* yacc.c:1646 */
+#line 247 "pars0grm.y"
+ { yyval = yyvsp[0]; }
+#line 1869 "pars0grm.cc"
break;
case 69:
-#line 259 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_printf_token; }
-#line 1948 "pars0grm.cc" /* yacc.c:1646 */
+#line 249 "pars0grm.y"
+ { yyval = pars_func(&pars_count_token,
+ que_node_list_add_last(NULL,
+ sym_tab_add_int_lit(
+ pars_sym_tab_global, 1))); }
+#line 1878 "pars0grm.cc"
break;
case 70:
-#line 260 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_assert_token; }
-#line 1954 "pars0grm.cc" /* yacc.c:1646 */
+#line 256 "pars0grm.y"
+ { yyval = NULL; }
+#line 1884 "pars0grm.cc"
break;
case 71:
-#line 264 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[-2]); }
-#line 1960 "pars0grm.cc" /* yacc.c:1646 */
+#line 257 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]); }
+#line 1890 "pars0grm.cc"
break;
case 72:
-#line 268 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 1966 "pars0grm.cc" /* yacc.c:1646 */
+#line 259 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); }
+#line 1896 "pars0grm.cc"
break;
case 73:
-#line 270 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); }
-#line 1972 "pars0grm.cc" /* yacc.c:1646 */
+#line 263 "pars0grm.y"
+ { yyval = pars_select_list(&pars_star_denoter,
+ NULL); }
+#line 1903 "pars0grm.cc"
break;
case 74:
-#line 274 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 1978 "pars0grm.cc" /* yacc.c:1646 */
+#line 266 "pars0grm.y"
+ { yyval = pars_select_list(
+ yyvsp[-2], static_cast<sym_node_t*>(yyvsp[0])); }
+#line 1910 "pars0grm.cc"
break;
case 75:
-#line 275 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 1984 "pars0grm.cc" /* yacc.c:1646 */
+#line 268 "pars0grm.y"
+ { yyval = pars_select_list(yyvsp[0], NULL); }
+#line 1916 "pars0grm.cc"
break;
case 76:
-#line 277 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); }
-#line 1990 "pars0grm.cc" /* yacc.c:1646 */
+#line 272 "pars0grm.y"
+ { yyval = NULL; }
+#line 1922 "pars0grm.cc"
break;
case 77:
-#line 281 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 1996 "pars0grm.cc" /* yacc.c:1646 */
+#line 273 "pars0grm.y"
+ { yyval = yyvsp[0]; }
+#line 1928 "pars0grm.cc"
break;
case 78:
-#line 282 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0]));}
-#line 2002 "pars0grm.cc" /* yacc.c:1646 */
+#line 277 "pars0grm.y"
+ { yyval = NULL; }
+#line 1934 "pars0grm.cc"
break;
case 79:
-#line 283 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); }
-#line 2008 "pars0grm.cc" /* yacc.c:1646 */
+#line 279 "pars0grm.y"
+ { yyval = &pars_update_token; }
+#line 1940 "pars0grm.cc"
break;
case 80:
-#line 287 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2014 "pars0grm.cc" /* yacc.c:1646 */
+#line 283 "pars0grm.y"
+ { yyval = NULL; }
+#line 1946 "pars0grm.cc"
break;
case 81:
-#line 289 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_func(&pars_count_token,
- que_node_list_add_last(NULL,
- sym_tab_add_int_lit(
- pars_sym_tab_global, 1))); }
-#line 2023 "pars0grm.cc" /* yacc.c:1646 */
+#line 285 "pars0grm.y"
+ { yyval = &pars_share_token; }
+#line 1952 "pars0grm.cc"
break;
case 82:
-#line 294 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_func(&pars_count_token,
- que_node_list_add_last(NULL,
- pars_func(&pars_distinct_token,
- que_node_list_add_last(
- NULL, (yyvsp[-1]))))); }
-#line 2033 "pars0grm.cc" /* yacc.c:1646 */
+#line 289 "pars0grm.y"
+ { yyval = &pars_asc_token; }
+#line 1958 "pars0grm.cc"
break;
case 83:
-#line 300 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_func(&pars_sum_token,
- que_node_list_add_last(NULL,
- (yyvsp[-1]))); }
-#line 2041 "pars0grm.cc" /* yacc.c:1646 */
+#line 290 "pars0grm.y"
+ { yyval = &pars_asc_token; }
+#line 1964 "pars0grm.cc"
break;
case 84:
-#line 306 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2047 "pars0grm.cc" /* yacc.c:1646 */
+#line 291 "pars0grm.y"
+ { yyval = &pars_desc_token; }
+#line 1970 "pars0grm.cc"
break;
case 85:
-#line 307 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 2053 "pars0grm.cc" /* yacc.c:1646 */
+#line 295 "pars0grm.y"
+ { yyval = NULL; }
+#line 1976 "pars0grm.cc"
break;
case 86:
-#line 309 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); }
-#line 2059 "pars0grm.cc" /* yacc.c:1646 */
+#line 297 "pars0grm.y"
+ { yyval = pars_order_by(
+ static_cast<sym_node_t*>(yyvsp[-1]),
+ static_cast<pars_res_word_t*>(yyvsp[0])); }
+#line 1984 "pars0grm.cc"
break;
case 87:
-#line 313 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_select_list(&pars_star_denoter,
- NULL); }
-#line 2066 "pars0grm.cc" /* yacc.c:1646 */
+#line 308 "pars0grm.y"
+ { yyval = pars_select_statement(
+ static_cast<sel_node_t*>(yyvsp[-6]),
+ static_cast<sym_node_t*>(yyvsp[-4]),
+ static_cast<que_node_t*>(yyvsp[-3]),
+ static_cast<pars_res_word_t*>(yyvsp[-2]),
+ static_cast<pars_res_word_t*>(yyvsp[-1]),
+ static_cast<order_node_t*>(yyvsp[0])); }
+#line 1996 "pars0grm.cc"
break;
case 88:
-#line 316 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_select_list(
- (yyvsp[-2]), static_cast<sym_node_t*>((yyvsp[0]))); }
-#line 2073 "pars0grm.cc" /* yacc.c:1646 */
+#line 319 "pars0grm.y"
+ { yyval = yyvsp[0]; }
+#line 2002 "pars0grm.cc"
break;
case 89:
-#line 318 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_select_list((yyvsp[0]), NULL); }
-#line 2079 "pars0grm.cc" /* yacc.c:1646 */
+#line 324 "pars0grm.y"
+ { yyval = pars_insert_statement(
+ static_cast<sym_node_t*>(yyvsp[-4]), yyvsp[-1], NULL); }
+#line 2009 "pars0grm.cc"
break;
case 90:
-#line 322 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2085 "pars0grm.cc" /* yacc.c:1646 */
+#line 327 "pars0grm.y"
+ { yyval = pars_insert_statement(
+ static_cast<sym_node_t*>(yyvsp[-1]),
+ NULL,
+ static_cast<sel_node_t*>(yyvsp[0])); }
+#line 2018 "pars0grm.cc"
break;
case 91:
-#line 323 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2091 "pars0grm.cc" /* yacc.c:1646 */
+#line 334 "pars0grm.y"
+ { yyval = pars_column_assignment(
+ static_cast<sym_node_t*>(yyvsp[-2]),
+ static_cast<que_node_t*>(yyvsp[0])); }
+#line 2026 "pars0grm.cc"
break;
case 92:
-#line 327 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2097 "pars0grm.cc" /* yacc.c:1646 */
+#line 340 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]); }
+#line 2032 "pars0grm.cc"
break;
case 93:
-#line 329 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_update_token; }
-#line 2103 "pars0grm.cc" /* yacc.c:1646 */
+#line 342 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); }
+#line 2038 "pars0grm.cc"
break;
case 94:
-#line 333 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2109 "pars0grm.cc" /* yacc.c:1646 */
+#line 348 "pars0grm.y"
+ { yyval = yyvsp[0]; }
+#line 2044 "pars0grm.cc"
break;
case 95:
-#line 335 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_share_token; }
-#line 2115 "pars0grm.cc" /* yacc.c:1646 */
+#line 354 "pars0grm.y"
+ { yyval = pars_update_statement_start(
+ FALSE,
+ static_cast<sym_node_t*>(yyvsp[-2]),
+ static_cast<col_assign_node_t*>(yyvsp[0])); }
+#line 2053 "pars0grm.cc"
break;
case 96:
-#line 339 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_asc_token; }
-#line 2121 "pars0grm.cc" /* yacc.c:1646 */
+#line 362 "pars0grm.y"
+ { yyval = pars_update_statement(
+ static_cast<upd_node_t*>(yyvsp[-1]),
+ NULL,
+ static_cast<que_node_t*>(yyvsp[0])); }
+#line 2062 "pars0grm.cc"
break;
case 97:
-#line 340 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_asc_token; }
-#line 2127 "pars0grm.cc" /* yacc.c:1646 */
+#line 370 "pars0grm.y"
+ { yyval = pars_update_statement(
+ static_cast<upd_node_t*>(yyvsp[-1]),
+ static_cast<sym_node_t*>(yyvsp[0]),
+ NULL); }
+#line 2071 "pars0grm.cc"
break;
case 98:
-#line 341 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_desc_token; }
-#line 2133 "pars0grm.cc" /* yacc.c:1646 */
+#line 378 "pars0grm.y"
+ { yyval = pars_update_statement_start(
+ TRUE,
+ static_cast<sym_node_t*>(yyvsp[0]), NULL); }
+#line 2079 "pars0grm.cc"
break;
case 99:
-#line 345 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2139 "pars0grm.cc" /* yacc.c:1646 */
+#line 385 "pars0grm.y"
+ { yyval = pars_update_statement(
+ static_cast<upd_node_t*>(yyvsp[-1]),
+ NULL,
+ static_cast<que_node_t*>(yyvsp[0])); }
+#line 2088 "pars0grm.cc"
break;
case 100:
-#line 347 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_order_by(
- static_cast<sym_node_t*>((yyvsp[-1])),
- static_cast<pars_res_word_t*>((yyvsp[0]))); }
-#line 2147 "pars0grm.cc" /* yacc.c:1646 */
+#line 393 "pars0grm.y"
+ { yyval = pars_update_statement(
+ static_cast<upd_node_t*>(yyvsp[-1]),
+ static_cast<sym_node_t*>(yyvsp[0]),
+ NULL); }
+#line 2097 "pars0grm.cc"
break;
case 101:
-#line 358 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_select_statement(
- static_cast<sel_node_t*>((yyvsp[-6])),
- static_cast<sym_node_t*>((yyvsp[-4])),
- static_cast<que_node_t*>((yyvsp[-3])),
- static_cast<pars_res_word_t*>((yyvsp[-2])),
- static_cast<pars_res_word_t*>((yyvsp[-1])),
- static_cast<order_node_t*>((yyvsp[0]))); }
-#line 2159 "pars0grm.cc" /* yacc.c:1646 */
+#line 401 "pars0grm.y"
+ { yyval = pars_assignment_statement(
+ static_cast<sym_node_t*>(yyvsp[-2]),
+ static_cast<que_node_t*>(yyvsp[0])); }
+#line 2105 "pars0grm.cc"
break;
case 102:
-#line 369 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2165 "pars0grm.cc" /* yacc.c:1646 */
+#line 409 "pars0grm.y"
+ { yyval = pars_elsif_element(yyvsp[-2], yyvsp[0]); }
+#line 2111 "pars0grm.cc"
break;
case 103:
-#line 374 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_insert_statement(
- static_cast<sym_node_t*>((yyvsp[-4])), (yyvsp[-1]), NULL); }
-#line 2172 "pars0grm.cc" /* yacc.c:1646 */
+#line 413 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]); }
+#line 2117 "pars0grm.cc"
break;
case 104:
-#line 377 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_insert_statement(
- static_cast<sym_node_t*>((yyvsp[-1])),
- NULL,
- static_cast<sel_node_t*>((yyvsp[0]))); }
-#line 2181 "pars0grm.cc" /* yacc.c:1646 */
+#line 415 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); }
+#line 2123 "pars0grm.cc"
break;
case 105:
-#line 384 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_column_assignment(
- static_cast<sym_node_t*>((yyvsp[-2])),
- static_cast<que_node_t*>((yyvsp[0]))); }
-#line 2189 "pars0grm.cc" /* yacc.c:1646 */
+#line 419 "pars0grm.y"
+ { yyval = NULL; }
+#line 2129 "pars0grm.cc"
break;
case 106:
-#line 390 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 2195 "pars0grm.cc" /* yacc.c:1646 */
+#line 421 "pars0grm.y"
+ { yyval = yyvsp[0]; }
+#line 2135 "pars0grm.cc"
break;
case 107:
-#line 392 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); }
-#line 2201 "pars0grm.cc" /* yacc.c:1646 */
+#line 422 "pars0grm.y"
+ { yyval = yyvsp[0]; }
+#line 2141 "pars0grm.cc"
break;
case 108:
-#line 398 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2207 "pars0grm.cc" /* yacc.c:1646 */
+#line 429 "pars0grm.y"
+ { yyval = pars_if_statement(yyvsp[-5], yyvsp[-3], yyvsp[-2]); }
+#line 2147 "pars0grm.cc"
break;
case 109:
-#line 404 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_update_statement_start(
- FALSE,
- static_cast<sym_node_t*>((yyvsp[-2])),
- static_cast<col_assign_node_t*>((yyvsp[0]))); }
-#line 2216 "pars0grm.cc" /* yacc.c:1646 */
+#line 435 "pars0grm.y"
+ { yyval = pars_while_statement(yyvsp[-4], yyvsp[-2]); }
+#line 2153 "pars0grm.cc"
break;
case 110:
-#line 412 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_update_statement(
- static_cast<upd_node_t*>((yyvsp[-1])),
- NULL,
- static_cast<que_node_t*>((yyvsp[0]))); }
-#line 2225 "pars0grm.cc" /* yacc.c:1646 */
+#line 443 "pars0grm.y"
+ { yyval = pars_for_statement(
+ static_cast<sym_node_t*>(yyvsp[-8]),
+ yyvsp[-6], yyvsp[-4], yyvsp[-2]); }
+#line 2161 "pars0grm.cc"
break;
case 111:
-#line 420 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_update_statement(
- static_cast<upd_node_t*>((yyvsp[-1])),
- static_cast<sym_node_t*>((yyvsp[0])),
- NULL); }
-#line 2234 "pars0grm.cc" /* yacc.c:1646 */
+#line 449 "pars0grm.y"
+ { yyval = pars_exit_statement(); }
+#line 2167 "pars0grm.cc"
break;
case 112:
-#line 428 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_update_statement_start(
- TRUE,
- static_cast<sym_node_t*>((yyvsp[0])), NULL); }
-#line 2242 "pars0grm.cc" /* yacc.c:1646 */
+#line 453 "pars0grm.y"
+ { yyval = pars_return_statement(); }
+#line 2173 "pars0grm.cc"
break;
case 113:
-#line 435 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_update_statement(
- static_cast<upd_node_t*>((yyvsp[-1])),
- NULL,
- static_cast<que_node_t*>((yyvsp[0]))); }
-#line 2251 "pars0grm.cc" /* yacc.c:1646 */
+#line 458 "pars0grm.y"
+ { yyval = pars_open_statement(
+ ROW_SEL_OPEN_CURSOR,
+ static_cast<sym_node_t*>(yyvsp[0])); }
+#line 2181 "pars0grm.cc"
break;
case 114:
-#line 443 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_update_statement(
- static_cast<upd_node_t*>((yyvsp[-1])),
- static_cast<sym_node_t*>((yyvsp[0])),
- NULL); }
-#line 2260 "pars0grm.cc" /* yacc.c:1646 */
+#line 465 "pars0grm.y"
+ { yyval = pars_open_statement(
+ ROW_SEL_CLOSE_CURSOR,
+ static_cast<sym_node_t*>(yyvsp[0])); }
+#line 2189 "pars0grm.cc"
break;
case 115:
-#line 451 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_row_printf_statement(
- static_cast<sel_node_t*>((yyvsp[0]))); }
-#line 2267 "pars0grm.cc" /* yacc.c:1646 */
+#line 472 "pars0grm.y"
+ { yyval = pars_fetch_statement(
+ static_cast<sym_node_t*>(yyvsp[-2]),
+ static_cast<sym_node_t*>(yyvsp[0]), NULL); }
+#line 2197 "pars0grm.cc"
break;
case 116:
-#line 457 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_assignment_statement(
- static_cast<sym_node_t*>((yyvsp[-2])),
- static_cast<que_node_t*>((yyvsp[0]))); }
-#line 2275 "pars0grm.cc" /* yacc.c:1646 */
+#line 476 "pars0grm.y"
+ { yyval = pars_fetch_statement(
+ static_cast<sym_node_t*>(yyvsp[-2]),
+ NULL,
+ static_cast<sym_node_t*>(yyvsp[0])); }
+#line 2206 "pars0grm.cc"
break;
case 117:
-#line 465 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_elsif_element((yyvsp[-2]), (yyvsp[0])); }
-#line 2281 "pars0grm.cc" /* yacc.c:1646 */
+#line 484 "pars0grm.y"
+ { yyval = pars_column_def(
+ static_cast<sym_node_t*>(yyvsp[-3]),
+ static_cast<pars_res_word_t*>(yyvsp[-2]),
+ static_cast<sym_node_t*>(yyvsp[-1]),
+ yyvsp[0]); }
+#line 2216 "pars0grm.cc"
break;
case 118:
-#line 469 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 2287 "pars0grm.cc" /* yacc.c:1646 */
+#line 492 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]); }
+#line 2222 "pars0grm.cc"
break;
case 119:
-#line 471 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-1]), (yyvsp[0])); }
-#line 2293 "pars0grm.cc" /* yacc.c:1646 */
+#line 494 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); }
+#line 2228 "pars0grm.cc"
break;
case 120:
-#line 475 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2299 "pars0grm.cc" /* yacc.c:1646 */
+#line 498 "pars0grm.y"
+ { yyval = NULL; }
+#line 2234 "pars0grm.cc"
break;
case 121:
-#line 477 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2305 "pars0grm.cc" /* yacc.c:1646 */
+#line 500 "pars0grm.y"
+ { yyval = yyvsp[-1]; }
+#line 2240 "pars0grm.cc"
break;
case 122:
-#line 478 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2311 "pars0grm.cc" /* yacc.c:1646 */
+#line 504 "pars0grm.y"
+ { yyval = NULL; }
+#line 2246 "pars0grm.cc"
break;
case 123:
-#line 485 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_if_statement((yyvsp[-5]), (yyvsp[-3]), (yyvsp[-2])); }
-#line 2317 "pars0grm.cc" /* yacc.c:1646 */
+#line 506 "pars0grm.y"
+ { yyval = &pars_int_token;
+ /* pass any non-NULL pointer */ }
+#line 2253 "pars0grm.cc"
break;
case 124:
-#line 491 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_while_statement((yyvsp[-4]), (yyvsp[-2])); }
-#line 2323 "pars0grm.cc" /* yacc.c:1646 */
+#line 513 "pars0grm.y"
+ { yyval = pars_create_table(
+ static_cast<sym_node_t*>(yyvsp[-3]),
+ static_cast<sym_node_t*>(yyvsp[-1])); }
+#line 2261 "pars0grm.cc"
break;
case 125:
-#line 499 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_for_statement(
- static_cast<sym_node_t*>((yyvsp[-8])),
- (yyvsp[-6]), (yyvsp[-4]), (yyvsp[-2])); }
-#line 2331 "pars0grm.cc" /* yacc.c:1646 */
+#line 519 "pars0grm.y"
+ { yyval = que_node_list_add_last(NULL, yyvsp[0]); }
+#line 2267 "pars0grm.cc"
break;
case 126:
-#line 505 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_exit_statement(); }
-#line 2337 "pars0grm.cc" /* yacc.c:1646 */
+#line 521 "pars0grm.y"
+ { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); }
+#line 2273 "pars0grm.cc"
break;
case 127:
-#line 509 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_return_statement(); }
-#line 2343 "pars0grm.cc" /* yacc.c:1646 */
+#line 525 "pars0grm.y"
+ { yyval = NULL; }
+#line 2279 "pars0grm.cc"
break;
case 128:
-#line 514 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_open_statement(
- ROW_SEL_OPEN_CURSOR,
- static_cast<sym_node_t*>((yyvsp[0]))); }
-#line 2351 "pars0grm.cc" /* yacc.c:1646 */
+#line 526 "pars0grm.y"
+ { yyval = &pars_unique_token; }
+#line 2285 "pars0grm.cc"
break;
case 129:
-#line 521 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_open_statement(
- ROW_SEL_CLOSE_CURSOR,
- static_cast<sym_node_t*>((yyvsp[0]))); }
-#line 2359 "pars0grm.cc" /* yacc.c:1646 */
+#line 530 "pars0grm.y"
+ { yyval = NULL; }
+#line 2291 "pars0grm.cc"
break;
case 130:
-#line 528 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_fetch_statement(
- static_cast<sym_node_t*>((yyvsp[-2])),
- static_cast<sym_node_t*>((yyvsp[0])), NULL); }
-#line 2367 "pars0grm.cc" /* yacc.c:1646 */
+#line 531 "pars0grm.y"
+ { yyval = &pars_clustered_token; }
+#line 2297 "pars0grm.cc"
break;
case 131:
-#line 532 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_fetch_statement(
- static_cast<sym_node_t*>((yyvsp[-2])),
- NULL,
- static_cast<sym_node_t*>((yyvsp[0]))); }
-#line 2376 "pars0grm.cc" /* yacc.c:1646 */
+#line 540 "pars0grm.y"
+ { yyval = pars_create_index(
+ static_cast<pars_res_word_t*>(yyvsp[-8]),
+ static_cast<pars_res_word_t*>(yyvsp[-7]),
+ static_cast<sym_node_t*>(yyvsp[-5]),
+ static_cast<sym_node_t*>(yyvsp[-3]),
+ static_cast<sym_node_t*>(yyvsp[-1])); }
+#line 2308 "pars0grm.cc"
break;
case 132:
-#line 540 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_column_def(
- static_cast<sym_node_t*>((yyvsp[-4])),
- static_cast<pars_res_word_t*>((yyvsp[-3])),
- static_cast<sym_node_t*>((yyvsp[-2])),
- (yyvsp[-1]), (yyvsp[0])); }
-#line 2386 "pars0grm.cc" /* yacc.c:1646 */
+#line 549 "pars0grm.y"
+ { yyval = yyvsp[0]; }
+#line 2314 "pars0grm.cc"
break;
case 133:
-#line 548 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 2392 "pars0grm.cc" /* yacc.c:1646 */
+#line 550 "pars0grm.y"
+ { yyval = yyvsp[0]; }
+#line 2320 "pars0grm.cc"
break;
case 134:
-#line 550 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); }
-#line 2398 "pars0grm.cc" /* yacc.c:1646 */
+#line 555 "pars0grm.y"
+ { yyval = pars_commit_statement(); }
+#line 2326 "pars0grm.cc"
break;
case 135:
-#line 554 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2404 "pars0grm.cc" /* yacc.c:1646 */
+#line 560 "pars0grm.y"
+ { yyval = pars_rollback_statement(); }
+#line 2332 "pars0grm.cc"
break;
case 136:
-#line 556 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[-1]); }
-#line 2410 "pars0grm.cc" /* yacc.c:1646 */
+#line 564 "pars0grm.y"
+ { yyval = &pars_int_token; }
+#line 2338 "pars0grm.cc"
break;
case 137:
-#line 560 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2416 "pars0grm.cc" /* yacc.c:1646 */
+#line 565 "pars0grm.y"
+ { yyval = &pars_bigint_token; }
+#line 2344 "pars0grm.cc"
break;
case 138:
-#line 562 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_int_token;
- /* pass any non-NULL pointer */ }
-#line 2423 "pars0grm.cc" /* yacc.c:1646 */
+#line 566 "pars0grm.y"
+ { yyval = &pars_char_token; }
+#line 2350 "pars0grm.cc"
break;
case 139:
-#line 567 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2429 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 140:
-#line 569 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_int_token;
- /* pass any non-NULL pointer */ }
-#line 2436 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 141:
-#line 574 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2442 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 142:
-#line 575 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_int_token;
- /* pass any non-NULL pointer */ }
-#line 2449 "pars0grm.cc" /* yacc.c:1646 */
+#line 571 "pars0grm.y"
+ { yyval = pars_variable_declaration(
+ static_cast<sym_node_t*>(yyvsp[-2]),
+ static_cast<pars_res_word_t*>(yyvsp[-1])); }
+#line 2358 "pars0grm.cc"
break;
case 143:
-#line 580 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2455 "pars0grm.cc" /* yacc.c:1646 */
+#line 585 "pars0grm.y"
+ { yyval = pars_cursor_declaration(
+ static_cast<sym_node_t*>(yyvsp[-3]),
+ static_cast<sel_node_t*>(yyvsp[-1])); }
+#line 2366 "pars0grm.cc"
break;
case 144:
-#line 582 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2461 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 145:
-#line 589 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_create_table(
- static_cast<sym_node_t*>((yyvsp[-5])),
- static_cast<sym_node_t*>((yyvsp[-3])),
- static_cast<sym_node_t*>((yyvsp[-1])),
- static_cast<sym_node_t*>((yyvsp[0]))); }
-#line 2471 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 146:
-#line 597 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 2477 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 147:
-#line 599 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); }
-#line 2483 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 148:
-#line 603 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2489 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 149:
-#line 604 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_unique_token; }
-#line 2495 "pars0grm.cc" /* yacc.c:1646 */
+#line 592 "pars0grm.y"
+ { yyval = pars_function_declaration(
+ static_cast<sym_node_t*>(yyvsp[-1])); }
+#line 2373 "pars0grm.cc"
break;
case 150:
-#line 608 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2501 "pars0grm.cc" /* yacc.c:1646 */
+#line 614 "pars0grm.y"
+ { yyval = pars_procedure_definition(
+ static_cast<sym_node_t*>(yyvsp[-8]), yyvsp[-1]); }
+#line 2380 "pars0grm.cc"
break;
- case 151:
-#line 609 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_clustered_token; }
-#line 2507 "pars0grm.cc" /* yacc.c:1646 */
- break;
- case 152:
-#line 618 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_create_index(
- static_cast<pars_res_word_t*>((yyvsp[-8])),
- static_cast<pars_res_word_t*>((yyvsp[-7])),
- static_cast<sym_node_t*>((yyvsp[-5])),
- static_cast<sym_node_t*>((yyvsp[-3])),
- static_cast<sym_node_t*>((yyvsp[-1]))); }
-#line 2518 "pars0grm.cc" /* yacc.c:1646 */
- break;
+#line 2384 "pars0grm.cc"
- case 153:
-#line 627 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2524 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 154:
-#line 628 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = (yyvsp[0]); }
-#line 2530 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 155:
-#line 633 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_commit_statement(); }
-#line 2536 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 156:
-#line 638 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_rollback_statement(); }
-#line 2542 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 157:
-#line 642 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_int_token; }
-#line 2548 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 158:
-#line 643 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_bigint_token; }
-#line 2554 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 159:
-#line 644 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_char_token; }
-#line 2560 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 160:
-#line 645 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_binary_token; }
-#line 2566 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 161:
-#line 646 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = &pars_blob_token; }
-#line 2572 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 162:
-#line 651 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_parameter_declaration(
- static_cast<sym_node_t*>((yyvsp[-2])),
- PARS_INPUT,
- static_cast<pars_res_word_t*>((yyvsp[0]))); }
-#line 2581 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 163:
-#line 656 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_parameter_declaration(
- static_cast<sym_node_t*>((yyvsp[-2])),
- PARS_OUTPUT,
- static_cast<pars_res_word_t*>((yyvsp[0]))); }
-#line 2590 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 164:
-#line 663 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = NULL; }
-#line 2596 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 165:
-#line 664 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); }
-#line 2602 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 166:
-#line 666 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); }
-#line 2608 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 167:
-#line 671 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_variable_declaration(
- static_cast<sym_node_t*>((yyvsp[-2])),
- static_cast<pars_res_word_t*>((yyvsp[-1]))); }
-#line 2616 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 171:
-#line 685 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_cursor_declaration(
- static_cast<sym_node_t*>((yyvsp[-3])),
- static_cast<sel_node_t*>((yyvsp[-1]))); }
-#line 2624 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 172:
-#line 692 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_function_declaration(
- static_cast<sym_node_t*>((yyvsp[-1]))); }
-#line 2631 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
- case 178:
-#line 714 "pars0grm.y" /* yacc.c:1646 */
- { (yyval) = pars_procedure_definition(
- static_cast<sym_node_t*>((yyvsp[-9])),
- static_cast<sym_node_t*>((yyvsp[-7])),
- (yyvsp[-1])); }
-#line 2640 "pars0grm.cc" /* yacc.c:1646 */
- break;
-
-
-#line 2644 "pars0grm.cc" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -2665,14 +2406,13 @@ yyreduce:
/* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
goto yynewstate;
@@ -2755,12 +2495,10 @@ yyerrlab:
| yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -2822,6 +2560,7 @@ yyacceptlab:
yyresult = 0;
goto yyreturn;
+
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
@@ -2829,6 +2568,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
+
#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
@@ -2839,6 +2579,10 @@ yyexhaustedlab:
/* Fall through. */
#endif
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result. |
+`-----------------------------------------------------*/
yyreturn:
if (yychar != YYEMPTY)
{
@@ -2868,5 +2612,5 @@ yyreturn:
#endif
return yyresult;
}
-#line 720 "pars0grm.y" /* yacc.c:1906 */
+#line 618 "pars0grm.y"
diff --git a/storage/innobase/pars/pars0grm.y b/storage/innobase/pars/pars0grm.y
index 27638e06a66..625ed41bbd4 100644
--- a/storage/innobase/pars/pars0grm.y
+++ b/storage/innobase/pars/pars0grm.y
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -58,11 +58,7 @@ yylex(void);
%token PARS_NE_TOKEN
%token PARS_PROCEDURE_TOKEN
%token PARS_IN_TOKEN
-%token PARS_OUT_TOKEN
-%token PARS_BINARY_TOKEN
-%token PARS_BLOB_TOKEN
%token PARS_INT_TOKEN
-%token PARS_FLOAT_TOKEN
%token PARS_CHAR_TOKEN
%token PARS_IS_TOKEN
%token PARS_BEGIN_TOKEN
@@ -75,14 +71,11 @@ yylex(void);
%token PARS_WHILE_TOKEN
%token PARS_RETURN_TOKEN
%token PARS_SELECT_TOKEN
-%token PARS_SUM_TOKEN
%token PARS_COUNT_TOKEN
-%token PARS_DISTINCT_TOKEN
%token PARS_FROM_TOKEN
%token PARS_WHERE_TOKEN
%token PARS_FOR_TOKEN
%token PARS_DDOT_TOKEN
-%token PARS_READ_TOKEN
%token PARS_ORDER_TOKEN
%token PARS_BY_TOKEN
%token PARS_ASC_TOKEN
@@ -109,25 +102,14 @@ yylex(void);
%token PARS_FETCH_TOKEN
%token PARS_CLOSE_TOKEN
%token PARS_NOTFOUND_TOKEN
-%token PARS_TO_CHAR_TOKEN
-%token PARS_TO_NUMBER_TOKEN
%token PARS_TO_BINARY_TOKEN
-%token PARS_BINARY_TO_NUMBER_TOKEN
%token PARS_SUBSTR_TOKEN
-%token PARS_REPLSTR_TOKEN
%token PARS_CONCAT_TOKEN
%token PARS_INSTR_TOKEN
%token PARS_LENGTH_TOKEN
-%token PARS_SYSDATE_TOKEN
-%token PARS_PRINTF_TOKEN
-%token PARS_ASSERT_TOKEN
-%token PARS_RND_TOKEN
-%token PARS_RND_STR_TOKEN
-%token PARS_ROW_PRINTF_TOKEN
%token PARS_COMMIT_TOKEN
%token PARS_ROLLBACK_TOKEN
%token PARS_WORK_TOKEN
-%token PARS_UNSIGNED_TOKEN
%token PARS_EXIT_TOKEN
%token PARS_FUNCTION_TOKEN
%token PARS_LOCK_TOKEN
@@ -139,8 +121,6 @@ yylex(void);
%token PARS_LIKE_TOKEN_SUFFIX
%token PARS_LIKE_TOKEN_SUBSTR
%token PARS_TABLE_NAME_TOKEN
-%token PARS_COMPACT_TOKEN
-%token PARS_BLOCK_SIZE_TOKEN
%token PARS_BIGINT_TOKEN
%left PARS_AND_TOKEN PARS_OR_TOKEN
@@ -161,7 +141,6 @@ top_statement:
statement:
stored_procedure_call
- | predefined_procedure_call ';'
| while_statement ';'
| for_statement ';'
| exit_statement ';'
@@ -170,7 +149,6 @@ statement:
| assignment_statement ';'
| select_statement ';'
| insert_statement ';'
- | row_printf_statement ';'
| delete_statement_searched ';'
| delete_statement_positioned ';'
| update_statement_searched ';'
@@ -223,18 +201,11 @@ exp:
;
function_name:
- PARS_TO_CHAR_TOKEN { $$ = &pars_to_char_token; }
- | PARS_TO_NUMBER_TOKEN { $$ = &pars_to_number_token; }
- | PARS_TO_BINARY_TOKEN { $$ = &pars_to_binary_token; }
- | PARS_BINARY_TO_NUMBER_TOKEN
- { $$ = &pars_binary_to_number_token; }
+ PARS_TO_BINARY_TOKEN { $$ = &pars_to_binary_token; }
| PARS_SUBSTR_TOKEN { $$ = &pars_substr_token; }
| PARS_CONCAT_TOKEN { $$ = &pars_concat_token; }
| PARS_INSTR_TOKEN { $$ = &pars_instr_token; }
| PARS_LENGTH_TOKEN { $$ = &pars_length_token; }
- | PARS_SYSDATE_TOKEN { $$ = &pars_sysdate_token; }
- | PARS_RND_TOKEN { $$ = &pars_rnd_token; }
- | PARS_RND_STR_TOKEN { $$ = &pars_rnd_str_token; }
;
question_mark_list:
@@ -249,17 +220,6 @@ stored_procedure_call:
static_cast<sym_node_t*>($2)); }
;
-predefined_procedure_call:
- predefined_procedure_name '(' exp_list ')'
- { $$ = pars_procedure_call($1, $3); }
-;
-
-predefined_procedure_name:
- PARS_REPLSTR_TOKEN { $$ = &pars_replstr_token; }
- | PARS_PRINTF_TOKEN { $$ = &pars_printf_token; }
- | PARS_ASSERT_TOKEN { $$ = &pars_assert_token; }
-;
-
user_function_call:
PARS_ID_TOKEN '(' ')' { $$ = $1; }
;
@@ -287,19 +247,9 @@ select_item:
exp { $$ = $1; }
| PARS_COUNT_TOKEN '(' '*' ')'
{ $$ = pars_func(&pars_count_token,
- que_node_list_add_last(NULL,
+ que_node_list_add_last(NULL,
sym_tab_add_int_lit(
pars_sym_tab_global, 1))); }
- | PARS_COUNT_TOKEN '(' PARS_DISTINCT_TOKEN PARS_ID_TOKEN ')'
- { $$ = pars_func(&pars_count_token,
- que_node_list_add_last(NULL,
- pars_func(&pars_distinct_token,
- que_node_list_add_last(
- NULL, $4)))); }
- | PARS_SUM_TOKEN '(' exp ')'
- { $$ = pars_func(&pars_sum_token,
- que_node_list_add_last(NULL,
- $3)); }
;
select_item_list:
@@ -446,12 +396,6 @@ delete_statement_positioned:
NULL); }
;
-row_printf_statement:
- PARS_ROW_PRINTF_TOKEN select_statement
- { $$ = pars_row_printf_statement(
- static_cast<sel_node_t*>($2)); }
-;
-
assignment_statement:
PARS_ID_TOKEN PARS_ASSIGN_TOKEN exp
{ $$ = pars_assignment_statement(
@@ -536,12 +480,12 @@ fetch_statement:
;
column_def:
- PARS_ID_TOKEN type_name opt_column_len opt_unsigned opt_not_null
+ PARS_ID_TOKEN type_name opt_column_len opt_not_null
{ $$ = pars_column_def(
static_cast<sym_node_t*>($1),
static_cast<pars_res_word_t*>($2),
static_cast<sym_node_t*>($3),
- $4, $5); }
+ $4); }
;
column_def_list:
@@ -556,13 +500,6 @@ opt_column_len:
{ $$ = $2; }
;
-opt_unsigned:
- /* Nothing */ { $$ = NULL; }
- | PARS_UNSIGNED_TOKEN
- { $$ = &pars_int_token;
- /* pass any non-NULL pointer */ }
-;
-
opt_not_null:
/* Nothing */ { $$ = NULL; }
| PARS_NOT_TOKEN PARS_NULL_LIT
@@ -570,27 +507,12 @@ opt_not_null:
/* pass any non-NULL pointer */ }
;
-compact:
- /* Nothing */ { $$ = NULL; }
- | PARS_COMPACT_TOKEN { $$ = &pars_int_token;
- /* pass any non-NULL pointer */ }
-;
-
-block_size:
- /* Nothing */ { $$ = NULL; }
- | PARS_BLOCK_SIZE_TOKEN '=' PARS_INT_LIT
- { $$ = $3; }
-;
-
create_table:
PARS_CREATE_TOKEN PARS_TABLE_TOKEN
table_name '(' column_def_list ')'
- compact block_size
{ $$ = pars_create_table(
static_cast<sym_node_t*>($3),
- static_cast<sym_node_t*>($5),
- static_cast<sym_node_t*>($7),
- static_cast<sym_node_t*>($8)); }
+ static_cast<sym_node_t*>($5)); }
;
column_list:
@@ -642,28 +564,6 @@ type_name:
PARS_INT_TOKEN { $$ = &pars_int_token; }
| PARS_BIGINT_TOKEN { $$ = &pars_bigint_token; }
| PARS_CHAR_TOKEN { $$ = &pars_char_token; }
- | PARS_BINARY_TOKEN { $$ = &pars_binary_token; }
- | PARS_BLOB_TOKEN { $$ = &pars_blob_token; }
-;
-
-parameter_declaration:
- PARS_ID_TOKEN PARS_IN_TOKEN type_name
- { $$ = pars_parameter_declaration(
- static_cast<sym_node_t*>($1),
- PARS_INPUT,
- static_cast<pars_res_word_t*>($3)); }
- | PARS_ID_TOKEN PARS_OUT_TOKEN type_name
- { $$ = pars_parameter_declaration(
- static_cast<sym_node_t*>($1),
- PARS_OUTPUT,
- static_cast<pars_res_word_t*>($3)); }
-;
-
-parameter_declaration_list:
- /* Nothing */ { $$ = NULL; }
- | parameter_declaration { $$ = que_node_list_add_last(NULL, $1); }
- | parameter_declaration_list ',' parameter_declaration
- { $$ = que_node_list_add_last($1, $3); }
;
variable_declaration:
@@ -705,16 +605,14 @@ declaration_list:
;
procedure_definition:
- PARS_PROCEDURE_TOKEN PARS_ID_TOKEN '(' parameter_declaration_list ')'
+ PARS_PROCEDURE_TOKEN PARS_ID_TOKEN '(' ')'
PARS_IS_TOKEN
variable_declaration_list
declaration_list
PARS_BEGIN_TOKEN
statement_list
PARS_END_TOKEN { $$ = pars_procedure_definition(
- static_cast<sym_node_t*>($2),
- static_cast<sym_node_t*>($4),
- $10); }
+ static_cast<sym_node_t*>($2), $9); }
;
%%
diff --git a/storage/innobase/pars/pars0lex.l b/storage/innobase/pars/pars0lex.l
index 2d0e56f400d..8b2df6b7940 100644
--- a/storage/innobase/pars/pars0lex.l
+++ b/storage/innobase/pars/pars0lex.l
@@ -249,30 +249,10 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_IN_TOKEN);
}
-"OUT" {
- return(PARS_OUT_TOKEN);
-}
-
-"BINARY" {
- return(PARS_BINARY_TOKEN);
-}
-
-"BLOB" {
- return(PARS_BLOB_TOKEN);
-}
-
"INT" {
return(PARS_INT_TOKEN);
}
-"INTEGER" {
- return(PARS_INT_TOKEN);
-}
-
-"FLOAT" {
- return(PARS_FLOAT_TOKEN);
-}
-
"CHAR" {
return(PARS_CHAR_TOKEN);
}
@@ -321,18 +301,10 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_SELECT_TOKEN);
}
-"SUM" {
- return(PARS_SUM_TOKEN);
-}
-
"COUNT" {
return(PARS_COUNT_TOKEN);
}
-"DISTINCT" {
- return(PARS_DISTINCT_TOKEN);
-}
-
"FROM" {
return(PARS_FROM_TOKEN);
}
@@ -345,10 +317,6 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_FOR_TOKEN);
}
-"READ" {
- return(PARS_READ_TOKEN);
-}
-
"ORDER" {
return(PARS_ORDER_TOKEN);
}
@@ -405,14 +373,6 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_TABLE_TOKEN);
}
-"COMPACT" {
- return(PARS_COMPACT_TOKEN);
-}
-
-"BLOCK_SIZE" {
- return(PARS_BLOCK_SIZE_TOKEN);
-}
-
"INDEX" {
return(PARS_INDEX_TOKEN);
}
@@ -453,30 +413,14 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_NOTFOUND_TOKEN);
}
-"TO_CHAR" {
- return(PARS_TO_CHAR_TOKEN);
-}
-
-"TO_NUMBER" {
- return(PARS_TO_NUMBER_TOKEN);
-}
-
"TO_BINARY" {
return(PARS_TO_BINARY_TOKEN);
}
-"BINARY_TO_NUMBER" {
- return(PARS_BINARY_TO_NUMBER_TOKEN);
-}
-
"SUBSTR" {
return(PARS_SUBSTR_TOKEN);
}
-"REPLSTR" {
- return(PARS_REPLSTR_TOKEN);
-}
-
"CONCAT" {
return(PARS_CONCAT_TOKEN);
}
@@ -489,30 +433,6 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_LENGTH_TOKEN);
}
-"SYSDATE" {
- return(PARS_SYSDATE_TOKEN);
-}
-
-"PRINTF" {
- return(PARS_PRINTF_TOKEN);
-}
-
-"ASSERT" {
- return(PARS_ASSERT_TOKEN);
-}
-
-"RND" {
- return(PARS_RND_TOKEN);
-}
-
-"RND_STR" {
- return(PARS_RND_STR_TOKEN);
-}
-
-"ROW_PRINTF" {
- return(PARS_ROW_PRINTF_TOKEN);
-}
-
"COMMIT" {
return(PARS_COMMIT_TOKEN);
}
@@ -525,10 +445,6 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_WORK_TOKEN);
}
-"UNSIGNED" {
- return(PARS_UNSIGNED_TOKEN);
-}
-
"EXIT" {
return(PARS_EXIT_TOKEN);
}
diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc
index 3f671adfdfc..280c4ee1815 100644
--- a/storage/innobase/pars/pars0pars.cc
+++ b/storage/innobase/pars/pars0pars.cc
@@ -50,29 +50,15 @@ sym_tab_t* pars_sym_tab_global;
/* Global variables used to denote certain reserved words, used in
constructing the parsing tree */
-pars_res_word_t pars_to_char_token = {PARS_TO_CHAR_TOKEN};
-pars_res_word_t pars_to_number_token = {PARS_TO_NUMBER_TOKEN};
pars_res_word_t pars_to_binary_token = {PARS_TO_BINARY_TOKEN};
-pars_res_word_t pars_binary_to_number_token = {PARS_BINARY_TO_NUMBER_TOKEN};
pars_res_word_t pars_substr_token = {PARS_SUBSTR_TOKEN};
-pars_res_word_t pars_replstr_token = {PARS_REPLSTR_TOKEN};
pars_res_word_t pars_concat_token = {PARS_CONCAT_TOKEN};
pars_res_word_t pars_instr_token = {PARS_INSTR_TOKEN};
pars_res_word_t pars_length_token = {PARS_LENGTH_TOKEN};
-pars_res_word_t pars_sysdate_token = {PARS_SYSDATE_TOKEN};
-pars_res_word_t pars_printf_token = {PARS_PRINTF_TOKEN};
-pars_res_word_t pars_assert_token = {PARS_ASSERT_TOKEN};
-pars_res_word_t pars_rnd_token = {PARS_RND_TOKEN};
-pars_res_word_t pars_rnd_str_token = {PARS_RND_STR_TOKEN};
pars_res_word_t pars_count_token = {PARS_COUNT_TOKEN};
-pars_res_word_t pars_sum_token = {PARS_SUM_TOKEN};
-pars_res_word_t pars_distinct_token = {PARS_DISTINCT_TOKEN};
-pars_res_word_t pars_binary_token = {PARS_BINARY_TOKEN};
-pars_res_word_t pars_blob_token = {PARS_BLOB_TOKEN};
pars_res_word_t pars_int_token = {PARS_INT_TOKEN};
pars_res_word_t pars_bigint_token = {PARS_BIGINT_TOKEN};
pars_res_word_t pars_char_token = {PARS_CHAR_TOKEN};
-pars_res_word_t pars_float_token = {PARS_FLOAT_TOKEN};
pars_res_word_t pars_update_token = {PARS_UPDATE_TOKEN};
pars_res_word_t pars_asc_token = {PARS_ASC_TOKEN};
pars_res_word_t pars_desc_token = {PARS_DESC_TOKEN};
@@ -195,24 +181,15 @@ pars_func_get_class(
case PARS_AND_TOKEN: case PARS_OR_TOKEN: case PARS_NOT_TOKEN:
return(PARS_FUNC_LOGICAL);
- case PARS_COUNT_TOKEN: case PARS_SUM_TOKEN:
+ case PARS_COUNT_TOKEN:
return(PARS_FUNC_AGGREGATE);
- case PARS_TO_CHAR_TOKEN:
- case PARS_TO_NUMBER_TOKEN:
case PARS_TO_BINARY_TOKEN:
- case PARS_BINARY_TO_NUMBER_TOKEN:
case PARS_SUBSTR_TOKEN:
case PARS_CONCAT_TOKEN:
case PARS_LENGTH_TOKEN:
case PARS_INSTR_TOKEN:
- case PARS_SYSDATE_TOKEN:
case PARS_NOTFOUND_TOKEN:
- case PARS_PRINTF_TOKEN:
- case PARS_ASSERT_TOKEN:
- case PARS_RND_TOKEN:
- case PARS_RND_STR_TOKEN:
- case PARS_REPLSTR_TOKEN:
return(PARS_FUNC_PREDEFINED);
default:
@@ -499,7 +476,6 @@ pars_resolve_func_data_type(
arg = node->args;
switch (node->func) {
- case PARS_SUM_TOKEN:
case '+': case '-': case '*': case '/':
/* Inherit the data type from the first argument (which must
not be the SQL null literal whose type is DATA_ERROR) */
@@ -516,13 +492,6 @@ pars_resolve_func_data_type(
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
break;
- case PARS_TO_CHAR_TOKEN:
- case PARS_RND_STR_TOKEN:
- ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
- dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
- DATA_ENGLISH, 0);
- break;
-
case PARS_TO_BINARY_TOKEN:
if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
@@ -533,19 +502,12 @@ pars_resolve_func_data_type(
}
break;
- case PARS_TO_NUMBER_TOKEN:
- case PARS_BINARY_TO_NUMBER_TOKEN:
case PARS_LENGTH_TOKEN:
case PARS_INSTR_TOKEN:
ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
break;
- case PARS_SYSDATE_TOKEN:
- ut_a(arg == NULL);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
- break;
-
case PARS_SUBSTR_TOKEN:
case PARS_CONCAT_TOKEN:
ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
@@ -566,11 +528,6 @@ pars_resolve_func_data_type(
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
break;
- case PARS_RND_TOKEN:
- ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
- break;
-
case PARS_LIKE_TOKEN_EXACT:
case PARS_LIKE_TOKEN_PREFIX:
case PARS_LIKE_TOKEN_SUFFIX:
@@ -1355,9 +1312,7 @@ pars_set_dfield_type(
pars_res_word_t* type, /*!< in: pointer to a type
token */
ulint len, /*!< in: length, or 0 */
- ibool is_unsigned, /*!< in: if TRUE, column is
- UNSIGNED. */
- ibool is_not_null) /*!< in: if TRUE, column is
+ bool is_not_null) /*!< in: whether the column is
NOT NULL. */
{
ulint flags = 0;
@@ -1366,10 +1321,6 @@ pars_set_dfield_type(
flags |= DATA_NOT_NULL;
}
- if (is_unsigned) {
- flags |= DATA_UNSIGNED;
- }
-
if (type == &pars_bigint_token) {
ut_a(len == 0);
@@ -1384,16 +1335,6 @@ pars_set_dfield_type(
dtype_set(dfield_get_type(dfield), DATA_VARCHAR,
DATA_ENGLISH | flags, len);
- } else if (type == &pars_binary_token) {
- ut_a(len != 0);
-
- dtype_set(dfield_get_type(dfield), DATA_FIXBINARY,
- DATA_BINARY_TYPE | flags, len);
- } else if (type == &pars_blob_token) {
- ut_a(len == 0);
-
- dtype_set(dfield_get_type(dfield), DATA_BLOB,
- DATA_BINARY_TYPE | flags, 0);
} else {
ut_error;
}
@@ -1414,28 +1355,7 @@ pars_variable_declaration(
node->param_type = PARS_NOT_PARAM;
- pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE, FALSE);
-
- return(node);
-}
-
-/*********************************************************************//**
-Parses a procedure parameter declaration.
-@return own: symbol table node of type SYM_VAR */
-sym_node_t*
-pars_parameter_declaration(
-/*=======================*/
- sym_node_t* node, /*!< in: symbol table node allocated for the
- id of the parameter */
- ulint param_type,
- /*!< in: PARS_INPUT or PARS_OUTPUT */
- pars_res_word_t* type) /*!< in: pointer to a type token */
-{
- ut_a((param_type == PARS_INPUT) || (param_type == PARS_OUTPUT));
-
- pars_variable_declaration(node, type);
-
- node->param_type = param_type;
+ pars_set_dfield_type(que_node_get_val(node), type, 0, false);
return(node);
}
@@ -1821,8 +1741,6 @@ pars_column_def(
pars_res_word_t* type, /*!< in: data type */
sym_node_t* len, /*!< in: length of column, or
NULL */
- void* is_unsigned, /*!< in: if not NULL, column
- is of type UNSIGNED. */
void* is_not_null) /*!< in: if not NULL, column
is of type NOT NULL. */
{
@@ -1835,7 +1753,7 @@ pars_column_def(
}
pars_set_dfield_type(que_node_get_val(sym_node), type, len2,
- is_unsigned != NULL, is_not_null != NULL);
+ is_not_null != NULL);
return(sym_node);
}
@@ -1848,9 +1766,7 @@ pars_create_table(
/*==============*/
sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_defs, /*!< in: list of column names */
- sym_node_t* compact, /* in: non-NULL if COMPACT table. */
- sym_node_t* block_size) /* in: block size (can be NULL) */
+ sym_node_t* column_defs) /*!< in: list of column names */
{
dict_table_t* table;
sym_node_t* column;
@@ -1858,57 +1774,11 @@ pars_create_table(
const dtype_t* dtype;
ulint n_cols;
ulint flags = 0;
- ulint flags2 = 0;
-
- if (compact != NULL) {
-
- /* System tables currently only use the REDUNDANT row
- format therefore the check for srv_file_per_table should be
- safe for now. */
-
- flags |= DICT_TF_COMPACT;
-
- /* FIXME: Ideally this should be part of the SQL syntax
- or use some other mechanism. We want to reduce dependency
- on global variables. There is an inherent race here but
- that has always existed around this variable. */
- if (srv_file_per_table) {
- flags2 |= DICT_TF2_USE_FILE_PER_TABLE;
- }
- }
-
- if (block_size != NULL) {
- ulint size;
- dfield_t* dfield;
+ ulint flags2 = DICT_TF2_FTS_AUX_HEX_NAME;
- dfield = que_node_get_val(block_size);
-
- ut_a(dfield_get_len(dfield) == 4);
- size = mach_read_from_4(static_cast<byte*>(
- dfield_get_data(dfield)));
-
-
- switch (size) {
- case 0:
- break;
-
- case 1: case 2: case 4: case 8: case 16:
- flags |= DICT_TF_COMPACT;
- /* FTS-FIXME: needs the zip changes */
- /* flags |= size << DICT_TF_COMPRESSED_SHIFT; */
- break;
-
- default:
- ut_error;
- }
- }
-
- /* Set the flags2 when create table or alter tables */
- flags2 |= DICT_TF2_FTS_AUX_HEX_NAME;
DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name",
flags2 &= ~DICT_TF2_FTS_AUX_HEX_NAME;);
-
n_cols = que_node_list_get_len(column_defs);
table = dict_mem_table_create(
@@ -2001,7 +1871,6 @@ pars_procedure_definition(
/*======================*/
sym_node_t* sym_node, /*!< in: procedure id node in the symbol
table */
- sym_node_t* param_list, /*!< in: parameter declaration list */
que_node_t* stat_list) /*!< in: statement list */
{
proc_node_t* node;
@@ -2026,7 +1895,6 @@ pars_procedure_definition(
sym_node->resolved = TRUE;
node->proc_id = sym_node;
- node->param_list = param_list;
node->stat_list = stat_list;
pars_set_parent_in_list(stat_list, node);
diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc
index 1d3d1573299..3ad948af4d2 100644
--- a/storage/innobase/que/que0que.cc
+++ b/storage/innobase/que/que0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2018, 2020 MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -460,6 +460,8 @@ que_graph_free_recursive(
que_graph_free_recursive(ins->select);
ins->select = NULL;
+ ins->~ins_node_t();
+
if (ins->entry_sys_heap != NULL) {
mem_heap_free(ins->entry_sys_heap);
ins->entry_sys_heap = NULL;
diff --git a/storage/innobase/rem/rem0cmp.cc b/storage/innobase/rem/rem0cmp.cc
index 9449274321e..ed44e91711c 100644
--- a/storage/innobase/rem/rem0cmp.cc
+++ b/storage/innobase/rem/rem0cmp.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,6 +26,7 @@ Created 7/1/1994 Heikki Tuuri
#include "rem0cmp.h"
#include "rem0rec.h"
+#include "page0page.h"
#include "dict0mem.h"
#include "handler0alter.h"
@@ -534,7 +536,7 @@ cmp_data(
/** Compare a GIS data tuple to a physical record.
@param[in] dtuple data tuple
-@param[in] rec B-tree record
+@param[in] rec R-tree record
@param[in] offsets rec_get_offsets(rec)
@param[in] mode compare mode
@retval negative if dtuple is less than rec */
@@ -546,7 +548,7 @@ cmp_dtuple_rec_with_gis(
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
page_cur_mode_t mode) /*!< in: compare mode */
{
const dfield_t* dtuple_field; /* current field in logical record */
@@ -579,7 +581,7 @@ int
cmp_dtuple_rec_with_gis_internal(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets)
+ const rec_offs* offsets)
{
const dfield_t* dtuple_field; /* current field in logical record */
ulint dtuple_f_len; /* the length of the current field
@@ -650,7 +652,7 @@ int
cmp_dtuple_rec_with_match_low(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint n_cmp,
ulint* matched_fields)
{
@@ -779,7 +781,7 @@ cmp_dtuple_rec_with_match_bytes(
const dtuple_t* dtuple,
const rec_t* rec,
const dict_index_t* index,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint* matched_fields,
ulint* matched_bytes)
{
@@ -942,7 +944,7 @@ int
cmp_dtuple_rec(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets)
+ const rec_offs* offsets)
{
ulint matched_fields = 0;
@@ -960,7 +962,7 @@ cmp_dtuple_is_prefix_of_rec(
/*========================*/
const dtuple_t* dtuple, /*!< in: data tuple */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
ulint matched_fields = 0;
@@ -988,8 +990,8 @@ cmp_rec_rec_simple_field(
/*=====================*/
const rec_t* rec1, /*!< in: physical record */
const rec_t* rec2, /*!< in: physical record */
- const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
- const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
+ const rec_offs* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
+ const rec_offs* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
const dict_index_t* index, /*!< in: data dictionary index */
ulint n) /*!< in: field to compare */
{
@@ -1019,8 +1021,8 @@ cmp_rec_rec_simple(
/*===============*/
const rec_t* rec1, /*!< in: physical record */
const rec_t* rec2, /*!< in: physical record */
- const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
- const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
+ const rec_offs* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
+ const rec_offs* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
const dict_index_t* index, /*!< in: data dictionary index */
struct TABLE* table) /*!< in: MySQL table, for reporting
duplicate key value if applicable,
@@ -1086,42 +1088,40 @@ cmp_rec_rec_simple(
return(0);
}
-/** Compare two B-tree records.
-@param[in] rec1 B-tree record
-@param[in] rec2 B-tree record
-@param[in] offsets1 rec_get_offsets(rec1, index)
-@param[in] offsets2 rec_get_offsets(rec2, index)
-@param[in] index B-tree index
-@param[in] nulls_unequal true if this is for index cardinality
-statistics estimation, and innodb_stats_method=nulls_unequal
-or innodb_stats_method=nulls_ignored
-@param[out] matched_fields number of completely matched fields
-within the first field not completely matched
-@return the comparison result
+/** Compare two B-tree or R-tree records.
+Only the common first fields are compared, and externally stored field
+are treated as equal.
+@param[in] rec1 record (possibly not on an index page)
+@param[in] rec2 B-tree or R-tree record in an index page
+@param[in] offsets1 rec_get_offsets(rec1, index)
+@param[in] offsets2 rec_get_offsets(rec2, index)
+@param[in] nulls_unequal true if this is for index cardinality
+ statistics estimation with
+ innodb_stats_method=nulls_unequal
+ or innodb_stats_method=nulls_ignored
+@param[out] matched_fields number of completely matched fields
+ within the first field not completely matched
@retval 0 if rec1 is equal to rec2
@retval negative if rec1 is less than rec2
-@retval positive if rec2 is greater than rec2 */
+@retval positive if rec1 is greater than rec2 */
int
-cmp_rec_rec_with_match(
+cmp_rec_rec(
const rec_t* rec1,
const rec_t* rec2,
- const ulint* offsets1,
- const ulint* offsets2,
+ const rec_offs* offsets1,
+ const rec_offs* offsets2,
const dict_index_t* index,
bool nulls_unequal,
ulint* matched_fields)
{
- ulint rec1_n_fields; /* the number of fields in rec */
ulint rec1_f_len; /* length of current field in rec */
const byte* rec1_b_ptr; /* pointer to the current byte
in rec field */
- ulint rec2_n_fields; /* the number of fields in rec */
ulint rec2_f_len; /* length of current field in rec */
const byte* rec2_b_ptr; /* pointer to the current byte
in rec field */
ulint cur_field = 0; /* current field number */
int ret = 0; /* return value */
- ulint comp;
ut_ad(rec1 != NULL);
ut_ad(rec2 != NULL);
@@ -1129,10 +1129,12 @@ cmp_rec_rec_with_match(
ut_ad(rec_offs_validate(rec1, index, offsets1));
ut_ad(rec_offs_validate(rec2, index, offsets2));
ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2));
+ ut_ad(fil_page_index_page_check(page_align(rec2)));
+ ut_ad(!!dict_index_is_spatial(index)
+ == (fil_page_get_type(page_align(rec2)) == FIL_PAGE_RTREE));
- comp = rec_offs_comp(offsets1);
- rec1_n_fields = rec_offs_n_fields(offsets1);
- rec2_n_fields = rec_offs_n_fields(offsets2);
+ ulint comp = rec_offs_comp(offsets1);
+ ulint n_fields;
/* Test if rec is the predefined minimum record */
if (UNIV_UNLIKELY(rec_get_info_bits(rec1, comp)
@@ -1149,37 +1151,41 @@ cmp_rec_rec_with_match(
goto order_resolved;
}
- /* Match fields in a loop */
+ /* For non-leaf spatial index records, the
+ dict_index_get_n_unique_in_tree() does include the child page
+ number, because spatial index node pointers only contain
+ the MBR (minimum bounding rectangle) and the child page number.
- for (; cur_field < rec1_n_fields && cur_field < rec2_n_fields;
- cur_field++) {
+ For B-tree node pointers, the key alone (secondary index
+ columns and PRIMARY KEY columns) must be unique, and there is
+ no need to compare the child page number. */
+ n_fields = std::min(rec_offs_n_fields(offsets1),
+ rec_offs_n_fields(offsets2));
+ n_fields = std::min(n_fields, dict_index_get_n_unique_in_tree(index));
+ for (; cur_field < n_fields; cur_field++) {
ulint mtype;
ulint prtype;
- /* If this is node-ptr records then avoid comparing node-ptr
- field. Only key field needs to be compared. */
- if (cur_field == dict_index_get_n_unique_in_tree(index)) {
- break;
- }
-
- if (dict_index_is_ibuf(index)) {
+ if (UNIV_UNLIKELY(dict_index_is_ibuf(index))) {
/* This is for the insert buffer B-tree. */
mtype = DATA_BINARY;
prtype = 0;
} else {
- const dict_col_t* col;
-
- col = dict_index_get_nth_col(index, cur_field);
-
+ const dict_col_t* col = dict_index_get_nth_col(
+ index, cur_field);
mtype = col->mtype;
prtype = col->prtype;
- /* If the index is spatial index, we mark the
- prtype of the first field as MBR field. */
- if (cur_field == 0 && dict_index_is_spatial(index)) {
+ if (UNIV_LIKELY(!dict_index_is_spatial(index))) {
+ } else if (cur_field == 0) {
ut_ad(DATA_GEOMETRY_MTYPE(mtype));
prtype |= DATA_GIS_MBR;
+ } else if (!page_rec_is_leaf(rec2)) {
+ /* Compare the child page number. */
+ ut_ad(cur_field == 1);
+ mtype = DATA_SYS_CHILD;
+ prtype = 0;
}
}
@@ -1215,8 +1221,10 @@ cmp_rec_rec_with_match(
to the common fields */
ut_ad(ret == 0);
order_resolved:
- *matched_fields = cur_field;
- return(ret);
+ if (matched_fields) {
+ *matched_fields = cur_field;
+ }
+ return ret;
}
#ifdef UNIV_COMPILE_TEST_FUNCS
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index b0fb4e0f113..962de60f555 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -242,12 +242,12 @@ rec_init_offsets_comp_ordinary(
format for temporary files in
index creation */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in/out: array of offsets;
+ rec_offs* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
- ulint offs = 0;
- ulint any_ext = 0;
+ rec_offs offs = 0;
+ rec_offs any_ext = 0;
ulint n_null = index->n_nullable;
const byte* nulls = temp
? rec - 1
@@ -259,8 +259,8 @@ rec_init_offsets_comp_ordinary(
/* We cannot invoke rec_offs_make_valid() here if temp=true.
Similarly, rec_offs_validate() will fail in that case, because
it invokes rec_get_status(). */
- offsets[2] = (ulint) rec;
- offsets[3] = (ulint) index;
+ memcpy(&offsets[RECORD_OFFSET], &rec, sizeof(rec));
+ memcpy(&offsets[INDEX_OFFSET], &index, sizeof(index));
#endif /* UNIV_DEBUG */
ut_ad(temp || dict_table_is_comp(index->table));
@@ -277,7 +277,7 @@ rec_init_offsets_comp_ordinary(
= dict_index_get_nth_field(index, i);
const dict_col_t* col
= dict_field_get_col(field);
- ulint len;
+ rec_offs len;
if (!(col->prtype & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
@@ -294,7 +294,7 @@ rec_init_offsets_comp_ordinary(
We do not advance offs, and we set
the length to zero and enable the
SQL NULL flag in offsets[]. */
- len = offs | REC_OFFS_SQL_NULL;
+ len = combine(offs, SQL_NULL);
goto resolved;
}
null_mask <<= 1;
@@ -317,14 +317,14 @@ rec_init_offsets_comp_ordinary(
len <<= 8;
len |= *lens--;
- offs += len & 0x3fff;
+ offs += get_value(len);
if (UNIV_UNLIKELY(len
& 0x4000)) {
ut_ad(dict_index_is_clust
(index));
any_ext = REC_OFFS_EXTERNAL;
- len = offs
- | REC_OFFS_EXTERNAL;
+ len = combine(offs,
+ STORED_OFFPAGE);
} else {
len = offs;
}
@@ -341,8 +341,8 @@ resolved:
rec_offs_base(offsets)[i + 1] = len;
} while (++i < rec_offs_n_fields(offsets));
- *rec_offs_base(offsets)
- = (rec - (lens + 1)) | REC_OFFS_COMPACT | any_ext;
+ *rec_offs_base(offsets) = static_cast<rec_offs>(rec - (lens + 1))
+ | REC_OFFS_COMPACT | any_ext;
}
/******************************************************//**
@@ -355,21 +355,20 @@ to the extra size (if REC_OFFS_COMPACT is set, the record is in the
new format; if REC_OFFS_EXTERNAL is set, the record contains externally
stored columns), and rec_offs_base(offsets)[1..n_fields] will be set to
offsets past the end of fields 0..n_fields, or to the beginning of
-fields 1..n_fields+1. When the high-order bit of the offset at [i+1]
-is set (REC_OFFS_SQL_NULL), the field i is NULL. When the second
-high-order bit of the offset at [i+1] is set (REC_OFFS_EXTERNAL), the
-field i is being stored externally. */
+fields 1..n_fields+1. When the type of the offset at [i+1]
+is (SQL_NULL), the field i is NULL. When the type of the offset at [i+1]
+is (STORED_OFFPAGE), the field i is stored externally. */
static
void
rec_init_offsets(
/*=============*/
const rec_t* rec, /*!< in: physical record */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in/out: array of offsets;
+ rec_offs* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
- ulint offs;
+ rec_offs offs;
rec_offs_make_valid(rec, index, offsets);
@@ -407,7 +406,7 @@ rec_init_offsets(
/* read the lengths of fields 0..n */
do {
- ulint len;
+ rec_offs len;
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
len = offs += REC_NODE_PTR_SIZE;
goto resolved;
@@ -429,7 +428,7 @@ rec_init_offsets(
We do not advance offs, and we set
the length to zero and enable the
SQL NULL flag in offsets[]. */
- len = offs | REC_OFFS_SQL_NULL;
+ len = combine(offs, SQL_NULL);
goto resolved;
}
null_mask <<= 1;
@@ -461,7 +460,7 @@ rec_init_offsets(
stored columns. Thus
the "e" flag must be 0. */
ut_a(!(len & 0x4000));
- offs += len & 0x3fff;
+ offs += get_value(len);
len = offs;
goto resolved;
@@ -476,36 +475,39 @@ resolved:
rec_offs_base(offsets)[i + 1] = len;
} while (++i < rec_offs_n_fields(offsets));
- *rec_offs_base(offsets)
- = (rec - (lens + 1)) | REC_OFFS_COMPACT;
+ *rec_offs_base(offsets) = static_cast<rec_offs>(
+ (rec - (lens + 1)) | REC_OFFS_COMPACT);
} else {
/* Old-style record: determine extra size and end offsets */
offs = REC_N_OLD_EXTRA_BYTES;
if (rec_get_1byte_offs_flag(rec)) {
- offs += rec_offs_n_fields(offsets);
+ offs += static_cast<rec_offs>(
+ rec_offs_n_fields(offsets));
*rec_offs_base(offsets) = offs;
/* Determine offsets to fields */
do {
offs = rec_1_get_field_end_info(rec, i);
if (offs & REC_1BYTE_SQL_NULL_MASK) {
offs &= ~REC_1BYTE_SQL_NULL_MASK;
- offs |= REC_OFFS_SQL_NULL;
+ set_type(offs, SQL_NULL);
}
rec_offs_base(offsets)[1 + i] = offs;
} while (++i < rec_offs_n_fields(offsets));
} else {
- offs += 2 * rec_offs_n_fields(offsets);
+ offs += 2
+ * static_cast<rec_offs>(
+ rec_offs_n_fields(offsets));
*rec_offs_base(offsets) = offs;
/* Determine offsets to fields */
do {
offs = rec_2_get_field_end_info(rec, i);
if (offs & REC_2BYTE_SQL_NULL_MASK) {
offs &= ~REC_2BYTE_SQL_NULL_MASK;
- offs |= REC_OFFS_SQL_NULL;
+ set_type(offs, SQL_NULL);
}
if (offs & REC_2BYTE_EXTERN_MASK) {
offs &= ~REC_2BYTE_EXTERN_MASK;
- offs |= REC_OFFS_EXTERNAL;
+ set_type(offs, STORED_OFFPAGE);
*rec_offs_base(offsets) |= REC_OFFS_EXTERNAL;
}
rec_offs_base(offsets)[1 + i] = offs;
@@ -524,11 +526,11 @@ resolved:
(ULINT_UNDEFINED to compute all offsets)
@param[in,out] heap memory heap
@return the new offsets */
-ulint*
+rec_offs*
rec_get_offsets_func(
const rec_t* rec,
const dict_index_t* index,
- ulint* offsets,
+ rec_offs* offsets,
#ifdef UNIV_DEBUG
bool leaf,
#endif /* UNIV_DEBUG */
@@ -606,11 +608,11 @@ rec_get_offsets_func(
if (UNIV_UNLIKELY(!offsets)
|| UNIV_UNLIKELY(rec_offs_get_n_alloc(offsets) < size)) {
if (UNIV_UNLIKELY(!*heap)) {
- *heap = mem_heap_create_at(size * sizeof(ulint),
+ *heap = mem_heap_create_at(size * sizeof(*offsets),
file, line);
}
- offsets = static_cast<ulint*>(
- mem_heap_alloc(*heap, size * sizeof(ulint)));
+ offsets = static_cast<rec_offs*>(
+ mem_heap_alloc(*heap, size * sizeof(*offsets)));
rec_offs_set_n_alloc(offsets, size);
}
@@ -633,13 +635,13 @@ rec_get_offsets_reverse(
const dict_index_t* index, /*!< in: record descriptor */
ulint node_ptr,/*!< in: nonzero=node pointer,
0=leaf node */
- ulint* offsets)/*!< in/out: array consisting of
+ rec_offs* offsets)/*!< in/out: array consisting of
offsets[0] allocated elements */
{
ulint n;
ulint i;
- ulint offs;
- ulint any_ext;
+ rec_offs offs;
+ rec_offs any_ext = 0;
const byte* nulls;
const byte* lens;
dict_field_t* field;
@@ -664,11 +666,10 @@ rec_get_offsets_reverse(
lens = nulls + UT_BITS_IN_BYTES(index->n_nullable);
i = offs = 0;
null_mask = 1;
- any_ext = 0;
/* read the lengths of fields 0..n */
do {
- ulint len;
+ rec_offs len;
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
len = offs += REC_NODE_PTR_SIZE;
goto resolved;
@@ -689,7 +690,7 @@ rec_get_offsets_reverse(
We do not advance offs, and we set
the length to zero and enable the
SQL NULL flag in offsets[]. */
- len = offs | REC_OFFS_SQL_NULL;
+ len = combine(offs, SQL_NULL);
goto resolved;
}
null_mask <<= 1;
@@ -713,10 +714,11 @@ rec_get_offsets_reverse(
len <<= 8;
len |= *lens++;
- offs += len & 0x3fff;
+ offs += get_value(len);
if (UNIV_UNLIKELY(len & 0x4000)) {
any_ext = REC_OFFS_EXTERNAL;
- len = offs | REC_OFFS_EXTERNAL;
+ len = combine(offs,
+ STORED_OFFPAGE);
} else {
len = offs;
}
@@ -727,15 +729,16 @@ rec_get_offsets_reverse(
len = offs += len;
} else {
- len = offs += field->fixed_len;
+ len = offs += static_cast<rec_offs>(field->fixed_len);
}
resolved:
rec_offs_base(offsets)[i + 1] = len;
} while (++i < rec_offs_n_fields(offsets));
ut_ad(lens >= extra);
- *rec_offs_base(offsets) = (lens - extra + REC_N_NEW_EXTRA_BYTES)
- | REC_OFFS_COMPACT | any_ext;
+ *rec_offs_base(offsets)
+ = static_cast<rec_offs>((lens - extra + REC_N_NEW_EXTRA_BYTES)
+ | REC_OFFS_COMPACT | any_ext);
}
/************************************************************//**
@@ -1397,7 +1400,7 @@ rec_init_offsets_temp(
/*==================*/
const rec_t* rec, /*!< in: temporary file record */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in/out: array of offsets;
+ rec_offs* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
rec_init_offsets_comp_ordinary(rec, true, index, offsets);
@@ -1436,8 +1439,8 @@ rec_copy_prefix_to_dtuple_func(
ulint n_fields,
mem_heap_t* heap)
{
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(is_leaf || n_fields
@@ -1697,7 +1700,7 @@ ibool
rec_validate(
/*=========*/
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint len;
ulint n_fields;
@@ -1799,7 +1802,7 @@ rec_print_comp(
/*===========*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint i;
@@ -1919,7 +1922,7 @@ rec_print_mbr_rec(
/*==============*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
@@ -1986,7 +1989,7 @@ rec_print_new(
/*==========*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
@@ -2026,7 +2029,7 @@ rec_print(
return;
} else {
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
rec_print_new(file, rec,
@@ -2049,7 +2052,7 @@ rec_print(
std::ostream& o,
const rec_t* rec,
ulint info,
- const ulint* offsets)
+ const rec_offs* offsets)
{
const ulint comp = rec_offs_comp(offsets);
const ulint n = rec_offs_n_fields(offsets);
@@ -2101,7 +2104,7 @@ std::ostream&
operator<<(std::ostream& o, const rec_index_print& r)
{
mem_heap_t* heap = NULL;
- ulint* offsets = rec_get_offsets(
+ rec_offs* offsets = rec_get_offsets(
r.m_rec, r.m_index, NULL, page_rec_is_leaf(r.m_rec),
ULINT_UNDEFINED, &heap);
rec_print(o, r.m_rec,
@@ -2139,9 +2142,9 @@ rec_get_trx_id(
const byte* trx_id;
ulint len;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
+ rec_offs offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
rec_offs_init(offsets_);
- ulint* offsets = offsets_;
+ rec_offs* offsets = offsets_;
ut_ad(trx_id_col <= MAX_REF_PARTS);
ut_ad(dict_index_is_clust(index));
@@ -2168,11 +2171,11 @@ rec_get_trx_id(
@param[in] n nth field */
void
rec_offs_make_nth_extern(
- ulint* offsets,
+ rec_offs* offsets,
const ulint n)
{
ut_ad(!rec_offs_nth_sql_null(offsets, n));
- rec_offs_base(offsets)[1 + n] |= REC_OFFS_EXTERNAL;
+ set_type(rec_offs_base(offsets)[1 +n ], STORED_OFFPAGE);
}
#ifdef WITH_WSREP
# include "ha_prototypes.h"
@@ -2192,8 +2195,8 @@ wsrep_rec_get_foreign_key(
ulint i;
uint key_parts;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- const ulint* offsets;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ const rec_offs* offsets;
ut_ad(index_for);
ut_ad(index_ref);
diff --git a/storage/innobase/row/row0ext.cc b/storage/innobase/row/row0ext.cc
index f7e28981939..32e9aad9896 100644
--- a/storage/innobase/row/row0ext.cc
+++ b/storage/innobase/row/row0ext.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -119,11 +120,6 @@ row_ext_create(
ret->buf = static_cast<byte*>(
mem_heap_alloc(heap, n_ext * ret->max_len));
-#ifdef UNIV_DEBUG
- memset(ret->buf, 0xaa, n_ext * ret->max_len);
- UNIV_MEM_ALLOC(ret->buf, n_ext * ret->max_len);
-#endif
-
/* Fetch the BLOB prefixes */
for (i = 0; i < n_ext; i++) {
const dfield_t* dfield;
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 2b751170886..4085ff17bd3 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -864,7 +864,8 @@ loop:
num_doc_processed++;
- if (fts_enable_diag_print && num_doc_processed % 10000 == 1) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)
+ && num_doc_processed % 10000 == 1) {
ib::info() << "Number of documents processed: "
<< num_doc_processed;
#ifdef FTS_INTERNAL_DIAG_PRINT
@@ -902,7 +903,7 @@ loop:
goto func_exit;
}
- UNIV_MEM_INVALID(block[t_ctx.buf_used], srv_sort_buf_size);
+ MEM_UNDEFINED(block[t_ctx.buf_used], srv_sort_buf_size);
buf[t_ctx.buf_used] = row_merge_buf_empty(buf[t_ctx.buf_used]);
mycount[t_ctx.buf_used] += t_ctx.rows_added[t_ctx.buf_used];
t_ctx.rows_added[t_ctx.buf_used] = 0;
@@ -996,12 +997,14 @@ exit:
goto func_exit;
}
- UNIV_MEM_INVALID(block[i], srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(block[i], srv_sort_buf_size);
if (crypt_block[i]) {
- UNIV_MEM_INVALID(crypt_block[i],
- srv_sort_buf_size);
+ MEM_UNDEFINED(crypt_block[i],
+ srv_sort_buf_size);
}
+#endif /* HAVE_valgrind_or_MSAN */
}
buf[i] = row_merge_buf_empty(buf[i]);
@@ -1009,7 +1012,7 @@ exit:
}
}
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
DEBUG_FTS_SORT_PRINT(" InnoDB_FTS: start merge sort\n");
}
@@ -1040,7 +1043,7 @@ exit:
}
func_exit:
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
DEBUG_FTS_SORT_PRINT(" InnoDB_FTS: complete merge sort\n");
}
@@ -1215,11 +1218,9 @@ row_merge_write_fts_word(
error = row_merge_write_fts_node(ins_ctx, &word->text, fts_node);
- if (error != DB_SUCCESS) {
- ib::error() << "Failed to write word "
- << word->text.f_str << " to FTS auxiliary"
- " index table, error (" << ut_strerr(error)
- << ")";
+ if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
+ ib::error() << "Failed to write word to FTS auxiliary"
+ " index table, error " << error;
ret = error;
}
@@ -1371,7 +1372,7 @@ row_fts_sel_tree_propagate(
int propogated, /*<! in: tree node propagated */
int* sel_tree, /*<! in: selection tree */
const mrec_t** mrec, /*<! in: sort record */
- ulint** offsets, /*<! in: record offsets */
+ rec_offs** offsets, /*<! in: record offsets */
dict_index_t* index) /*<! in/out: FTS index */
{
ulint parent;
@@ -1421,7 +1422,7 @@ row_fts_sel_tree_update(
ulint propagated, /*<! in: node to propagate up */
ulint height, /*<! in: tree height */
const mrec_t** mrec, /*<! in: sort record */
- ulint** offsets, /*<! in: record offsets */
+ rec_offs** offsets, /*<! in: record offsets */
dict_index_t* index) /*<! in: index dictionary */
{
ulint i;
@@ -1443,7 +1444,7 @@ row_fts_build_sel_tree_level(
int* sel_tree, /*<! in/out: selection tree */
ulint level, /*<! in: selection tree level */
const mrec_t** mrec, /*<! in: sort record */
- ulint** offsets, /*<! in: record offsets */
+ rec_offs** offsets, /*<! in: record offsets */
dict_index_t* index) /*<! in: index dictionary */
{
ulint start;
@@ -1503,7 +1504,7 @@ row_fts_build_sel_tree(
/*===================*/
int* sel_tree, /*<! in/out: selection tree */
const mrec_t** mrec, /*<! in: sort record */
- ulint** offsets, /*<! in: record offsets */
+ rec_offs** offsets, /*<! in: record offsets */
dict_index_t* index) /*<! in: index dictionary */
{
ulint treelevel = 1;
@@ -1553,7 +1554,7 @@ row_fts_merge_insert(
mem_heap_t* heap;
dberr_t error = DB_SUCCESS;
ulint* foffs;
- ulint** offsets;
+ rec_offs** offsets;
fts_tokenizer_word_t new_word;
ib_vector_t* positions;
doc_id_t last_doc_id;
@@ -1593,7 +1594,7 @@ row_fts_merge_insert(
heap, sizeof (*b) * fts_sort_pll_degree);
foffs = (ulint*) mem_heap_alloc(
heap, sizeof(*foffs) * fts_sort_pll_degree);
- offsets = (ulint**) mem_heap_alloc(
+ offsets = (rec_offs**) mem_heap_alloc(
heap, sizeof(*offsets) * fts_sort_pll_degree);
buf = (mrec_buf_t**) mem_heap_alloc(
heap, sizeof(*buf) * fts_sort_pll_degree);
@@ -1617,10 +1618,10 @@ row_fts_merge_insert(
num = 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index);
- offsets[i] = static_cast<ulint*>(mem_heap_zalloc(
+ offsets[i] = static_cast<rec_offs*>(mem_heap_zalloc(
heap, num * sizeof *offsets[i]));
- offsets[i][0] = num;
- offsets[i][1] = dict_index_get_n_fields(index);
+ rec_offs_set_n_alloc(offsets[i], num);
+ rec_offs_set_n_fields(offsets[i], dict_index_get_n_fields(index));
block[i] = psort_info[i].merge_block[id];
crypt_block[i] = psort_info[i].crypt_block[id];
b[i] = psort_info[i].merge_block[id];
@@ -1633,7 +1634,7 @@ row_fts_merge_insert(
count_diag += (int) psort_info[i].merge_file[id]->n_rec;
}
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "InnoDB_FTS: to insert " << count_diag
<< " records";
}
@@ -1720,7 +1721,6 @@ row_fts_merge_insert(
corresponding FTS index auxiliary tables */
for (;;) {
dtuple_t* dtuple;
- ulint n_ext;
int min_rec = 0;
if (fts_sort_pll_degree <= 2) {
@@ -1763,7 +1763,7 @@ row_fts_merge_insert(
}
dtuple = row_rec_to_index_entry_low(
- mrec[min_rec], index, offsets[min_rec], &n_ext,
+ mrec[min_rec], index, offsets[min_rec],
tuple_heap);
row_fts_insert_tuple(
@@ -1802,7 +1802,7 @@ exit:
mem_heap_free(heap);
- if (fts_enable_diag_print) {
+ if (UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "InnoDB_FTS: inserted " << count << " records";
}
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 6d0d77c9f5b..981c5046de1 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -26,6 +26,9 @@ Created 2012-02-08 by Sunny Bains.
#include "row0import.h"
#include "btr0pcur.h"
+#ifdef BTR_CUR_HASH_ADAPT
+# include "btr0sea.h"
+#endif
#include "que0que.h"
#include "dict0boot.h"
#include "dict0load.h"
@@ -264,7 +267,7 @@ public:
bool remove(
const dict_index_t* index,
page_zip_des_t* page_zip,
- ulint* offsets) UNIV_NOTHROW
+ rec_offs* offsets) UNIV_NOTHROW
{
/* We can't end up with an empty page unless it is root. */
if (page_get_n_recs(m_cur.block->frame) <= 1) {
@@ -524,14 +527,6 @@ protected:
/** Space id of the file being iterated over. */
ulint m_space;
- /** Minimum page number for which the free list has not been
- initialized: the pages >= this limit are, by definition, free;
- note that in a single-table tablespace where size < 64 pages,
- this number is 64, i.e., we have initialized the space about
- the first extent, but have not physically allocted those pages
- to the file. @see FSP_LIMIT. */
- ulint m_free_limit;
-
/** Current size of the space in pages */
ulint m_size;
@@ -591,7 +586,6 @@ AbstractCallback::init(
ut_a(m_space == ULINT_UNDEFINED);
m_size = mach_read_from_4(page + FSP_SIZE);
- m_free_limit = mach_read_from_4(page + FSP_FREE_LIMIT);
m_space = mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID);
return set_current_xdes(0, page);
@@ -845,7 +839,7 @@ private:
@return DB_SUCCESS or error code */
dberr_t adjust_cluster_index_blob_column(
rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint i) UNIV_NOTHROW;
/** Adjusts the BLOB reference in the clustered index row for all
@@ -855,7 +849,7 @@ private:
@return DB_SUCCESS or error code */
dberr_t adjust_cluster_index_blob_columns(
rec_t* rec,
- const ulint* offsets) UNIV_NOTHROW;
+ const rec_offs* offsets) UNIV_NOTHROW;
/** In the clustered index, adjist the BLOB pointers as needed.
Also update the BLOB reference, write the new space id.
@@ -864,13 +858,13 @@ private:
@return DB_SUCCESS or error code */
dberr_t adjust_cluster_index_blob_ref(
rec_t* rec,
- const ulint* offsets) UNIV_NOTHROW;
+ const rec_offs* offsets) UNIV_NOTHROW;
/** Purge delete-marked records, only if it is possible to do
so without re-organising the B+tree.
@param offsets current row offsets.
@retval true if purged */
- bool purge(const ulint* offsets) UNIV_NOTHROW;
+ bool purge(const rec_offs* offsets) UNIV_NOTHROW;
/** Adjust the BLOB references and sys fields for the current record.
@param index the index being converted
@@ -880,7 +874,7 @@ private:
dberr_t adjust_cluster_record(
const dict_index_t* index,
rec_t* rec,
- const ulint* offsets) UNIV_NOTHROW;
+ const rec_offs* offsets) UNIV_NOTHROW;
/** Find an index with the matching id.
@return row_index_t* instance or 0 */
@@ -914,10 +908,10 @@ private:
RecIterator m_rec_iter;
/** Record offset */
- ulint m_offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs m_offsets_[REC_OFFS_NORMAL_SIZE];
/** Pointer to m_offsets_ */
- ulint* m_offsets;
+ rec_offs* m_offsets;
/** Memory heap for the record offsets */
mem_heap_t* m_heap;
@@ -1154,60 +1148,82 @@ row_import::match_table_columns(
if (cfg_col->prtype != col->prtype) {
ib_errf(thd,
- IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Column %s precise type mismatch.",
- col_name);
+ IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Column %s precise type mismatch,"
+ " it's 0X%X in the table and 0X%X"
+ " in the tablespace meta file",
+ col_name, col->prtype, cfg_col->prtype);
err = DB_ERROR;
}
if (cfg_col->mtype != col->mtype) {
ib_errf(thd,
- IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Column %s main type mismatch.",
- col_name);
+ IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Column %s main type mismatch,"
+ " it's 0X%X in the table and 0X%X"
+ " in the tablespace meta file",
+ col_name, col->mtype, cfg_col->mtype);
err = DB_ERROR;
}
if (cfg_col->len != col->len) {
ib_errf(thd,
- IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Column %s length mismatch.",
- col_name);
+ IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Column %s length mismatch,"
+ " it's %u in the table and %u"
+ " in the tablespace meta file",
+ col_name, col->len, cfg_col->len);
err = DB_ERROR;
}
if (cfg_col->mbminlen != col->mbminlen
|| cfg_col->mbmaxlen != col->mbmaxlen) {
ib_errf(thd,
- IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Column %s multi-byte len mismatch.",
- col_name);
+ IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Column %s multi-byte len mismatch,"
+ " it's %u-%u in the table and %u-%u"
+ " in the tablespace meta file",
+ col_name, col->mbminlen, col->mbmaxlen,
+ cfg_col->mbminlen, cfg_col->mbmaxlen);
err = DB_ERROR;
}
if (cfg_col->ind != col->ind) {
+ ib_errf(thd,
+ IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Column %s position mismatch,"
+ " it's %u in the table and %u"
+ " in the tablespace meta file",
+ col_name, col->ind, cfg_col->ind);
err = DB_ERROR;
}
if (cfg_col->ord_part != col->ord_part) {
ib_errf(thd,
- IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Column %s ordering mismatch.",
- col_name);
+ IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Column %s ordering mismatch,"
+ " it's %u in the table and %u"
+ " in the tablespace meta file",
+ col_name, col->ord_part,
+ cfg_col->ord_part);
err = DB_ERROR;
}
if (cfg_col->max_prefix != col->max_prefix) {
ib_errf(thd,
- IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Column %s max prefix mismatch.",
- col_name);
+ IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Column %s max prefix mismatch"
+ " it's %u in the table and %u"
+ " in the tablespace meta file",
+ col_name, col->max_prefix,
+ cfg_col->max_prefix);
err = DB_ERROR;
}
}
@@ -1502,13 +1518,70 @@ IndexPurge::next() UNIV_NOTHROW
mtr_set_log_mode(&m_mtr, MTR_LOG_NO_REDO);
btr_pcur_restore_position(BTR_MODIFY_LEAF, &m_pcur, &m_mtr);
+ /* The following is based on btr_pcur_move_to_next_user_rec(). */
+ m_pcur.old_stored = false;
+ ut_ad(m_pcur.latch_mode == BTR_MODIFY_LEAF);
+ do {
+ if (btr_pcur_is_after_last_on_page(&m_pcur)) {
+ if (btr_pcur_is_after_last_in_tree(&m_pcur, &m_mtr)) {
+ return DB_END_OF_INDEX;
+ }
- if (!btr_pcur_move_to_next_user_rec(&m_pcur, &m_mtr)) {
+ buf_block_t* block = btr_pcur_get_block(&m_pcur);
+ uint32_t next_page = btr_page_get_next(block->frame);
- return(DB_END_OF_INDEX);
- }
+ /* MDEV-13542 FIXME: Make these checks part of
+ btr_pcur_move_to_next_page(), and introduce a
+ return status that will be checked in all callers! */
+ switch (next_page) {
+ default:
+ if (next_page != block->page.id.page_no()) {
+ break;
+ }
+ /* MDEV-20931 FIXME: Check that
+ next_page is within the tablespace
+ bounds! Also check that it is not a
+ change buffer bitmap page. */
+ /* fall through */
+ case 0:
+ case 1:
+ case FIL_NULL:
+ return DB_CORRUPTION;
+ }
- return(DB_SUCCESS);
+ dict_index_t* index = m_pcur.btr_cur.index;
+ buf_block_t* next_block = btr_block_get(
+ page_id_t(block->page.id.space(), next_page),
+ block->page.size, BTR_MODIFY_LEAF, index,
+ &m_mtr);
+
+ if (UNIV_UNLIKELY(!next_block
+ || !fil_page_index_page_check(
+ next_block->frame)
+ || !!dict_index_is_spatial(index)
+ != (fil_page_get_type(
+ next_block->frame)
+ == FIL_PAGE_RTREE)
+ || page_is_comp(next_block->frame)
+ != page_is_comp(block->frame)
+ || btr_page_get_prev(
+ next_block->frame)
+ != block->page.id.page_no())) {
+ return DB_CORRUPTION;
+ }
+
+ btr_leaf_page_release(block, BTR_MODIFY_LEAF, &m_mtr);
+
+ page_cur_set_before_first(next_block,
+ &m_pcur.btr_cur.page_cur);
+
+ ut_d(page_check_dir(next_block->frame));
+ } else {
+ btr_pcur_move_to_next_on_page(&m_pcur);
+ }
+ } while (!btr_pcur_is_on_user_rec(&m_pcur));
+
+ return DB_SUCCESS;
}
/**
@@ -1583,7 +1656,7 @@ inline
dberr_t
PageConverter::adjust_cluster_index_blob_column(
rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint i) UNIV_NOTHROW
{
ulint len;
@@ -1627,7 +1700,7 @@ inline
dberr_t
PageConverter::adjust_cluster_index_blob_columns(
rec_t* rec,
- const ulint* offsets) UNIV_NOTHROW
+ const rec_offs* offsets) UNIV_NOTHROW
{
ut_ad(rec_offs_any_extern(offsets));
@@ -1660,7 +1733,7 @@ inline
dberr_t
PageConverter::adjust_cluster_index_blob_ref(
rec_t* rec,
- const ulint* offsets) UNIV_NOTHROW
+ const rec_offs* offsets) UNIV_NOTHROW
{
if (rec_offs_any_extern(offsets)) {
dberr_t err;
@@ -1681,7 +1754,7 @@ re-organising the B+tree.
@return true if purge succeeded */
inline
bool
-PageConverter::purge(const ulint* offsets) UNIV_NOTHROW
+PageConverter::purge(const rec_offs* offsets) UNIV_NOTHROW
{
const dict_index_t* index = m_index->m_srv_index;
@@ -1707,7 +1780,7 @@ dberr_t
PageConverter::adjust_cluster_record(
const dict_index_t* index,
rec_t* rec,
- const ulint* offsets) UNIV_NOTHROW
+ const rec_offs* offsets) UNIV_NOTHROW
{
dberr_t err;
@@ -1803,7 +1876,7 @@ PageConverter::update_index_page(
row_index_t* index = find_index(id);
- if (index == 0) {
+ if (UNIV_UNLIKELY(!index)) {
ib::error() << "Page for tablespace " << m_space
<< " is index page with id " << id
<< " but that index is not found from"
@@ -1823,6 +1896,23 @@ PageConverter::update_index_page(
return(DB_SUCCESS);
}
+ if (m_index && block->page.id.page_no() == m_index->m_page_no) {
+ byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE
+ + page;
+ mach_write_to_4(b, block->page.id.space());
+
+ memcpy(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP + FSEG_HDR_SPACE
+ + page, b, 4);
+ if (UNIV_LIKELY_NULL(block->page.zip.data)) {
+ memcpy(&block->page.zip.data[FIL_PAGE_DATA
+ + PAGE_BTR_SEG_TOP
+ + FSEG_HDR_SPACE], b, 4);
+ memcpy(&block->page.zip.data[FIL_PAGE_DATA
+ + PAGE_BTR_SEG_LEAF
+ + FSEG_HDR_SPACE], b, 4);
+ }
+ }
+
#ifdef UNIV_ZIP_DEBUG
ut_a(!is_compressed_table()
|| page_zip_validate(m_page_zip_ptr, page, m_index->m_srv_index));
@@ -2033,7 +2123,7 @@ row_import_discard_changes(
ib::info() << "Discarding tablespace of table "
<< prebuilt->table->name
- << ": " << ut_strerr(err);
+ << ": " << err;
if (trx->dict_operation_lock_mode != RW_X_LATCH) {
ut_a(trx->dict_operation_lock_mode == 0);
@@ -2273,8 +2363,8 @@ row_import_set_sys_max_row_id(
ulint len;
const byte* field;
mem_heap_t* heap = NULL;
- ulint offsets_[1 + REC_OFFS_HEADER_SIZE];
- ulint* offsets;
+ rec_offs offsets_[1 + REC_OFFS_HEADER_SIZE];
+ rec_offs* offsets;
rec_offs_init(offsets_);
@@ -3921,15 +4011,12 @@ row_import_for_mysql(
index entries that point to cached garbage pages in the buffer
pool, because PageConverter::operator() only evicted those
pages that were replaced by the imported pages. We must
- discard all remaining adaptive hash index entries, because the
+ detach any remaining adaptive hash index entries, because the
adaptive hash index must be a subset of the table contents;
false positives are not tolerated. */
- while (buf_LRU_drop_page_hash_for_tablespace(table)) {
- if (trx_is_interrupted(trx)
- || srv_shutdown_state != SRV_SHUTDOWN_NONE) {
- err = DB_INTERRUPTED;
- break;
- }
+ for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index;
+ index = UT_LIST_GET_NEXT(indexes, index)) {
+ index = index->clone_if_needed();
}
#endif /* BTR_CUR_HASH_ADAPT */
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 17c45503cc1..ca04be71953 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -73,8 +73,8 @@ ins_node_create(
{
ins_node_t* node;
- node = static_cast<ins_node_t*>(
- mem_heap_alloc(heap, sizeof(ins_node_t)));
+ node = new (static_cast<ins_node_t*>(
+ mem_heap_alloc(heap, sizeof(ins_node_t)))) ins_node_t;
node->common.type = QUE_NODE_INSERT;
@@ -83,7 +83,6 @@ ins_node_create(
node->state = INS_NODE_SET_IX_LOCK;
node->table = table;
node->index = NULL;
- node->entry = NULL;
node->select = NULL;
@@ -96,35 +95,22 @@ ins_node_create(
return(node);
}
-/***********************************************************//**
-Creates an entry template for each index of a table. */
-static
-void
-ins_node_create_entry_list(
-/*=======================*/
- ins_node_t* node) /*!< in: row insert node */
+/** Create an row template for each index of a table. */
+static void ins_node_create_entry_list(ins_node_t *node)
{
- dict_index_t* index;
- dtuple_t* entry;
-
- ut_ad(node->entry_sys_heap);
-
- UT_LIST_INIT(node->entry_list, &dtuple_t::tuple_list);
-
- /* We will include all indexes (include those corrupted
- secondary indexes) in the entry list. Filteration of
- these corrupted index will be done in row_ins() */
-
- for (index = dict_table_get_first_index(node->table);
- index != 0;
- index = dict_table_get_next_index(index)) {
-
- entry = row_build_index_entry_low(
- node->row, NULL, index, node->entry_sys_heap,
- ROW_BUILD_FOR_INSERT);
-
- UT_LIST_ADD_LAST(node->entry_list, entry);
- }
+ node->entry_list.reserve(UT_LIST_GET_LEN(node->table->indexes));
+
+ for (dict_index_t *index= dict_table_get_first_index(node->table); index;
+ index= dict_table_get_next_index(index))
+ {
+ /* Corrupted or incomplete secondary indexes will be filtered out in
+ row_ins(). */
+ dtuple_t *entry= index->online_status >= ONLINE_INDEX_ABORTED
+ ? dtuple_create(node->entry_sys_heap, 0)
+ : row_build_index_entry_low(node->row, NULL, index, node->entry_sys_heap,
+ ROW_BUILD_FOR_INSERT);
+ node->entry_list.push_back(entry);
+ }
}
/*****************************************************************//**
@@ -189,7 +175,8 @@ ins_node_set_new_row(
{
node->state = INS_NODE_SET_IX_LOCK;
node->index = NULL;
- node->entry = NULL;
+ node->entry_list.clear();
+ node->entry = node->entry_list.end();
node->row = row;
@@ -223,7 +210,7 @@ row_ins_sec_index_entry_by_modify(
depending on whether mtr holds just a leaf
latch or also a tree latch */
btr_cur_t* cursor, /*!< in: B-tree cursor */
- ulint** offsets,/*!< in/out: offsets on cursor->page_cur.rec */
+ rec_offs** offsets,/*!< in/out: offsets on cursor->page_cur.rec */
mem_heap_t* offsets_heap,
/*!< in/out: memory heap that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
@@ -318,7 +305,7 @@ row_ins_clust_index_entry_by_modify(
ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether mtr holds just a leaf
latch or also a tree latch */
- ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
+ rec_offs** offsets,/*!< out: offsets on cursor->page_cur.rec */
mem_heap_t** offsets_heap,
/*!< in/out: pointer to memory heap that can
be emptied, or NULL */
@@ -509,7 +496,7 @@ row_ins_cascade_calc_update_vec(
n_fields_updated = 0;
- bool affects_fulltext = false;
+ bool affects_fulltext = foreign->affects_fulltext();
if (table->fts) {
doc_id_pos = dict_table_get_nth_col_pos(
@@ -630,17 +617,6 @@ row_ins_cascade_calc_update_vec(
padded_data, min_size);
}
- /* Check whether the current column has
- FTS index on it */
- if (table->fts
- && dict_table_is_fts_column(
- table->fts->indexes,
- dict_col_get_no(col),
- dict_col_is_virtual(col))
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- }
-
/* If Doc ID is updated, check whether the
Doc ID is valid */
if (table->fts
@@ -929,28 +905,24 @@ row_ins_invalidate_query_cache(
@param[in] index clustered index of child table
@param[in] node parent update node
@param[in] foreign foreign key information
-@param[out] err error code. */
+@return error code. */
static
-void
+dberr_t
row_ins_foreign_fill_virtual(
upd_node_t* cascade,
const rec_t* rec,
dict_index_t* index,
upd_node_t* node,
- dict_foreign_t* foreign,
- dberr_t* err)
+ dict_foreign_t* foreign)
{
THD* thd = current_thd;
row_ext_t* ext;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
- const ulint* offsets =
+ const rec_offs* offsets =
rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &cascade->heap);
- mem_heap_t* v_heap = NULL;
TABLE* mysql_table= NULL;
- VCOL_STORAGE* vcol_storage= NULL;
- byte* record;
upd_t* update = cascade->update;
ulint n_v_fld = index->table->n_v_def;
ulint n_diff;
@@ -962,20 +934,16 @@ row_ins_foreign_fill_virtual(
&ext, cascade->heap);
n_diff = update->n_fields;
- update->n_fields += n_v_fld;
-
if (index->table->vc_templ == NULL) {
/** This can occur when there is a cascading
delete or update after restart. */
innobase_init_vc_templ(index->table);
}
- if (innobase_allocate_row_for_vcol(thd, index, &v_heap,
- &mysql_table,
- &record, &vcol_storage)) {
- if (v_heap) mem_heap_free(v_heap);
- *err = DB_OUT_OF_MEMORY;
- goto func_exit;
+ ib_vcol_row vc(NULL);
+ uchar *record = vc.record(thd, index, &mysql_table);
+ if (!record) {
+ return DB_OUT_OF_MEMORY;
}
for (ulint i = 0; i < n_v_fld; i++) {
@@ -991,15 +959,14 @@ row_ins_foreign_fill_virtual(
dfield_t* vfield = innobase_get_computed_value(
update->old_vrow, col, index,
- &v_heap, update->heap, NULL, thd, mysql_table,
+ &vc.heap, update->heap, NULL, thd, mysql_table,
record, NULL, NULL, NULL);
if (vfield == NULL) {
- *err = DB_COMPUTE_VALUE_FAILED;
- goto func_exit;
+ return DB_COMPUTE_VALUE_FAILED;
}
- upd_field = upd_get_nth_field(update, n_diff);
+ upd_field = update->fields + n_diff;
upd_field->old_v_val = static_cast<dfield_t*>(
mem_heap_alloc(cascade->heap,
@@ -1009,42 +976,31 @@ row_ins_foreign_fill_virtual(
upd_field_set_v_field_no(upd_field, i, index);
- if (node->is_delete
- ? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
- : (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) {
-
- dfield_set_null(&upd_field->new_val);
- }
-
- if (!node->is_delete
- && (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)) {
-
- dfield_t* new_vfield = innobase_get_computed_value(
- update->old_vrow, col, index,
- &v_heap, update->heap, NULL, thd,
- mysql_table, record, NULL,
- node->update, foreign);
+ bool set_null =
+ node->is_delete
+ ? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
+ : (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL);
- if (new_vfield == NULL) {
- *err = DB_COMPUTE_VALUE_FAILED;
- goto func_exit;
- }
+ dfield_t* new_vfield = innobase_get_computed_value(
+ update->old_vrow, col, index,
+ &vc.heap, update->heap, NULL, thd,
+ mysql_table, record, NULL,
+ set_null ? update : node->update, foreign);
- dfield_copy(&(upd_field->new_val), new_vfield);
+ if (new_vfield == NULL) {
+ return DB_COMPUTE_VALUE_FAILED;
}
- n_diff++;
+ dfield_copy(&upd_field->new_val, new_vfield);
+
+ if (!dfield_datas_are_binary_equal(
+ upd_field->old_v_val,
+ &upd_field->new_val, 0))
+ n_diff++;
}
update->n_fields = n_diff;
- *err = DB_SUCCESS;
-
-func_exit:
- if (v_heap) {
- if (vcol_storage)
- innobase_free_row_for_vcol(vcol_storage);
- mem_heap_free(v_heap);
- }
+ return DB_SUCCESS;
}
#ifdef WITH_WSREP
@@ -1285,10 +1241,10 @@ row_ins_foreign_check_on_constraint(
update->info_bits = 0;
update->n_fields = foreign->n_fields;
- UNIV_MEM_INVALID(update->fields,
- update->n_fields * sizeof *update->fields);
-
- bool affects_fulltext = false;
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(update->fields,
+ update->n_fields * sizeof *update->fields);
+#endif /* HAVE_valgrind_or_MSAN */
for (ulint i = 0; i < foreign->n_fields; i++) {
upd_field_t* ufield = &update->fields[i];
@@ -1305,51 +1261,25 @@ row_ins_foreign_check_on_constraint(
ufield->orig_len = 0;
ufield->exp = NULL;
dfield_set_null(&ufield->new_val);
-
- if (!affects_fulltext
- && table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i),
- dict_col_is_virtual(
- dict_index_get_nth_col(index, i)))
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- }
}
- if (affects_fulltext) {
+ if (foreign->affects_fulltext()) {
fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
if (foreign->v_cols != NULL
&& foreign->v_cols->size() > 0) {
- row_ins_foreign_fill_virtual(
+ err = row_ins_foreign_fill_virtual(
cascade, clust_rec, clust_index,
- node, foreign, &err);
+ node, foreign);
if (err != DB_SUCCESS) {
goto nonstandard_exit_func;
}
}
- } else if (table->fts && cascade->is_delete) {
- /* DICT_FOREIGN_ON_DELETE_CASCADE case */
- bool affects_fulltext = false;
-
- for (ulint i = 0; i < foreign->n_fields; i++) {
- if (dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i),
- dict_col_is_virtual(
- dict_index_get_nth_col(index, i)))
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- break;
- }
- }
-
- if (affects_fulltext) {
- fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
- }
+ } else if (table->fts && cascade->is_delete
+ && foreign->affects_fulltext()) {
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
if (!node->is_delete
@@ -1362,9 +1292,9 @@ row_ins_foreign_check_on_constraint(
node, foreign, tmp_heap, trx);
if (foreign->v_cols && !foreign->v_cols->empty()) {
- row_ins_foreign_fill_virtual(
+ err = row_ins_foreign_fill_virtual(
cascade, clust_rec, clust_index,
- node, foreign, &err);
+ node, foreign);
if (err != DB_SUCCESS) {
goto nonstandard_exit_func;
@@ -1413,20 +1343,20 @@ row_ins_foreign_check_on_constraint(
btr_pcur_store_position(cascade->pcur, mtr);
}
+#ifdef WITH_WSREP
+ err = wsrep_append_foreign_key(trx, foreign, clust_rec, clust_index,
+ FALSE, WSREP_KEY_EXCLUSIVE);
+ if (err != DB_SUCCESS) {
+ ib::info() << "WSREP: foreign key append failed: " << err;
+ goto nonstandard_exit_func;
+ }
+#endif /* WITH_WSREP */
mtr_commit(mtr);
ut_a(cascade->pcur->rel_pos == BTR_PCUR_ON);
cascade->state = UPD_NODE_UPDATE_CLUSTERED;
-#ifdef WITH_WSREP
- err = wsrep_append_foreign_key(trx, foreign, cascade->pcur->old_rec, clust_index,
- FALSE, WSREP_KEY_EXCLUSIVE);
- if (err != DB_SUCCESS) {
- fprintf(stderr,
- "WSREP: foreign key append failed: %d\n", err);
- } else
-#endif /* WITH_WSREP */
err = row_update_cascade_for_mysql(thr, cascade,
foreign->foreign_table);
@@ -1483,7 +1413,7 @@ row_ins_set_shared_rec_lock(
const buf_block_t* block, /*!< in: buffer block of rec */
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
{
dberr_t err;
@@ -1514,7 +1444,7 @@ row_ins_set_exclusive_rec_lock(
const buf_block_t* block, /*!< in: buffer block of rec */
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
{
dberr_t err;
@@ -1561,8 +1491,8 @@ row_ins_check_foreign_constraint(
mtr_t mtr;
trx_t* trx = thr_get_trx(thr);
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
bool skip_gap_lock;
@@ -1779,7 +1709,7 @@ row_ins_check_foreign_constraint(
if (check_ref) {
err = DB_SUCCESS;
#ifdef WITH_WSREP
- if (!wsrep_on(trx->mysql_thd)) {
+ if (!trx->is_wsrep()) {
goto end_scan;
}
enum wsrep_key_type key_type;
@@ -1931,6 +1861,39 @@ exit_func:
DBUG_RETURN(err);
}
+/** Sets the values of the dtuple fields in ref_entry from the values of
+foreign columns in entry.
+@param[in] foreign foreign key constraint
+@param[in] index clustered index
+@param[in] entry tuple of clustered index
+@param[in] ref_entry tuple of foreign columns
+@return true if all foreign key fields present in clustered index */
+static
+bool row_ins_foreign_index_entry(dict_foreign_t *foreign,
+ const dict_index_t *index,
+ const dtuple_t *entry,
+ dtuple_t *ref_entry)
+{
+ for (ulint i= 0; i < foreign->n_fields; i++)
+ {
+ for (ulint j= 0; j < index->n_fields; j++)
+ {
+ const char *col_name= dict_table_get_col_name(
+ index->table, dict_index_get_nth_col_no(index, j));
+ if (0 == innobase_strcasecmp(col_name, foreign->foreign_col_names[i]))
+ {
+ dfield_copy(&ref_entry->fields[i], &entry->fields[j]);
+ goto got_match;
+ }
+ }
+ return false;
+got_match:
+ continue;
+ }
+
+ return true;
+}
+
/***************************************************************//**
Checks if foreign key constraints fail for an index entry. If index
is not mentioned in any constraint, this function does nothing,
@@ -1949,9 +1912,10 @@ row_ins_check_foreign_constraints(
que_thr_t* thr) /*!< in: query thread */
{
dict_foreign_t* foreign;
- dberr_t err;
+ dberr_t err = DB_SUCCESS;
trx_t* trx;
ibool got_s_lock = FALSE;
+ mem_heap_t* heap = NULL;
DBUG_ASSERT(index->is_primary() == pk);
@@ -1961,13 +1925,36 @@ row_ins_check_foreign_constraints(
"foreign_constraint_check_for_ins");
for (dict_foreign_set::iterator it = table->foreign_set.begin();
- it != table->foreign_set.end();
+ err == DB_SUCCESS && it != table->foreign_set.end();
++it) {
foreign = *it;
if (foreign->foreign_index == index
|| (pk && !foreign->foreign_index)) {
+
+ dtuple_t* ref_tuple = entry;
+ if (UNIV_UNLIKELY(!foreign->foreign_index)) {
+ /* Change primary key entry to
+ foreign key index entry */
+ if (!heap) {
+ heap = mem_heap_create(1000);
+ } else {
+ mem_heap_empty(heap);
+ }
+
+ ref_tuple = dtuple_create(
+ heap, foreign->n_fields);
+ dtuple_set_n_fields_cmp(
+ ref_tuple, foreign->n_fields);
+ if (!row_ins_foreign_index_entry(
+ foreign, index, entry, ref_tuple)) {
+ err = DB_NO_REFERENCED_ROW;
+ break;
+ }
+
+ }
+
dict_table_t* ref_table = NULL;
dict_table_t* referenced_table
= foreign->referenced_table;
@@ -1997,7 +1984,7 @@ row_ins_check_foreign_constraints(
table from being dropped while the check is running. */
err = row_ins_check_foreign_constraint(
- TRUE, foreign, table, entry, thr);
+ TRUE, foreign, table, ref_tuple, thr);
if (referenced_table) {
my_atomic_addlint(
@@ -2012,15 +1999,14 @@ row_ins_check_foreign_constraints(
if (ref_table != NULL) {
dict_table_close(ref_table, FALSE, FALSE);
}
-
- if (err != DB_SUCCESS) {
-
- return(err);
- }
}
}
- return(DB_SUCCESS);
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+
+ return err;
}
/***************************************************************//**
@@ -2036,7 +2022,7 @@ row_ins_dupl_error_with_rec(
the record! */
const dtuple_t* entry, /*!< in: entry to insert */
dict_index_t* index, /*!< in: index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint matched_fields;
ulint n_unique;
@@ -2095,9 +2081,11 @@ row_ins_scan_sec_index_for_duplicate(
btr_pcur_t pcur;
dberr_t err = DB_SUCCESS;
ulint allow_duplicates;
- ulint* offsets = NULL;
+ rec_offs offsets_[REC_OFFS_SEC_INDEX_SIZE];
+ rec_offs* offsets = offsets_;
DBUG_ENTER("row_ins_scan_sec_index_for_duplicate");
+ rec_offs_init(offsets_);
ut_ad(s_latch == rw_lock_own_flagged(
&index->lock, RW_LOCK_FLAG_S | RW_LOCK_FLAG_SX));
@@ -2227,7 +2215,7 @@ row_ins_duplicate_online(
ulint n_uniq, /*!< in: offset of DB_TRX_ID */
const dtuple_t* entry, /*!< in: entry that is being inserted */
const rec_t* rec, /*!< in: clustered index record */
- ulint* offsets)/*!< in/out: rec_get_offsets(rec) */
+ rec_offs* offsets)/*!< in/out: rec_get_offsets(rec) */
{
ulint fields = 0;
@@ -2266,7 +2254,7 @@ row_ins_duplicate_error_in_clust_online(
ulint n_uniq, /*!< in: offset of DB_TRX_ID */
const dtuple_t* entry, /*!< in: entry that is being inserted */
const btr_cur_t*cursor, /*!< in: cursor on insert position */
- ulint** offsets,/*!< in/out: rec_get_offsets(rec) */
+ rec_offs** offsets,/*!< in/out: rec_get_offsets(rec) */
mem_heap_t** heap) /*!< in/out: heap for offsets */
{
dberr_t err = DB_SUCCESS;
@@ -2313,8 +2301,8 @@ row_ins_duplicate_error_in_clust(
ulint n_unique;
trx_t* trx = thr_get_trx(thr);
mem_heap_t*heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(dict_index_is_clust(cursor->index));
@@ -2487,7 +2475,7 @@ dberr_t
row_ins_index_entry_big_rec(
const dtuple_t* entry,
const big_rec_t* big_rec,
- ulint* offsets,
+ rec_offs* offsets,
mem_heap_t** heap,
dict_index_t* index,
const void* thd __attribute__((unused)))
@@ -2562,8 +2550,8 @@ row_ins_clust_index_entry_low(
mtr_t mtr;
ib_uint64_t auto_inc = 0;
mem_heap_t* offsets_heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
DBUG_ENTER("row_ins_clust_index_entry_low");
@@ -2841,8 +2829,8 @@ row_ins_sec_index_entry_low(
dberr_t err = DB_SUCCESS;
ulint n_unique;
mtr_t mtr;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
rtr_info_t rtr_info;
@@ -2905,7 +2893,7 @@ row_ins_sec_index_entry_low(
err = btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_RTREE_INSERT,
search_mode,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, 0, __FILE__, __LINE__, &mtr, 0);
if (mode == BTR_MODIFY_LEAF && rtr_info.mbr_adj) {
mtr_commit(&mtr);
@@ -2920,7 +2908,7 @@ row_ins_sec_index_entry_low(
err = btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_RTREE_INSERT,
search_mode,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, 0, __FILE__, __LINE__, &mtr, 0);
mode = BTR_MODIFY_TREE;
}
@@ -2932,7 +2920,7 @@ row_ins_sec_index_entry_low(
err = btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_LE,
search_mode,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, 0, __FILE__, __LINE__, &mtr, 0);
}
if (err != DB_SUCCESS) {
@@ -3026,7 +3014,7 @@ row_ins_sec_index_entry_low(
index, 0, entry, PAGE_CUR_LE,
(search_mode
& ~(BTR_INSERT | BTR_IGNORE_SEC_UNIQUE)),
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, 0, __FILE__, __LINE__, &mtr, 0);
}
if (row_ins_must_modify_rec(&cursor)) {
@@ -3411,15 +3399,16 @@ row_ins_index_entry_step(
ut_ad(dtuple_check_typed(node->row));
- err = row_ins_index_entry_set_vals(node->index, node->entry, node->row);
+ err = row_ins_index_entry_set_vals(node->index, *node->entry,
+ node->row);
if (err != DB_SUCCESS) {
DBUG_RETURN(err);
}
- ut_ad(dtuple_check_typed(node->entry));
+ ut_ad(dtuple_check_typed(*node->entry));
- err = row_ins_index_entry(node->index, node->entry, thr);
+ err = row_ins_index_entry(node->index, *node->entry, thr);
DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
"after_row_ins_index_entry_step");
@@ -3537,7 +3526,8 @@ row_ins(
row_ins_alloc_row_id_step(node);
node->index = dict_table_get_first_index(node->table);
- node->entry = UT_LIST_GET_FIRST(node->entry_list);
+ ut_ad(node->entry_list.empty() == false);
+ node->entry = node->entry_list.begin();
if (node->ins_type == INS_SEARCHED) {
@@ -3563,20 +3553,16 @@ row_ins(
}
node->index = dict_table_get_next_index(node->index);
- node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);
-
- DBUG_EXECUTE_IF(
- "row_ins_skip_sec",
- node->index = NULL; node->entry = NULL; break;);
+ ++node->entry;
/* Skip corrupted secondary index and its entry */
while (node->index && node->index->is_corrupted()) {
node->index = dict_table_get_next_index(node->index);
- node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);
+ ++node->entry;
}
}
- ut_ad(node->entry == NULL);
+ ut_ad(node->entry == node->entry_list.end());
node->state = INS_NODE_ALLOC_ROW_ID;
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 6da08872a9a..986cac54540 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -323,7 +323,9 @@ row_log_online_op(
goto err_exit;
}
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
+#endif /* HAVE_valgrind_or_MSAN */
ut_ad(log->tail.bytes < srv_sort_buf_size);
avail_size = srv_sort_buf_size - log->tail.bytes;
@@ -373,7 +375,7 @@ row_log_online_op(
log->tail.buf, avail_size);
}
- UNIV_MEM_ASSERT_RW(buf, srv_sort_buf_size);
+ MEM_CHECK_DEFINED(buf, srv_sort_buf_size);
if (row_log_tmpfile(log) < 0) {
log->error = DB_OUT_OF_MEMORY;
@@ -407,8 +409,10 @@ write_failed:
index->type |= DICT_CORRUPT;
}
- UNIV_MEM_INVALID(log->tail.block, srv_sort_buf_size);
- UNIV_MEM_INVALID(buf, srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.block, srv_sort_buf_size);
+ MEM_UNDEFINED(buf, srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
memcpy(log->tail.block, log->tail.buf + avail_size,
mrec_size - avail_size);
@@ -418,7 +422,9 @@ write_failed:
ut_ad(b == log->tail.block + log->tail.bytes);
}
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
+#endif /* HAVE_valgrind_or_MSAN */
err_exit:
mutex_exit(&log->mutex);
}
@@ -450,7 +456,9 @@ row_log_table_open(
{
mutex_enter(&log->mutex);
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
+#endif /* HAVE_valgrind_or_MSAN */
if (log->error != DB_SUCCESS) {
err_exit:
@@ -510,7 +518,7 @@ row_log_table_close_func(
memcpy(buf + log->tail.bytes, log->tail.buf, avail);
}
- UNIV_MEM_ASSERT_RW(buf, srv_sort_buf_size);
+ MEM_CHECK_DEFINED(buf, srv_sort_buf_size);
if (row_log_tmpfile(log) < 0) {
log->error = DB_OUT_OF_MEMORY;
@@ -541,8 +549,10 @@ row_log_table_close_func(
write_failed:
log->error = DB_ONLINE_LOG_TOO_BIG;
}
- UNIV_MEM_INVALID(log->tail.block, srv_sort_buf_size);
- UNIV_MEM_INVALID(buf, srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.block, srv_sort_buf_size);
+ MEM_UNDEFINED(buf, srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
memcpy(log->tail.block, log->tail.buf + avail, size - avail);
log->tail.bytes = size - avail;
} else {
@@ -551,7 +561,9 @@ write_failed:
}
log->tail.total += size;
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
+#endif /* HAVE_valgrind_or_MSAN */
err_exit:
mutex_exit(&log->mutex);
@@ -592,7 +604,7 @@ row_log_table_delete(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index) */
const byte* sys) /*!< in: DB_TRX_ID,DB_ROLL_PTR that should
be logged, or NULL to use those in rec */
{
@@ -835,7 +847,7 @@ row_log_table_low(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index) */
bool insert, /*!< in: true if insert, false if update */
const dtuple_t* old_pk) /*!< in: old PRIMARY KEY value (if !insert
and a PRIMARY KEY is being created) */
@@ -948,7 +960,7 @@ row_log_table_update(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index) */
const dtuple_t* old_pk) /*!< in: row_log_table_get_pk()
before the update */
{
@@ -999,7 +1011,7 @@ row_log_table_get_pk_col(
dfield_t* dfield,
mem_heap_t* heap,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
ulint i,
const page_size_t& page_size,
ulint max_len)
@@ -1053,7 +1065,7 @@ row_log_table_get_pk(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index) */
byte* sys, /*!< out: DB_TRX_ID,DB_ROLL_PTR for
row_log_table_delete(), or NULL */
mem_heap_t** heap) /*!< in/out: memory heap where allocated */
@@ -1246,7 +1258,7 @@ row_log_table_insert(
page X-latched */
dict_index_t* index, /*!< in/out: clustered index, S-latched
or X-latched */
- const ulint* offsets)/*!< in: rec_get_offsets(rec,index) */
+ const rec_offs* offsets)/*!< in: rec_get_offsets(rec,index) */
{
row_log_table_low(rec, index, offsets, true, NULL);
}
@@ -1337,7 +1349,7 @@ row_log_table_apply_convert_mrec(
/*=============================*/
const mrec_t* mrec, /*!< in: merge record */
dict_index_t* index, /*!< in: index of mrec */
- const ulint* offsets, /*!< in: offsets of mrec */
+ const rec_offs* offsets, /*!< in: offsets of mrec */
const row_log_t* log, /*!< in: rebuild context */
mem_heap_t* heap, /*!< in/out: memory heap */
trx_id_t trx_id, /*!< in: DB_TRX_ID of mrec */
@@ -1569,7 +1581,7 @@ row_log_table_apply_insert(
/*=======================*/
que_thr_t* thr, /*!< in: query graph */
const mrec_t* mrec, /*!< in: record to insert */
- const ulint* offsets, /*!< in: offsets of mrec */
+ const rec_offs* offsets, /*!< in: offsets of mrec */
mem_heap_t* offsets_heap, /*!< in/out: memory heap
that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
@@ -1621,7 +1633,7 @@ row_log_table_apply_delete_low(
/*===========================*/
btr_pcur_t* pcur, /*!< in/out: B-tree cursor,
will be trashed */
- const ulint* offsets, /*!< in: offsets on pcur */
+ const rec_offs* offsets, /*!< in: offsets on pcur */
mem_heap_t* heap, /*!< in/out: memory heap */
mtr_t* mtr) /*!< in/out: mini-transaction,
will be committed */
@@ -1714,7 +1726,7 @@ row_log_table_apply_delete(
DB_TRX_ID in the new
clustered index */
const mrec_t* mrec, /*!< in: merge record */
- const ulint* moffsets, /*!< in: offsets of mrec */
+ const rec_offs* moffsets, /*!< in: offsets of mrec */
mem_heap_t* offsets_heap, /*!< in/out: memory heap
that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
@@ -1725,7 +1737,7 @@ row_log_table_apply_delete(
dtuple_t* old_pk;
mtr_t mtr;
btr_pcur_t pcur;
- ulint* offsets;
+ rec_offs* offsets;
ut_ad(rec_offs_n_fields(moffsets)
== dict_index_get_n_unique(index) + 2);
@@ -1835,7 +1847,7 @@ row_log_table_apply_update(
DB_TRX_ID in the new
clustered index */
const mrec_t* mrec, /*!< in: new value */
- const ulint* offsets, /*!< in: offsets of mrec */
+ const rec_offs* offsets, /*!< in: offsets of mrec */
mem_heap_t* offsets_heap, /*!< in/out: memory heap
that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
@@ -1973,7 +1985,7 @@ func_exit_committed:
}
/* Prepare to update (or delete) the record. */
- ulint* cur_offsets = rec_get_offsets(
+ rec_offs* cur_offsets = rec_get_offsets(
btr_pcur_get_rec(&pcur), index, NULL, true,
ULINT_UNDEFINED, &offsets_heap);
@@ -2213,7 +2225,7 @@ row_log_table_apply_op(
mem_heap_t* heap, /*!< in/out: memory heap */
const mrec_t* mrec, /*!< in: merge record */
const mrec_t* mrec_end, /*!< in: end of buffer */
- ulint* offsets) /*!< in/out: work area
+ rec_offs* offsets) /*!< in/out: work area
for parsing mrec */
{
row_log_t* log = dup->index->online_log;
@@ -2531,7 +2543,7 @@ row_log_table_apply_ops(
const mrec_t* next_mrec_end;
mem_heap_t* heap;
mem_heap_t* offsets_heap;
- ulint* offsets;
+ rec_offs* offsets;
bool has_index_lock;
dict_index_t* index = const_cast<dict_index_t*>(
dup->index);
@@ -2557,11 +2569,13 @@ row_log_table_apply_ops(
ut_ad(new_trx_id_col > 0);
ut_ad(new_trx_id_col != ULINT_UNDEFINED);
- UNIV_MEM_INVALID(&mrec_end, sizeof mrec_end);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&mrec_end, sizeof mrec_end);
+#endif /* HAVE_valgrind_or_MSAN */
- offsets = static_cast<ulint*>(ut_malloc_nokey(i * sizeof *offsets));
- offsets[0] = i;
- offsets[1] = dict_index_get_n_fields(index);
+ offsets = static_cast<rec_offs*>(ut_malloc_nokey(i * sizeof *offsets));
+ rec_offs_set_n_alloc(offsets, i);
+ rec_offs_set_n_fields(offsets, dict_index_get_n_fields(index));
heap = mem_heap_create(UNIV_PAGE_SIZE);
offsets_heap = mem_heap_create(UNIV_PAGE_SIZE);
@@ -3073,7 +3087,7 @@ row_log_apply_op_low(
{
mtr_t mtr;
btr_cur_t cursor;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
ut_ad(!dict_index_is_clust(index));
@@ -3102,7 +3116,7 @@ row_log_apply_op_low(
? BTR_MODIFY_TREE
: BTR_MODIFY_LEAF,
&cursor, 0, __FILE__, __LINE__,
- &mtr);
+ &mtr, 0);
ut_ad(dict_index_get_n_unique(index) > 0);
/* This test is somewhat similar to row_ins_must_modify_rec(),
@@ -3151,7 +3165,7 @@ row_log_apply_op_low(
btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_LE,
BTR_MODIFY_TREE, &cursor, 0,
- __FILE__, __LINE__, &mtr);
+ __FILE__, __LINE__, &mtr, 0);
/* No other thread than the current one
is allowed to modify the index tree.
@@ -3254,7 +3268,7 @@ insert_the_rec:
btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_LE,
BTR_MODIFY_TREE, &cursor, 0,
- __FILE__, __LINE__, &mtr);
+ __FILE__, __LINE__, &mtr, 0);
}
/* We already determined that the
@@ -3307,14 +3321,13 @@ row_log_apply_op(
in exclusive mode */
const mrec_t* mrec, /*!< in: merge record */
const mrec_t* mrec_end, /*!< in: end of buffer */
- ulint* offsets) /*!< in/out: work area for
+ rec_offs* offsets) /*!< in/out: work area for
rec_init_offsets_temp() */
{
enum row_op op;
ulint extra_size;
ulint data_size;
- ulint n_ext;
dtuple_t* entry;
trx_id_t trx_id;
@@ -3392,10 +3405,10 @@ corrupted:
}
entry = row_rec_to_index_entry_low(
- mrec - data_size, index, offsets, &n_ext, heap);
+ mrec - data_size, index, offsets, heap);
/* Online index creation is only implemented for secondary
indexes, which never contain off-page columns. */
- ut_ad(n_ext == 0);
+ ut_ad(dtuple_get_n_ext(entry) == 0);
row_log_apply_op_low(index, dup, error, offsets_heap,
has_index_lock, op, trx_id, entry);
@@ -3426,7 +3439,7 @@ row_log_apply_ops(
const mrec_t* next_mrec_end;
mem_heap_t* offsets_heap;
mem_heap_t* heap;
- ulint* offsets;
+ rec_offs* offsets;
bool has_index_lock;
const ulint i = 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index);
@@ -3435,11 +3448,13 @@ row_log_apply_ops(
ut_ad(!index->is_committed());
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X));
ut_ad(index->online_log);
- UNIV_MEM_INVALID(&mrec_end, sizeof mrec_end);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&mrec_end, sizeof mrec_end);
+#endif /* HAVE_valgrind_or_MSAN */
- offsets = static_cast<ulint*>(ut_malloc_nokey(i * sizeof *offsets));
- offsets[0] = i;
- offsets[1] = dict_index_get_n_fields(index);
+ offsets = static_cast<rec_offs*>(ut_malloc_nokey(i * sizeof *offsets));
+ rec_offs_set_n_alloc(offsets, i);
+ rec_offs_set_n_fields(offsets, dict_index_get_n_fields(index));
offsets_heap = mem_heap_create(UNIV_PAGE_SIZE);
heap = mem_heap_create(UNIV_PAGE_SIZE);
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 1e7a6156479..6571a7fbfec 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -46,6 +46,9 @@ Completed by Sunny Bains and Marko Makela
#include "row0vers.h"
#include "handler0alter.h"
#include "btr0bulk.h"
+#ifdef BTR_CUR_ADAPT
+# include "btr0sea.h"
+#endif /* BTR_CUR_ADAPT */
#include "ut0stage.h"
#include "fil0crypt.h"
@@ -120,7 +123,7 @@ public:
btr_cur_t ins_cur;
mtr_t mtr;
rtr_info_t rtr_info;
- ulint* ins_offsets = NULL;
+ rec_offs* ins_offsets = NULL;
dberr_t error = DB_SUCCESS;
dtuple_t* dtuple;
ulint count = 0;
@@ -162,7 +165,7 @@ public:
PAGE_CUR_RTREE_INSERT,
BTR_MODIFY_LEAF, &ins_cur,
0, __FILE__, __LINE__,
- &mtr);
+ &mtr, 0);
/* It need to update MBR in parent entry,
so change search mode to BTR_MODIFY_TREE */
@@ -178,7 +181,7 @@ public:
m_index, 0, dtuple,
PAGE_CUR_RTREE_INSERT,
BTR_MODIFY_TREE, &ins_cur, 0,
- __FILE__, __LINE__, &mtr);
+ __FILE__, __LINE__, &mtr, 0);
}
error = btr_cur_optimistic_insert(
@@ -201,8 +204,7 @@ public:
PAGE_CUR_RTREE_INSERT,
BTR_MODIFY_TREE,
&ins_cur, 0,
- __FILE__, __LINE__, &mtr);
-
+ __FILE__, __LINE__, &mtr, 0);
error = btr_cur_pessimistic_insert(
flag, &ins_cur, &ins_offsets,
@@ -518,8 +520,7 @@ row_merge_buf_add(
ulint bucket = 0;
doc_id_t write_doc_id;
ulint n_row_added = 0;
- VCOL_STORAGE* vcol_storage= 0;
- byte* record;
+ VCOL_STORAGE vcol_storage;
DBUG_ENTER("row_merge_buf_add");
if (buf->n_tuples >= buf->max_tuples) {
@@ -553,23 +554,16 @@ row_merge_buf_add(
for (i = 0; i < n_fields; i++, field++, ifield++) {
ulint len;
- const dict_col_t* col;
- ulint col_no;
ulint fixed_len;
const dfield_t* row_field;
-
- col = ifield->col;
- const dict_v_col_t* v_col = NULL;
- if (dict_col_is_virtual(col)) {
- v_col = reinterpret_cast<const dict_v_col_t*>(col);
- }
-
- col_no = dict_col_get_no(col);
+ const dict_col_t* const col = ifield->col;
+ const dict_v_col_t* const v_col = col->is_virtual()
+ ? reinterpret_cast<const dict_v_col_t*>(col)
+ : NULL;
/* Process the Doc ID column */
- if (*doc_id > 0
- && col_no == index->table->fts->doc_col
- && !dict_col_is_virtual(col)) {
+ if (!v_col && *doc_id
+ && col->ind == index->table->fts->doc_col) {
fts_write_doc_id((byte*) &write_doc_id, *doc_id);
/* Note: field->data now points to a value on the
@@ -588,12 +582,15 @@ row_merge_buf_add(
field->type.len = ifield->col->len;
} else {
/* Use callback to get the virtual column value */
- if (dict_col_is_virtual(col)) {
+ if (v_col) {
dict_index_t* clust_index
= dict_table_get_first_index(new_table);
- if (!vcol_storage &&
- innobase_allocate_row_for_vcol(trx->mysql_thd, clust_index, v_heap, &my_table, &record, &vcol_storage)) {
+ if (!vcol_storage.innobase_record &&
+ !innobase_allocate_row_for_vcol(
+ trx->mysql_thd, clust_index,
+ v_heap, &my_table,
+ &vcol_storage)) {
*err = DB_OUT_OF_MEMORY;
goto error;
}
@@ -601,8 +598,8 @@ row_merge_buf_add(
row_field = innobase_get_computed_value(
row, v_col, clust_index,
v_heap, NULL, ifield, trx->mysql_thd,
- my_table, record, old_table, NULL,
- NULL);
+ my_table, vcol_storage.innobase_record,
+ old_table, NULL, NULL);
if (row_field == NULL) {
*err = DB_COMPUTE_VALUE_FAILED;
@@ -610,7 +607,8 @@ row_merge_buf_add(
}
dfield_copy(field, row_field);
} else {
- row_field = dtuple_get_nth_field(row, col_no);
+ row_field = dtuple_get_nth_field(row,
+ col->ind);
dfield_copy(field, row_field);
}
@@ -716,7 +714,7 @@ row_merge_buf_add(
} else if (!ext) {
} else if (dict_index_is_clust(index)) {
/* Flag externally stored fields. */
- const byte* buf = row_ext_lookup(ext, col_no,
+ const byte* buf = row_ext_lookup(ext, col->ind,
&len);
if (UNIV_LIKELY_NULL(buf)) {
ut_a(buf != field_ref_zero);
@@ -727,9 +725,9 @@ row_merge_buf_add(
len = dfield_get_len(field);
}
}
- } else if (!dict_col_is_virtual(col)) {
+ } else if (!v_col) {
/* Only non-virtual column are stored externally */
- const byte* buf = row_ext_lookup(ext, col_no,
+ const byte* buf = row_ext_lookup(ext, col->ind,
&len);
if (UNIV_LIKELY_NULL(buf)) {
ut_a(buf != field_ref_zero);
@@ -844,13 +842,13 @@ row_merge_buf_add(
}
end:
- if (vcol_storage)
- innobase_free_row_for_vcol(vcol_storage);
+ if (vcol_storage.innobase_record)
+ innobase_free_row_for_vcol(&vcol_storage);
DBUG_RETURN(n_row_added);
error:
- if (vcol_storage)
- innobase_free_row_for_vcol(vcol_storage);
+ if (vcol_storage.innobase_record)
+ innobase_free_row_for_vcol(&vcol_storage);
DBUG_RETURN(0);
}
@@ -1025,11 +1023,11 @@ row_merge_buf_write(
ut_a(b < &block[srv_sort_buf_size]);
ut_a(b == &block[0] + buf->total_size);
*b++ = 0;
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
/* The rest of the block is uninitialized. Initialize it
to avoid bogus warnings. */
memset(b, 0xff, &block[srv_sort_buf_size] - b);
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
DBUG_LOG("ib_merge_sort",
"write " << reinterpret_cast<const void*>(b) << ','
<< of->fd << ',' << of->offset << " EOF");
@@ -1046,8 +1044,8 @@ row_merge_heap_create(
/*==================*/
const dict_index_t* index, /*!< in: record descriptor */
mrec_buf_t** buf, /*!< out: 3 buffers */
- ulint** offsets1, /*!< out: offsets */
- ulint** offsets2) /*!< out: offsets */
+ rec_offs** offsets1, /*!< out: offsets */
+ rec_offs** offsets2) /*!< out: offsets */
{
ulint i = 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index);
@@ -1056,13 +1054,15 @@ row_merge_heap_create(
*buf = static_cast<mrec_buf_t*>(
mem_heap_alloc(heap, 3 * sizeof **buf));
- *offsets1 = static_cast<ulint*>(
+ *offsets1 = static_cast<rec_offs*>(
mem_heap_alloc(heap, i * sizeof **offsets1));
- *offsets2 = static_cast<ulint*>(
+ *offsets2 = static_cast<rec_offs*>(
mem_heap_alloc(heap, i * sizeof **offsets2));
- (*offsets1)[0] = (*offsets2)[0] = i;
- (*offsets1)[1] = (*offsets2)[1] = dict_index_get_n_fields(index);
+ rec_offs_set_n_alloc(*offsets1, i);
+ rec_offs_set_n_alloc(*offsets2, i);
+ rec_offs_set_n_fields(*offsets1, dict_index_get_n_fields(index));
+ rec_offs_set_n_fields(*offsets2, dict_index_get_n_fields(index));
return(heap);
}
@@ -1179,7 +1179,7 @@ row_merge_read_rec(
const mrec_t** mrec, /*!< out: pointer to merge record,
or NULL on end of list
(non-NULL on I/O error) */
- ulint* offsets,/*!< out: offsets of mrec */
+ rec_offs* offsets,/*!< out: offsets of mrec */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
{
@@ -1190,7 +1190,7 @@ row_merge_read_rec(
ut_ad(b >= &block[0]);
ut_ad(b < &block[srv_sort_buf_size]);
- ut_ad(*offsets == 1 + REC_OFFS_HEADER_SIZE
+ ut_ad(rec_offs_get_n_alloc(offsets) == 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index));
DBUG_ENTER("row_merge_read_rec");
@@ -1297,12 +1297,7 @@ err_exit:
memcpy(*buf, b, avail_size);
*mrec = *buf + extra_size;
- /* We cannot invoke rec_offs_make_valid() here, because there
- are no REC_N_NEW_EXTRA_BYTES between extra_size and data_size.
- Similarly, rec_offs_validate() would fail, because it invokes
- rec_get_status(). */
- ut_d(offsets[2] = (ulint) *mrec);
- ut_d(offsets[3] = (ulint) index);
+ rec_init_offsets_temp(*mrec, index, offsets);
if (!row_merge_read(fd, ++(*foffs), block,
crypt_block,
@@ -1341,7 +1336,7 @@ row_merge_write_rec_low(
ulint foffs, /*!< in: file offset */
#endif /* !DBUG_OFF */
const mrec_t* mrec, /*!< in: record to write */
- const ulint* offsets)/*!< in: offsets of mrec */
+ const rec_offs* offsets)/*!< in: offsets of mrec */
#ifdef DBUG_OFF
# define row_merge_write_rec_low(b, e, size, fd, foffs, mrec, offsets) \
row_merge_write_rec_low(b, e, mrec, offsets)
@@ -1383,7 +1378,7 @@ row_merge_write_rec(
int fd, /*!< in: file descriptor */
ulint* foffs, /*!< in/out: file offset */
const mrec_t* mrec, /*!< in: record to write */
- const ulint* offsets,/*!< in: offsets of mrec */
+ const rec_offs* offsets,/*!< in: offsets of mrec */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
{
@@ -1426,7 +1421,9 @@ row_merge_write_rec(
return(NULL);
}
- UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&block[0], srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
/* Copy the rest. */
b = &block[0];
@@ -1467,20 +1464,19 @@ row_merge_write_eof(
",fd=" << fd << ',' << *foffs);
*b++ = 0;
- UNIV_MEM_ASSERT_RW(&block[0], b - &block[0]);
- UNIV_MEM_ASSERT_W(&block[0], srv_sort_buf_size);
+ MEM_CHECK_DEFINED(&block[0], b - &block[0]);
+ MEM_CHECK_ADDRESSABLE(&block[0], srv_sort_buf_size);
-#ifdef UNIV_DEBUG_VALGRIND
- /* The rest of the block is uninitialized. Initialize it
- to avoid bogus warnings. */
- memset(b, 0xff, &block[srv_sort_buf_size] - b);
-#endif /* UNIV_DEBUG_VALGRIND */
+ /* The rest of the block is uninitialized. Silence warnings. */
+ MEM_MAKE_DEFINED(b, &block[srv_sort_buf_size] - b);
if (!row_merge_write(fd, (*foffs)++, block, crypt_block, space)) {
DBUG_RETURN(NULL);
}
- UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&block[0], srv_sort_buf_size);
+#endif
DBUG_RETURN(&block[0]);
}
@@ -1899,7 +1895,7 @@ row_merge_read_clustered_index(
}
const rec_t* rec;
- ulint* offsets;
+ rec_offs* offsets;
dtuple_t* row;
row_ext_t* ext;
page_cur_t* cur = btr_pcur_get_page_cur(&pcur);
@@ -2551,8 +2547,10 @@ write_buffers:
break;
}
- UNIV_MEM_INVALID(
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(
&block[0], srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
}
}
merge_buf[i] = row_merge_buf_empty(buf);
@@ -2821,8 +2819,8 @@ row_merge_blocks(
const mrec_t* mrec0; /*!< merge rec, points to block[0] or buf[0] */
const mrec_t* mrec1; /*!< merge rec, points to
block[srv_sort_buf_size] or buf[1] */
- ulint* offsets0;/* offsets of mrec0 */
- ulint* offsets1;/* offsets of mrec1 */
+ rec_offs* offsets0;/* offsets of mrec0 */
+ rec_offs* offsets1;/* offsets of mrec1 */
DBUG_ENTER("row_merge_blocks");
DBUG_LOG("ib_merge_sort",
@@ -2939,8 +2937,8 @@ row_merge_blocks_copy(
const byte* b0; /*!< pointer to block[0] */
byte* b2; /*!< pointer to block[2 * srv_sort_buf_size] */
const mrec_t* mrec0; /*!< merge rec, points to block[0] */
- ulint* offsets0;/* offsets of mrec0 */
- ulint* offsets1;/* dummy offsets */
+ rec_offs* offsets0;/* offsets of mrec0 */
+ rec_offs* offsets1;/* dummy offsets */
DBUG_ENTER("row_merge_blocks_copy");
DBUG_LOG("ib_merge_sort",
@@ -3035,10 +3033,10 @@ row_merge(
ulint n_run = 0;
/*!< num of runs generated from this merge */
- UNIV_MEM_ASSERT_W(&block[0], 3 * srv_sort_buf_size);
+ MEM_CHECK_ADDRESSABLE(&block[0], 3 * srv_sort_buf_size);
if (crypt_block) {
- UNIV_MEM_ASSERT_W(&crypt_block[0], 3 * srv_sort_buf_size);
+ MEM_CHECK_ADDRESSABLE(&crypt_block[0], 3 * srv_sort_buf_size);
}
ut_ad(ihalf < file->offset);
@@ -3059,7 +3057,9 @@ row_merge(
foffs0 = 0;
foffs1 = ihalf;
- UNIV_MEM_INVALID(run_offset, *num_run * sizeof *run_offset);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(run_offset, *num_run * sizeof *run_offset);
+#endif /* HAVE_valgrind_or_MSAN */
for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
@@ -3140,7 +3140,9 @@ row_merge(
*tmpfd = file->fd;
*file = of;
- UNIV_MEM_INVALID(&block[0], 3 * srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&block[0], 3 * srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
return(DB_SUCCESS);
}
@@ -3253,7 +3255,7 @@ row_merge_sort(
break;
}
- UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset);
+ MEM_CHECK_DEFINED(run_offset, num_runs * sizeof *run_offset);
} while (num_runs > 1);
ut_free(run_offset);
@@ -3279,7 +3281,7 @@ static
void
row_merge_copy_blobs(
const mrec_t* mrec,
- const ulint* offsets,
+ const rec_offs* offsets,
const page_size_t& page_size,
dtuple_t* tuple,
mem_heap_t* heap)
@@ -3388,7 +3390,7 @@ row_merge_insert_index_tuples(
mem_heap_t* tuple_heap;
dberr_t error = DB_SUCCESS;
ulint foffs = 0;
- ulint* offsets;
+ rec_offs* offsets;
mrec_buf_t* buf;
ulint n_rows = 0;
dtuple_t* dtuple;
@@ -3396,7 +3398,6 @@ row_merge_insert_index_tuples(
double curr_progress = 0;
dict_index_t* old_index = NULL;
const mrec_t* mrec = NULL;
- ulint n_ext = 0;
mtr_t mtr;
@@ -3416,10 +3417,10 @@ row_merge_insert_index_tuples(
ulint i = 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index);
heap = mem_heap_create(sizeof *buf + i * sizeof *offsets);
- offsets = static_cast<ulint*>(
+ offsets = static_cast<rec_offs*>(
mem_heap_alloc(heap, i * sizeof *offsets));
- offsets[0] = i;
- offsets[1] = dict_index_get_n_fields(index);
+ rec_offs_set_n_alloc(offsets, i);
+ rec_offs_set_n_fields(offsets, dict_index_get_n_fields(index));
}
if (row_buf != NULL) {
@@ -3462,8 +3463,6 @@ row_merge_insert_index_tuples(
row buffer to data tuple record */
row_merge_mtuple_to_dtuple(
index, dtuple, &row_buf->tuples[n_rows]);
-
- n_ext = dtuple_get_n_ext(dtuple);
n_rows++;
/* BLOB pointers must be copied from dtuple */
mrec = NULL;
@@ -3482,7 +3481,7 @@ row_merge_insert_index_tuples(
}
dtuple = row_rec_to_index_entry_low(
- mrec, index, offsets, &n_ext, tuple_heap);
+ mrec, index, offsets, tuple_heap);
}
old_index = dict_table_get_first_index(old_table);
@@ -3495,10 +3494,7 @@ row_merge_insert_index_tuples(
}
}
- if (!n_ext) {
- /* There are no externally stored columns. */
- } else {
- ut_ad(dict_index_is_clust(index));
+ if (dict_index_is_clust(index) && dtuple_get_n_ext(dtuple)) {
/* Off-page columns can be fetched safely
when concurrent modifications to the table
are disabled. (Purge can process delete-marked
@@ -3779,6 +3775,9 @@ row_merge_drop_indexes(
we should exclude FTS entries from
prebuilt->ins_node->entry_list
in ins_node_create_entry_list(). */
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!index->search_info->ref_count);
+#endif /* BTR_CUR_HASH_ADAPT */
dict_index_remove_from_cache(
table, index);
index = prev;
@@ -3819,6 +3818,7 @@ row_merge_drop_indexes(
ut_error;
}
+ fts_clear_all(table, trx);
return;
}
@@ -3871,6 +3871,7 @@ row_merge_drop_indexes(
}
}
+ fts_clear_all(table, trx);
table->drop_aborted = FALSE;
ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE));
}
@@ -4158,6 +4159,7 @@ Provide a new pathname for a table that is being renamed if it belongs to
a file-per-table tablespace. The caller is responsible for freeing the
memory allocated for the return value.
@return new pathname of tablespace file, or NULL if space = 0 */
+static
char*
row_make_new_pathname(
/*==================*/
@@ -4920,7 +4922,8 @@ wait_again:
goto func_exit;
}
- if (indexes[i]->type & DICT_FTS && fts_enable_diag_print) {
+ if (indexes[i]->type & DICT_FTS
+ && UNIV_UNLIKELY(fts_enable_diag_print)) {
ib::info() << "Finished building full-text index "
<< indexes[i]->name;
}
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index dabdeeec68b..6704c5cff00 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -100,7 +100,7 @@ static UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
static ib_mutex_t row_drop_list_mutex;
/** Flag: has row_mysql_drop_list been initialized? */
-static ibool row_mysql_drop_list_inited = FALSE;
+static bool row_mysql_drop_list_inited;
/*******************************************************************//**
Determine if the given name is a name reserved for MySQL system tables.
@@ -297,9 +297,7 @@ row_mysql_store_geometry(
{
/* MySQL might assume the field is set to zero except the length and
the pointer fields */
- UNIV_MEM_ASSERT_RW(src, src_len);
- UNIV_MEM_ASSERT_W(dest, dest_len);
- UNIV_MEM_INVALID(dest, dest_len);
+ MEM_CHECK_DEFINED(src, src_len);
memset(dest, '\0', dest_len);
@@ -782,8 +780,7 @@ handle_new_error:
" foreign constraints and try again";
goto rollback_to_savept;
default:
- ib::fatal() << "Unknown error code " << err << ": "
- << ut_strerr(err);
+ ib::fatal() << "Unknown error " << err;
}
if (trx->error_state != DB_SUCCESS) {
@@ -1033,7 +1030,7 @@ row_prebuilt_free(
rtr_clean_rtr_info(prebuilt->rtr_info, true);
}
if (prebuilt->table) {
- dict_table_close(prebuilt->table, dict_locked, TRUE);
+ dict_table_close(prebuilt->table, dict_locked, FALSE);
}
mem_heap_free(prebuilt->heap);
@@ -1092,7 +1089,7 @@ row_get_prebuilt_insert_row(
may need to rebuild the row insert template. */
if (prebuilt->trx_id == table->def_trx_id
- && UT_LIST_GET_LEN(prebuilt->ins_node->entry_list)
+ && prebuilt->ins_node->entry_list.size()
== UT_LIST_GET_LEN(table->indexes)) {
return(prebuilt->ins_node->row);
@@ -1526,7 +1523,7 @@ error_exit:
memcpy(prebuilt->row_id, node->sys_buf, DATA_ROW_ID_LEN);
}
- dict_stats_update_if_needed(table, trx->mysql_thd);
+ dict_stats_update_if_needed(table, *trx);
trx->op_info = "";
if (blob_heap != NULL) {
@@ -1898,7 +1895,7 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
}
if (update_statistics) {
- dict_stats_update_if_needed(prebuilt->table, trx->mysql_thd);
+ dict_stats_update_if_needed(prebuilt->table, *trx);
} else {
/* Always update the table modification counter. */
prebuilt->table->stat_modified_counter++;
@@ -2003,8 +2000,8 @@ row_unlock_for_mysql(
+ index->trx_id_offset);
} else {
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets, true,
@@ -2151,8 +2148,7 @@ row_update_cascade_for_mysql(
}
if (stats) {
- dict_stats_update_if_needed(node->table,
- trx->mysql_thd);
+ dict_stats_update_if_needed(node->table, *trx);
} else {
/* Always update the table
modification counter. */
@@ -2460,6 +2456,9 @@ row_create_index_for_mysql(
index->table = table;
err = dict_create_index_tree_in_mem(index, trx);
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!index->search_info->ref_count);
+#endif /* BTR_CUR_HASH_ADAPT */
if (err != DB_SUCCESS) {
dict_index_remove_from_cache(table, index);
@@ -2571,15 +2570,33 @@ next:
ut_a(!table->can_be_evicted);
+ bool skip = false;
+
if (!table->to_be_dropped) {
+skip:
dict_table_close(table, FALSE, FALSE);
mutex_enter(&row_drop_list_mutex);
UT_LIST_REMOVE(row_mysql_drop_list, drop);
- UT_LIST_ADD_LAST(row_mysql_drop_list, drop);
+ if (!skip) {
+ UT_LIST_ADD_LAST(row_mysql_drop_list, drop);
+ } else {
+ ut_free(drop);
+ }
goto next;
}
+ if (!srv_fast_shutdown && !trx_sys_any_active_transactions()) {
+ lock_mutex_enter();
+ skip = UT_LIST_GET_LEN(table->locks) != 0;
+ lock_mutex_exit();
+ if (skip) {
+ /* We cannot drop tables that are locked by XA
+ PREPARE transactions. */
+ goto skip;
+ }
+ }
+
char* name = mem_strdup(table->name.m_name);
dict_table_close(table, FALSE, FALSE);
@@ -3056,6 +3073,16 @@ row_discard_tablespace_for_mysql(
err = DB_ERROR;
} else {
+ bool fts_exist = (dict_table_has_fts_index(table)
+ || DICT_TF2_FLAG_IS_SET(
+ table, DICT_TF2_FTS_HAS_DOC_ID));
+
+ if (fts_exist) {
+ row_mysql_unlock_data_dictionary(trx);
+ fts_optimize_remove_table(table);
+ row_mysql_lock_data_dictionary(trx);
+ }
+
/* Do foreign key constraint checks. */
err = row_discard_tablespace_foreign_key_checks(trx, table);
@@ -3063,6 +3090,10 @@ row_discard_tablespace_for_mysql(
if (err == DB_SUCCESS) {
err = row_discard_tablespace(trx, table);
}
+
+ if (fts_exist && err != DB_SUCCESS) {
+ fts_optimize_add_table(table);
+ }
}
return(row_discard_tablespace_end(trx, table, err));
@@ -3145,10 +3176,10 @@ row_drop_ancillary_fts_tables(
dberr_t err = fts_drop_tables(trx, table);
- if (err != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::error() << " Unable to remove ancillary FTS"
" tables for table "
- << table->name << " : " << ut_strerr(err);
+ << table->name << " : " << err;
return(err);
}
@@ -3359,35 +3390,6 @@ row_drop_table_for_mysql(
if (!dict_table_is_temporary(table)) {
if (table->space != TRX_SYS_SPACE) {
-#ifdef BTR_CUR_HASH_ADAPT
- /* On DISCARD TABLESPACE, we would not drop the
- adaptive hash index entries. If the tablespace is
- missing here, delete-marking the record in SYS_INDEXES
- would not free any pages in the buffer pool. Thus,
- dict_index_remove_from_cache() would hang due to
- adaptive hash index entries existing in the buffer
- pool. To prevent this hang, and also to guarantee
- that btr_search_drop_page_hash_when_freed() will avoid
- calling btr_search_drop_page_hash_index() while we
- hold the InnoDB dictionary lock, we will drop any
- adaptive hash index entries upfront. */
- const bool immune = is_temp_name
- || create_failed
- || sqlcom == SQLCOM_CREATE_TABLE
- || strstr(table->name.m_name, "/FTS");
-
- while (buf_LRU_drop_page_hash_for_tablespace(table)) {
- if ((!immune && trx_is_interrupted(trx))
- || srv_shutdown_state
- != SRV_SHUTDOWN_NONE) {
- err = DB_INTERRUPTED;
- table->to_be_dropped = false;
- dict_table_close(table, true, false);
- goto funct_exit;
- }
- }
-#endif /* BTR_CUR_HASH_ADAPT */
-
/* Delete the link file if used. */
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
RemoteDatafile::delete_link_file(name);
@@ -3404,15 +3406,15 @@ row_drop_table_for_mysql(
btr_defragment_remove_table(table);
}
- /* Remove stats for this table and all of its indexes from the
- persistent storage if it exists and if there are stats for this
- table in there. This function creates its own trx and commits
- it. */
- char errstr[1024];
- err = dict_stats_drop_table(name, errstr, sizeof(errstr));
-
- if (err != DB_SUCCESS) {
- ib::warn() << errstr;
+ if (UNIV_LIKELY(!strstr(name, "/" TEMP_FILE_PREFIX_INNODB))) {
+ /* Remove any persistent statistics for this table,
+ in a separate transaction. */
+ char errstr[1024];
+ err = dict_stats_drop_table(name, errstr,
+ sizeof errstr);
+ if (err != DB_SUCCESS) {
+ ib::warn() << errstr;
+ }
}
}
@@ -3711,10 +3713,12 @@ do_drop:
dict_table_t. Free this memory before returning. */
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
dict_get_and_save_data_dir_path(table, true);
- ut_a(table->data_dir_path);
+ ut_ad(table->data_dir_path
+ || dict_table_is_discarded(table));
filepath = fil_make_filepath(
table->data_dir_path,
- table->name.m_name, IBD, true);
+ table->name.m_name, IBD,
+ table->data_dir_path != NULL);
} else {
filepath = fil_make_filepath(
NULL, table->name.m_name, IBD, false);
@@ -3806,6 +3810,11 @@ funct_exit:
trx_commit_for_mysql(trx);
}
+ /* Add the table to fts queue if drop table fails */
+ if (err != DB_SUCCESS && table->fts) {
+ fts_optimize_add_table(table);
+ }
+
row_mysql_unlock_data_dictionary(trx);
}
@@ -3931,9 +3940,21 @@ loop:
avoid accessing dropped fts aux tables in information
scheam when parent table still exists.
Note: Drop parent table will drop fts aux tables. */
- char* parent_table_name;
- parent_table_name = fts_get_parent_table_name(
- table_name, strlen(table_name));
+ char* parent_table_name = NULL;
+ table_id_t table_id;
+ index_id_t index_id;
+
+ if (fts_check_aux_table(
+ table_name, &table_id, &index_id)) {
+ dict_table_t* parent_table = dict_table_open_on_id(
+ table_id, TRUE, DICT_TABLE_OP_NORMAL);
+ if (parent_table != NULL) {
+ parent_table_name = mem_strdupl(
+ parent_table->name.m_name,
+ strlen(parent_table->name.m_name));
+ dict_table_close(parent_table, TRUE, FALSE);
+ }
+ }
if (parent_table_name != NULL) {
ut_free(table_name);
@@ -4015,10 +4036,10 @@ loop:
table_name, trx, SQLCOM_DROP_DB);
trx_commit_for_mysql(trx);
- if (err != DB_SUCCESS) {
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::error() << "DROP DATABASE "
<< ut_get_name(trx, name) << " failed"
- " with error (" << ut_strerr(err) << ") for"
+ " with error (" << err << ") for"
" table " << ut_get_name(trx, table_name);
ut_free(table_name);
break;
@@ -4285,11 +4306,9 @@ row_rename_table_for_mysql(
/* SYS_TABLESPACES and SYS_DATAFILES need to be updated if
the table is in a single-table tablespace. */
- if (err == DB_SUCCESS
- && dict_table_is_file_per_table(table)) {
- /* Make a new pathname to update SYS_DATAFILES. */
- char* new_path = row_make_new_pathname(table, new_name);
- char* old_path = fil_space_get_first_path(table->space);
+ if (err != DB_SUCCESS || !dict_table_is_file_per_table(table)) {
+ } else if (char* old_path = fil_space_get_first_path(table->space)) {
+ char* new_path = os_file_make_new_pathname(old_path, new_name);
/* If old path and new path are the same means tablename
has not changed and only the database name holding the table
@@ -4529,12 +4548,20 @@ end:
if (err != DB_SUCCESS) {
if (old_is_tmp) {
- ib::error() << "In ALTER TABLE "
+ /* In case of copy alter, ignore the
+ loading of foreign key constraint
+ when foreign_key_check is disabled */
+ ib::error_or_warn(trx->check_foreigns)
+ << "In ALTER TABLE "
<< ut_get_name(trx, new_name)
<< " has or is referenced in foreign"
" key constraints which are not"
" compatible with the new table"
" definition.";
+ if (!trx->check_foreigns) {
+ err = DB_SUCCESS;
+ goto funct_exit;
+ }
} else {
ib::error() << "In RENAME TABLE table "
<< ut_get_name(trx, new_name)
@@ -4652,9 +4679,8 @@ row_scan_index_for_mysql(
ulint i;
ulint cnt;
mem_heap_t* heap = NULL;
- ulint n_ext;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets;
rec_offs_init(offsets_);
*n_rows = 0;
@@ -4786,14 +4812,14 @@ not_ok:
tmp_heap = mem_heap_create(size);
- offsets = static_cast<ulint*>(
+ offsets = static_cast<rec_offs*>(
mem_heap_dup(tmp_heap, offsets, size));
}
mem_heap_empty(heap);
prev_entry = row_rec_to_index_entry(
- rec, index, offsets, &n_ext, heap);
+ rec, index, offsets, heap);
if (UNIV_LIKELY_NULL(tmp_heap)) {
mem_heap_free(tmp_heap);
@@ -4818,19 +4844,22 @@ row_mysql_init(void)
row_mysql_drop_list,
&row_mysql_drop_t::row_mysql_drop_list);
- row_mysql_drop_list_inited = TRUE;
+ row_mysql_drop_list_inited = true;
}
-/*********************************************************************//**
-Close this module */
-void
-row_mysql_close(void)
-/*================*/
+void row_mysql_close()
{
- ut_a(UT_LIST_GET_LEN(row_mysql_drop_list) == 0);
-
- if (row_mysql_drop_list_inited) {
- mutex_free(&row_drop_list_mutex);
- row_mysql_drop_list_inited = FALSE;
- }
+ ut_ad(!UT_LIST_GET_LEN(row_mysql_drop_list) ||
+ srv_force_recovery >= SRV_FORCE_NO_BACKGROUND);
+ if (row_mysql_drop_list_inited)
+ {
+ row_mysql_drop_list_inited= false;
+ mutex_free(&row_drop_list_mutex);
+
+ while (row_mysql_drop_t *drop= UT_LIST_GET_FIRST(row_mysql_drop_list))
+ {
+ UT_LIST_REMOVE(row_mysql_drop_list, drop);
+ ut_free(drop);
+ }
+ }
}
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 42aa6123cd6..e79784a5a5f 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -46,7 +46,6 @@ Created 3/14/1997 Heikki Tuuri
#include "handler.h"
#include "ha_innodb.h"
#include "fil0fil.h"
-#include "debug_sync.h"
/*************************************************************************
IMPORTANT NOTE: Any operation that generates redo MUST check that there
@@ -108,8 +107,8 @@ row_purge_remove_clust_if_poss_low(
mtr_t mtr;
rec_t* rec;
mem_heap_t* heap = NULL;
- ulint* offsets;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_S)
@@ -1005,7 +1004,7 @@ try_again:
dict_table_close(node->table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
return(false);
}
os_thread_sleep(1000000);
@@ -1103,8 +1102,7 @@ row_purge_record_func(
if (node->table->stat_initialized
&& srv_stats_include_delete_marked) {
dict_stats_update_if_needed(
- node->table,
- thr->graph->trx->mysql_thd);
+ node->table, *thr->graph->trx);
}
MONITOR_INC(MONITOR_N_DEL_ROW_PURGE);
}
@@ -1169,7 +1167,7 @@ row_purge(
ut_ad(!rw_lock_own(&dict_operation_lock, RW_LOCK_S));
if (purged
- || srv_shutdown_state != SRV_SHUTDOWN_NONE
+ || srv_shutdown_state > SRV_SHUTDOWN_INITIATED
|| node->vcol_op_failed()) {
return;
}
@@ -1210,26 +1208,6 @@ row_purge_step(
node->start();
-#ifdef UNIV_DEBUG
- srv_slot_t *slot = thr->thread_slot;
- ut_ad(slot);
-
- rw_lock_x_lock(&slot->debug_sync_lock);
- while (UT_LIST_GET_LEN(slot->debug_sync)) {
- srv_slot_t::debug_sync_t *sync =
- UT_LIST_GET_FIRST(slot->debug_sync);
- const char* sync_str = reinterpret_cast<char*>(&sync[1]);
- bool result = debug_sync_set_action(current_thd,
- sync_str,
- strlen(sync_str));
- ut_a(!result);
-
- UT_LIST_REMOVE(slot->debug_sync, sync);
- ut_free(sync);
- }
- rw_lock_x_unlock(&slot->debug_sync_lock);
-#endif
-
if (!(node->undo_recs == NULL || ib_vector_is_empty(node->undo_recs))) {
trx_purge_rec_t*purge_rec;
@@ -1284,7 +1262,7 @@ purge_node_t::validate_pcur()
dict_index_t* clust_index = pcur.btr_cur.index;
- ulint* offsets = rec_get_offsets(
+ rec_offs* offsets = rec_get_offsets(
pcur.old_rec, clust_index, NULL, true,
pcur.old_n_fields, &heap);
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index 3e65dc1d28b..774794be225 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2019, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -372,7 +372,7 @@ row_build_low(
ulint type,
const dict_index_t* index,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
const dict_table_t* col_table,
const dtuple_t* add_cols,
const dict_add_v_col_t* add_v,
@@ -388,7 +388,7 @@ row_build_low(
byte* buf;
ulint j;
mem_heap_t* tmp_heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
ut_ad(index != NULL);
@@ -435,7 +435,7 @@ row_build_low(
}
/* Avoid a debug assertion in rec_offs_validate(). */
- rec_offs_make_valid(copy, index, const_cast<ulint*>(offsets));
+ rec_offs_make_valid(copy, index, const_cast<rec_offs*>(offsets));
if (!col_table) {
ut_ad(!col_map);
@@ -525,7 +525,7 @@ row_build_low(
}
}
- rec_offs_make_valid(rec, index, const_cast<ulint*>(offsets));
+ rec_offs_make_valid(rec, index, const_cast<rec_offs*>(offsets));
ut_ad(dtuple_check_typed(row));
@@ -578,7 +578,7 @@ row_build(
this record must be at least
s-latched and the latch held
as long as the row dtuple is used! */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index)
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index)
or NULL, in which case this function
will invoke rec_get_offsets() */
const dict_table_t* col_table,
@@ -631,7 +631,7 @@ row_build_w_add_vcol(
ulint type,
const dict_index_t* index,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
const dict_table_t* col_table,
const dtuple_t* add_cols,
const dict_add_v_col_t* add_v,
@@ -652,9 +652,7 @@ row_rec_to_index_entry_low(
/*=======================*/
const rec_t* rec, /*!< in: record in the index */
const dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
- ulint* n_ext, /*!< out: number of externally
- stored columns */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
{
@@ -672,8 +670,6 @@ row_rec_to_index_entry_low(
/* Because this function may be invoked by row0merge.cc
on a record whose header is in different format, the check
rec_offs_validate(rec, index, offsets) must be avoided here. */
- ut_ad(n_ext);
- *n_ext = 0;
rec_len = rec_offs_n_fields(offsets);
@@ -698,7 +694,6 @@ row_rec_to_index_entry_low(
if (rec_offs_nth_extern(offsets, i)) {
dfield_set_ext(dfield);
- (*n_ext)++;
}
}
@@ -716,9 +711,7 @@ row_rec_to_index_entry(
/*===================*/
const rec_t* rec, /*!< in: record in the index */
const dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec) */
- ulint* n_ext, /*!< out: number of externally
- stored columns */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec) */
mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
{
@@ -737,10 +730,10 @@ row_rec_to_index_entry(
copy_rec = rec_copy(buf, rec, offsets);
- rec_offs_make_valid(copy_rec, index, const_cast<ulint*>(offsets));
+ rec_offs_make_valid(copy_rec, index, const_cast<rec_offs*>(offsets));
entry = row_rec_to_index_entry_low(
- copy_rec, index, offsets, n_ext, heap);
- rec_offs_make_valid(rec, index, const_cast<ulint*>(offsets));
+ copy_rec, index, offsets, heap);
+ rec_offs_make_valid(rec, index, const_cast<rec_offs*>(offsets));
dtuple_set_info_bits(entry,
rec_get_info_bits(rec, rec_offs_comp(offsets)));
@@ -782,8 +775,8 @@ row_build_row_ref(
ulint clust_col_prefix_len;
ulint i;
mem_heap_t* tmp_heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(index != NULL);
@@ -878,7 +871,7 @@ row_build_row_ref_in_tuple(
held as long as the row
reference is used! */
const dict_index_t* index, /*!< in: secondary index */
- ulint* offsets,/*!< in: rec_get_offsets(rec, index)
+ rec_offs* offsets,/*!< in: rec_get_offsets(rec, index)
or NULL */
trx_t* trx) /*!< in: transaction */
{
@@ -891,7 +884,7 @@ row_build_row_ref_in_tuple(
ulint clust_col_prefix_len;
ulint i;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
ut_ad(!dict_index_is_clust(index));
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index dae51354196..0451a240ffc 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -154,11 +154,15 @@ fields are compared with collation!
must be protected by a page s-latch
@param[in] clust_index clustered index
@param[in] thr query thread
-@return TRUE if the secondary record is equal to the corresponding
-fields in the clustered record, when compared with collation;
-FALSE if not equal or if the clustered record has been marked for deletion */
+@retval DB_COMPUTE_VALUE_FAILED in case of virtual column value computation
+ failure.
+@retval DB_SUCCESS_LOCKED_REC if the secondary record is equal to the
+ corresponding fields in the clustered record, when compared with
+ collation;
+@retval DB_SUCCESS if not equal or if the clustered record has been marked
+ for deletion */
static
-ibool
+dberr_t
row_sel_sec_rec_is_for_clust_rec(
const rec_t* sec_rec,
dict_index_t* sec_index,
@@ -172,13 +176,10 @@ row_sel_sec_rec_is_for_clust_rec(
ulint n;
ulint i;
mem_heap_t* heap = NULL;
- ulint clust_offsets_[REC_OFFS_NORMAL_SIZE];
- ulint sec_offsets_[REC_OFFS_SMALL_SIZE];
- ulint* clust_offs = clust_offsets_;
- ulint* sec_offs = sec_offsets_;
- ibool is_equal = TRUE;
- VCOL_STORAGE* vcol_storage= 0;
- byte* record;
+ rec_offs clust_offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs sec_offsets_[REC_OFFS_SMALL_SIZE];
+ rec_offs* clust_offs = clust_offsets_;
+ rec_offs* sec_offs = sec_offsets_;
rec_offs_init(clust_offsets_);
rec_offs_init(sec_offsets_);
@@ -193,10 +194,11 @@ row_sel_sec_rec_is_for_clust_rec(
it is not visible in the read view. Besides,
if there are any externally stored columns,
some of them may have already been purged. */
- return(FALSE);
+ return DB_SUCCESS;
}
heap = mem_heap_create(256);
+ ib_vcol_row vc(heap);
clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs,
true, ULINT_UNDEFINED, &heap);
@@ -225,16 +227,9 @@ row_sel_sec_rec_is_for_clust_rec(
dfield_t* vfield;
row_ext_t* ext;
- if (!vcol_storage)
- {
- TABLE *mysql_table= thr->prebuilt->m_mysql_table;
- innobase_allocate_row_for_vcol(thr_get_trx(thr)->mysql_thd,
- clust_index,
- &heap,
- &mysql_table,
- &record,
- &vcol_storage);
- }
+ byte *record = vc.record(thr_get_trx(thr)->mysql_thd,
+ clust_index,
+ &thr->prebuilt->m_mysql_table);
v_col = reinterpret_cast<const dict_v_col_t*>(col);
@@ -251,6 +246,10 @@ row_sel_sec_rec_is_for_clust_rec(
thr->prebuilt->m_mysql_table,
record, NULL, NULL, NULL);
+ if (vfield == NULL) {
+ innobase_report_computed_value_failed(row);
+ return DB_COMPUTE_VALUE_FAILED;
+ }
clust_len = vfield->len;
clust_field = static_cast<byte*>(vfield->data);
} else {
@@ -284,7 +283,7 @@ row_sel_sec_rec_is_for_clust_rec(
sec_field, sec_len,
ifield->prefix_len,
clust_index->table)) {
- goto inequal;
+ return DB_SUCCESS;
}
continue;
@@ -320,28 +319,19 @@ row_sel_sec_rec_is_for_clust_rec(
rtr_read_mbr(sec_field, &sec_mbr);
if (!MBR_EQUAL_CMP(&sec_mbr, &tmp_mbr)) {
- is_equal = FALSE;
- goto func_exit;
+ return DB_SUCCESS;
}
} else {
if (0 != cmp_data_data(col->mtype, col->prtype,
clust_field, len,
sec_field, sec_len)) {
-inequal:
- is_equal = FALSE;
- goto func_exit;
+ return DB_SUCCESS;
}
}
}
-func_exit:
- if (UNIV_LIKELY_NULL(heap)) {
- if (UNIV_LIKELY_NULL(vcol_storage))
- innobase_free_row_for_vcol(vcol_storage);
- mem_heap_free(heap);
- }
- return(is_equal);
+ return DB_SUCCESS_LOCKED_REC;
}
/*********************************************************************//**
@@ -494,7 +484,7 @@ row_sel_fetch_columns(
dict_index_t* index, /*!< in: record index */
const rec_t* rec, /*!< in: record in a clustered or non-clustered
index; must be protected by a page latch */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
sym_node_t* column) /*!< in: first column in a column list, or
NULL */
{
@@ -761,7 +751,7 @@ row_sel_build_prev_vers(
ReadView* read_view, /*!< in: read view */
dict_index_t* index, /*!< in: plan node for table */
rec_t* rec, /*!< in: record in a clustered index */
- ulint** offsets, /*!< in/out: offsets returned by
+ rec_offs** offsets, /*!< in/out: offsets returned by
rec_get_offsets(rec, plan->index) */
mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
@@ -796,7 +786,7 @@ row_sel_build_committed_vers_for_mysql(
dict_index_t* clust_index, /*!< in: clustered index */
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
const rec_t* rec, /*!< in: record in a clustered index */
- ulint** offsets, /*!< in/out: offsets returned by
+ rec_offs** offsets, /*!< in/out: offsets returned by
rec_get_offsets(rec, clust_index) */
mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
@@ -908,10 +898,10 @@ row_sel_get_clust_rec(
dict_index_t* index;
rec_t* clust_rec;
rec_t* old_vers;
- dberr_t err;
+ dberr_t err = DB_SUCCESS;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
*out_rec = NULL;
@@ -950,7 +940,7 @@ row_sel_get_clust_rec(
clustered index record did not exist in the read view of
trx. */
- goto func_exit;
+ goto err_exit;
}
offsets = rec_get_offsets(clust_rec, index, offsets, true,
@@ -984,9 +974,11 @@ row_sel_get_clust_rec(
switch (err) {
case DB_SUCCESS:
case DB_SUCCESS_LOCKED_REC:
- /* Declare the variable uninitialized in Valgrind.
+#ifdef HAVE_valgrind_or_MSAN
+ /* Declare the variable uninitialized.
It should be set to DB_SUCCESS at func_exit. */
- UNIV_MEM_INVALID(&err, sizeof err);
+ MEM_UNDEFINED(&err, sizeof err);
+#endif /* HAVE_valgrind_or_MSAN */
break;
default:
goto err_exit;
@@ -1013,7 +1005,7 @@ row_sel_get_clust_rec(
clust_rec = old_vers;
if (clust_rec == NULL) {
- goto func_exit;
+ goto err_exit;
}
}
@@ -1030,13 +1022,14 @@ row_sel_get_clust_rec(
visit through secondary index records that would not really
exist in our snapshot. */
- if ((old_vers
- || rec_get_deleted_flag(rec, dict_table_is_comp(
- plan->table)))
- && !row_sel_sec_rec_is_for_clust_rec(rec, plan->index,
- clust_rec, index,
- thr)) {
- goto func_exit;
+ if (old_vers || rec_get_deleted_flag(rec, dict_table_is_comp(
+ plan->table))) {
+ err = row_sel_sec_rec_is_for_clust_rec(rec,
+ plan->index, clust_rec,
+ index, thr);
+ if (err != DB_SUCCESS_LOCKED_REC) {
+ goto err_exit;
+ }
}
}
@@ -1049,7 +1042,6 @@ row_sel_get_clust_rec(
row_sel_fetch_columns(index, clust_rec, offsets,
UT_LIST_GET_FIRST(plan->columns));
*out_rec = clust_rec;
-func_exit:
err = DB_SUCCESS;
err_exit:
if (UNIV_LIKELY_NULL(heap)) {
@@ -1070,7 +1062,7 @@ sel_set_rtr_rec_lock(
btr_pcur_t* pcur, /*!< in: cursor */
const rec_t* first_rec,/*!< in: record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint mode, /*!< in: lock mode */
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOC_REC_NOT_GAP */
@@ -1082,8 +1074,8 @@ sel_set_rtr_rec_lock(
dberr_t err = DB_SUCCESS;
trx_t* trx = thr_get_trx(thr);
buf_block_t* cur_block = btr_pcur_get_block(pcur);
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* my_offsets = const_cast<ulint*>(offsets);
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* my_offsets = const_cast<rec_offs*>(offsets);
rec_t* rec = const_cast<rec_t*>(first_rec);
rtr_rec_vector* match_rec;
rtr_rec_vector::iterator end;
@@ -1235,7 +1227,7 @@ sel_set_rec_lock(
btr_pcur_t* pcur, /*!< in: cursor */
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint mode, /*!< in: lock mode */
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOC_REC_NOT_GAP */
@@ -1289,23 +1281,17 @@ void
row_sel_open_pcur(
/*==============*/
plan_t* plan, /*!< in: table plan */
- ibool search_latch_locked,
- /*!< in: TRUE if the thread currently
- has the search latch locked in
- s-mode */
+#ifdef BTR_CUR_HASH_ADAPT
+ ulint has_search_latch,
+#endif
mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
func_node_t* cond;
que_node_t* exp;
ulint n_fields;
- ulint has_search_latch = 0; /* RW_S_LATCH or 0 */
ulint i;
- if (search_latch_locked) {
- has_search_latch = RW_S_LATCH;
- }
-
index = plan->index;
/* Calculate the value of the search tuple: the exact match columns
@@ -1357,6 +1343,11 @@ row_sel_open_pcur(
plan->pcur_is_open = TRUE;
}
+#ifndef BTR_CUR_HASH_ADAPT
+# define row_sel_open_pcur(plan, has_search_latch, mtr) \
+ row_sel_open_pcur(plan, mtr)
+#endif /* !BTR_CUR_HASH_ADAPT */
+
/*********************************************************************//**
Restores a stored pcur position to a table index.
@return TRUE if the cursor should be moved to the next record after we
@@ -1486,8 +1477,8 @@ row_sel_try_search_shortcut(
dict_index_t* index;
rec_t* rec;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
ulint ret;
rec_offs_init(offsets_);
@@ -1612,18 +1603,12 @@ row_sel(
to the next non-clustered record */
dberr_t err;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(thr->run_node == node);
-#ifdef BTR_CUR_HASH_ADAPT
- ibool search_latch_locked = FALSE;
-#else /* BTR_CUR_HASH_ADAPT */
-# define search_latch_locked false
-#endif /* BTR_CUR_HASH_ADAPT */
-
if (node->read_view) {
/* In consistent reads, we try to do with the hash index and
not to use the buffer page get. This is to reduce memory bus
@@ -1648,6 +1633,10 @@ table_loop:
plan = sel_node_get_nth_plan(node, node->fetch_table);
index = plan->index;
+#ifdef BTR_CUR_HASH_ADAPT
+ ulint has_search_latch = 0;
+ rw_lock_t* const latch = btr_get_search_latch(index);
+#endif /* BTR_CUR_HASH_ADAPT */
if (plan->n_rows_prefetched > 0) {
sel_dequeue_prefetched_row(plan);
@@ -1672,26 +1661,22 @@ table_loop:
#ifdef BTR_CUR_HASH_ADAPT
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust) {
- if (!search_latch_locked) {
- btr_search_s_lock(index);
-
- search_latch_locked = TRUE;
- } else if (rw_lock_get_writer(btr_get_search_latch(index))
- == RW_LOCK_X_WAIT) {
-
+ if (!has_search_latch) {
+ has_search_latch = RW_S_LATCH;
+ rw_lock_s_lock(latch);
+ } else if (rw_lock_get_writer(latch) == RW_LOCK_X_WAIT) {
/* There is an x-latch request waiting: release the
s-latch for a moment; as an s-latch here is often
kept for some 10 searches before being released,
a waiting x-latch request would block other threads
from acquiring an s-latch for a long time, lowering
performance significantly in multiprocessors. */
-
- btr_search_s_unlock(index);
- btr_search_s_lock(index);
+ rw_lock_s_unlock(latch);
+ rw_lock_s_lock(latch);
}
switch (row_sel_try_search_shortcut(node, plan,
- search_latch_locked,
+ has_search_latch,
&mtr)) {
case SEL_FOUND:
goto next_table;
@@ -1709,10 +1694,9 @@ table_loop:
mtr.start();
}
- if (search_latch_locked) {
- btr_search_s_unlock(index);
-
- search_latch_locked = FALSE;
+ if (has_search_latch) {
+ has_search_latch = 0;
+ rw_lock_s_unlock(latch);
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -1720,7 +1704,7 @@ table_loop:
/* Evaluate the expressions to build the search tuple and
open the cursor */
- row_sel_open_pcur(plan, search_latch_locked, &mtr);
+ row_sel_open_pcur(plan, has_search_latch, &mtr);
cursor_just_opened = TRUE;
@@ -2117,7 +2101,9 @@ skip_lock:
}
next_rec:
- ut_ad(!search_latch_locked);
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!has_search_latch);
+#endif /* BTR_CUR_HASH_ADAPT */
if (mtr_has_extra_clust_latch) {
@@ -2156,8 +2142,9 @@ next_table:
plan->cursor_at_end = TRUE;
} else {
- ut_ad(!search_latch_locked);
-
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!has_search_latch);
+#endif /* BTR_CUR_HASH_ADAPT */
plan->stored_cursor_rec_processed = TRUE;
btr_pcur_store_position(&(plan->pcur), &mtr);
@@ -2248,8 +2235,9 @@ stop_for_a_while:
inserted new records which should have appeared in the result set,
which would result in the phantom problem. */
- ut_ad(!search_latch_locked);
-
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!has_search_latch);
+#endif /* BTR_CUR_HASH_ADAPT */
plan->stored_cursor_rec_processed = FALSE;
btr_pcur_store_position(&(plan->pcur), &mtr);
@@ -2266,7 +2254,9 @@ commit_mtr_for_a_while:
plan->stored_cursor_rec_processed = TRUE;
- ut_ad(!search_latch_locked);
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!has_search_latch);
+#endif /* BTR_CUR_HASH_ADAPT */
btr_pcur_store_position(&(plan->pcur), &mtr);
mtr.commit();
@@ -2280,7 +2270,9 @@ lock_wait_or_error:
/* See the note at stop_for_a_while: the same holds for this case */
ut_ad(!btr_pcur_is_before_first_on_page(&plan->pcur) || !node->asc);
- ut_ad(!search_latch_locked);
+#ifdef BTR_CUR_HASH_ADAPT
+ ut_ad(!has_search_latch);
+#endif /* BTR_CUR_HASH_ADAPT */
plan->stored_cursor_rec_processed = FALSE;
btr_pcur_store_position(&(plan->pcur), &mtr);
@@ -2289,8 +2281,8 @@ lock_wait_or_error:
func_exit:
#ifdef BTR_CUR_HASH_ADAPT
- if (search_latch_locked) {
- btr_search_s_unlock(index);
+ if (has_search_latch) {
+ rw_lock_s_unlock(latch);
}
#endif /* BTR_CUR_HASH_ADAPT */
ut_ad(!sync_check_iterate(dict_sync_check()));
@@ -2760,7 +2752,7 @@ row_sel_store_row_id_to_prebuilt(
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt */
const rec_t* index_rec, /*!< in: record */
const dict_index_t* index, /*!< in: index of the record */
- const ulint* offsets) /*!< in: rec_get_offsets
+ const rec_offs* offsets) /*!< in: rec_get_offsets
(index_rec, index) */
{
const byte* data;
@@ -2811,9 +2803,11 @@ row_sel_field_store_in_mysql_format_func(
#endif /* UNIV_DEBUG */
ut_ad(len != UNIV_SQL_NULL);
- UNIV_MEM_ASSERT_RW(data, len);
- UNIV_MEM_ASSERT_W(dest, templ->mysql_col_len);
- UNIV_MEM_INVALID(dest, templ->mysql_col_len);
+ MEM_CHECK_DEFINED(data, len);
+ MEM_CHECK_ADDRESSABLE(dest, templ->mysql_col_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(dest, templ->mysql_col_len);
+#endif /* HAVE_valgrind_or_MSAN */
switch (templ->type) {
const byte* field_end;
@@ -2996,7 +2990,7 @@ row_sel_store_mysql_field_func(
#ifdef UNIV_DEBUG
const dict_index_t* index,
#endif
- const ulint* offsets,
+ const rec_offs* offsets,
ulint field_no,
const mysql_row_templ_t*templ)
{
@@ -3075,9 +3069,9 @@ row_sel_store_mysql_field_func(
NULL value is set to the default value. */
ut_ad(templ->mysql_null_bit_mask);
- UNIV_MEM_ASSERT_RW(prebuilt->default_rec
- + templ->mysql_col_offset,
- templ->mysql_col_len);
+ MEM_CHECK_DEFINED(prebuilt->default_rec
+ + templ->mysql_col_offset,
+ templ->mysql_col_len);
mysql_rec[templ->mysql_null_byte_offset]
|= (byte) templ->mysql_null_bit_mask;
memcpy(mysql_rec + templ->mysql_col_offset,
@@ -3152,7 +3146,7 @@ static bool row_sel_store_mysql_rec(
const dtuple_t* vrow,
bool rec_clust,
const dict_index_t* index,
- const ulint* offsets)
+ const rec_offs* offsets)
{
DBUG_ENTER("row_sel_store_mysql_rec");
@@ -3283,7 +3277,7 @@ row_sel_build_prev_vers_for_mysql(
dict_index_t* clust_index, /*!< in: clustered index */
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
const rec_t* rec, /*!< in: record in a clustered index */
- ulint** offsets, /*!< in/out: offsets returned by
+ rec_offs** offsets, /*!< in/out: offsets returned by
rec_get_offsets(rec, clust_index) */
mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
@@ -3309,20 +3303,46 @@ row_sel_build_prev_vers_for_mysql(
return(err);
}
-/** Helper class to cache clust_rec and old_ver */
+/** Helper class to cache clust_rec and old_vers */
class Row_sel_get_clust_rec_for_mysql
{
- const rec_t *cached_clust_rec;
- rec_t *cached_old_vers;
+ const rec_t *cached_clust_rec;
+ rec_t *cached_old_vers;
+ lsn_t cached_lsn;
+ page_id_t cached_page_id;
-public:
- Row_sel_get_clust_rec_for_mysql() :
- cached_clust_rec(NULL), cached_old_vers(NULL) {}
+#ifdef UNIV_DEBUG
+ void check_eq(const dict_index_t *index, const rec_offs *offsets) const
+ {
+ rec_offs vers_offs[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS];
+ rec_offs_init(vers_offs);
+ mem_heap_t *heap= NULL;
+
+ ut_ad(rec_offs_validate(cached_clust_rec, index, offsets));
+ ut_ad(index->first_user_field() <= rec_offs_n_fields(offsets));
+ ut_ad(vers_offs == rec_get_offsets(cached_old_vers, index, vers_offs, true,
+ index->db_trx_id(), &heap));
+ ut_ad(!heap);
+ for (unsigned n= index->db_trx_id(); n--; )
+ {
+ const dict_col_t *col= dict_index_get_nth_col(index, n);
+ ulint len1, len2;
+ const byte *b1= rec_get_nth_field(cached_clust_rec, offsets, n, &len1);
+ const byte *b2= rec_get_nth_field(cached_old_vers, vers_offs, n, &len2);
+ ut_ad(!cmp_data_data(col->mtype, col->prtype, b1, len1, b2, len2));
+ }
+ }
+#endif
- dberr_t operator()(row_prebuilt_t *prebuilt, dict_index_t *sec_index,
- const rec_t *rec, que_thr_t *thr, const rec_t **out_rec,
- ulint **offsets, mem_heap_t **offset_heap,
- dtuple_t **vrow, mtr_t *mtr);
+public:
+ Row_sel_get_clust_rec_for_mysql() :
+ cached_clust_rec(NULL), cached_old_vers(NULL), cached_lsn(0),
+ cached_page_id(page_id_t(0,0)) {}
+
+ dberr_t operator()(row_prebuilt_t *prebuilt, dict_index_t *sec_index,
+ const rec_t *rec, que_thr_t *thr, const rec_t **out_rec,
+ rec_offs **offsets, mem_heap_t **offset_heap,
+ dtuple_t **vrow, mtr_t *mtr);
};
/*********************************************************************//**
@@ -3344,7 +3364,7 @@ Row_sel_get_clust_rec_for_mysql::operator()(
it, NULL if the old version did not exist
in the read view, i.e., it was a fresh
inserted version */
- ulint** offsets,/*!< in: offsets returned by
+ rec_offs** offsets,/*!< in: offsets returned by
rec_get_offsets(rec, sec_index);
out: offsets returned by
rec_get_offsets(out_rec, clust_index) */
@@ -3522,8 +3542,18 @@ Row_sel_get_clust_rec_for_mysql::operator()(
&& !lock_clust_rec_cons_read_sees(
clust_rec, clust_index, *offsets,
trx_get_read_view(trx))) {
+ const buf_page_t& bpage = btr_pcur_get_block(
+ prebuilt->clust_pcur)->page;
+
+ lsn_t lsn = bpage.newest_modification;
+ if (!lsn) {
+ lsn = mach_read_from_8(
+ page_align(clust_rec) + FIL_PAGE_LSN);
+ }
- if (clust_rec != cached_clust_rec) {
+ if (lsn != cached_lsn
+ || bpage.id != cached_page_id
+ || clust_rec != cached_clust_rec) {
/* The following call returns 'offsets' associated with
'old_vers' */
err = row_sel_build_prev_vers_for_mysql(
@@ -3535,6 +3565,8 @@ Row_sel_get_clust_rec_for_mysql::operator()(
goto err_exit;
}
+ cached_lsn = lsn;
+ cached_page_id = bpage.id;
cached_clust_rec = clust_rec;
cached_old_vers = old_vers;
} else {
@@ -3545,7 +3577,8 @@ Row_sel_get_clust_rec_for_mysql::operator()(
version of clust_rec and its old version
old_vers. Re-calculate the offsets for old_vers. */
- if (old_vers != NULL) {
+ if (old_vers) {
+ ut_d(check_eq(clust_index, *offsets));
*offsets = rec_get_offsets(
old_vers, clust_index, *offsets,
true, ULINT_UNDEFINED, offset_heap);
@@ -3579,10 +3612,18 @@ Row_sel_get_clust_rec_for_mysql::operator()(
|| trx->isolation_level <= TRX_ISO_READ_UNCOMMITTED
|| dict_index_is_spatial(sec_index)
|| rec_get_deleted_flag(rec, dict_table_is_comp(
- sec_index->table)))
- && !row_sel_sec_rec_is_for_clust_rec(
- rec, sec_index, clust_rec, clust_index, thr)) {
- clust_rec = NULL;
+ sec_index->table)))) {
+ err = row_sel_sec_rec_is_for_clust_rec(rec, sec_index,
+ clust_rec, clust_index, thr);
+ switch (err) {
+ case DB_SUCCESS:
+ clust_rec = NULL;
+ break;
+ case DB_SUCCESS_LOCKED_REC:
+ break;
+ default:
+ goto err_exit;
+ }
}
err = DB_SUCCESS;
@@ -3715,7 +3756,7 @@ row_sel_copy_cached_field_for_mysql(
buf += templ->mysql_col_offset;
cache += templ->mysql_col_offset;
- UNIV_MEM_ASSERT_W(buf, templ->mysql_col_len);
+ MEM_CHECK_ADDRESSABLE(buf, templ->mysql_col_len);
if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR
&& (templ->type != DATA_INT)) {
@@ -3725,7 +3766,9 @@ row_sel_copy_cached_field_for_mysql(
row_mysql_read_true_varchar(
&len, cache, templ->mysql_length_bytes);
len += templ->mysql_length_bytes;
- UNIV_MEM_INVALID(buf, templ->mysql_col_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(buf, templ->mysql_col_len);
+#endif /* HAVE_valgrind_or_MSAN */
} else {
len = templ->mysql_col_len;
}
@@ -3784,7 +3827,7 @@ row_sel_dequeue_cached_row_for_mysql(
ut_ad(prebuilt->n_fetch_cached > 0);
ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
- UNIV_MEM_ASSERT_W(buf, prebuilt->mysql_row_len);
+ MEM_CHECK_ADDRESSABLE(buf, prebuilt->mysql_row_len);
cached_rec = prebuilt->fetch_cache[prebuilt->fetch_cache_first];
@@ -3794,7 +3837,9 @@ row_sel_dequeue_cached_row_for_mysql(
/* The record is long. Copy it field by field, in case
there are some long VARCHAR column of which only a
small length is being used. */
- UNIV_MEM_INVALID(buf, prebuilt->mysql_prefix_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(buf, prebuilt->mysql_prefix_len);
+#endif /* HAVE_valgrind_or_MSAN */
/* First copy the NULL bits. */
ut_memcpy(buf, cached_rec, prebuilt->null_bitmap_len);
@@ -3878,8 +3923,10 @@ row_sel_fetch_last_buf(
}
ut_ad(prebuilt->fetch_cache_first == 0);
- UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
- prebuilt->mysql_row_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
+ prebuilt->mysql_row_len);
+#endif /* HAVE_valgrind_or_MSAN */
return(prebuilt->fetch_cache[prebuilt->n_fetch_cached]);
}
@@ -3918,7 +3965,7 @@ row_sel_try_search_shortcut_for_mysql(
/*==================================*/
const rec_t** out_rec,/*!< out: record if found */
row_prebuilt_t* prebuilt,/*!< in: prebuilt struct */
- ulint** offsets,/*!< in/out: for rec_get_offsets(*out_rec) */
+ rec_offs** offsets,/*!< in/out: for rec_get_offsets(*out_rec) */
mem_heap_t** heap, /*!< in/out: heap for rec_get_offsets() */
mtr_t* mtr) /*!< in: started mtr */
{
@@ -3977,7 +4024,7 @@ row_sel_try_search_shortcut_for_mysql(
/*********************************************************************//**
Check a pushed-down index condition.
-@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
+@return ICP_ABORTED_BY_USER, ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
static
ICP_RESULT
row_search_idx_cond_check(
@@ -3989,7 +4036,7 @@ row_search_idx_cond_check(
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
for the table handle */
const rec_t* rec, /*!< in: InnoDB record */
- const ulint* offsets) /*!< in: rec_get_offsets() */
+ const rec_offs* offsets) /*!< in: rec_get_offsets() */
{
ICP_RESULT result;
ulint i;
@@ -4077,8 +4124,8 @@ row_sel_fill_vrow(
dtuple_t** vrow,
mem_heap_t* heap)
{
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(!(*vrow));
@@ -4129,7 +4176,7 @@ rec_field_len_in_chars(
const dict_col_t* col,
const ulint field_no,
const rec_t* rec,
- const ulint* offsets)
+ const rec_offs* offsets)
{
const ulint cset = dtype_get_charset_coll(col->prtype);
const CHARSET_INFO* cs = all_charsets[cset];
@@ -4156,11 +4203,15 @@ static
bool row_search_with_covering_prefix(
row_prebuilt_t* prebuilt,
const rec_t* rec,
- const ulint* offsets)
+ const rec_offs* offsets)
{
const dict_index_t* index = prebuilt->index;
ut_ad(!dict_index_is_clust(index));
+ if (dict_index_is_spatial(index)) {
+ return false;
+ }
+
if (!srv_prefix_index_cluster_optimization) {
return false;
}
@@ -4171,9 +4222,16 @@ bool row_search_with_covering_prefix(
return false;
}
+ /* We can avoid a clustered index lookup if
+ all of the following hold:
+ (1) all columns are in the secondary index
+ (2) all values for columns that are prefix-only
+ indexes are shorter than the prefix size
+ This optimization can avoid many IOs for certain schemas. */
for (ulint i = 0; i < prebuilt->n_template; i++) {
mysql_row_templ_t* templ = prebuilt->mysql_template + i;
ulint j = templ->rec_prefix_field_no;
+ ut_ad(!templ->mbminlen == !templ->mbmaxlen);
/** Condition (1) : is the field in the index. */
if (j == ULINT_UNDEFINED) {
@@ -4183,33 +4241,29 @@ bool row_search_with_covering_prefix(
/** Condition (2): If this is a prefix index then
row's value size shorter than prefix length. */
- if (!templ->rec_field_is_prefix) {
+ if (!templ->rec_field_is_prefix
+ || rec_offs_nth_sql_null(offsets, j)) {
continue;
}
- ulint rec_size = rec_offs_nth_size(offsets, j);
const dict_field_t* field = dict_index_get_nth_field(index, j);
- ulint max_chars = field->prefix_len / templ->mbmaxlen;
-
- ut_a(field->prefix_len > 0);
- if (rec_size < max_chars) {
- /* Record in bytes shorter than the index
- prefix length in char. */
+ if (!field->prefix_len) {
continue;
}
- if (rec_size * templ->mbminlen >= field->prefix_len) {
+ const ulint rec_size = rec_offs_nth_size(offsets, j);
+
+ if (rec_size >= field->prefix_len) {
/* Shortest representation string by the
byte length of the record is longer than the
maximum possible index prefix. */
return false;
}
- size_t num_chars = rec_field_len_in_chars(
- field->col, j, rec, offsets);
-
- if (num_chars >= max_chars) {
+ if (templ->mbminlen != templ->mbmaxlen
+ && rec_field_len_in_chars(field->col, j, rec, offsets)
+ >= field->prefix_len / templ->mbmaxlen) {
/* No of chars to store the record exceeds
the index prefix character length. */
return false;
@@ -4285,8 +4339,8 @@ row_search_mvcc(
ibool same_user_rec;
mtr_t mtr;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
ibool table_lock_waited = FALSE;
byte* next_buf = 0;
bool spatial_search = false;
@@ -4460,7 +4514,6 @@ row_search_mvcc(
&& !prebuilt->templ_contains_blob
&& !prebuilt->used_in_HANDLER
&& (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) {
-
mode = PAGE_CUR_GE;
if (trx->mysql_n_tables_locked == 0
@@ -4480,7 +4533,8 @@ row_search_mvcc(
and if we try that, we can deadlock on the adaptive
hash index semaphore! */
- rw_lock_s_lock(btr_get_search_latch(index));
+ rw_lock_t* const latch = btr_get_search_latch(index);
+ rw_lock_s_lock(latch);
switch (row_sel_try_search_shortcut_for_mysql(
&rec, prebuilt, &offsets, &heap,
@@ -4497,10 +4551,13 @@ row_search_mvcc(
switch (row_search_idx_cond_check(
buf, prebuilt,
rec, offsets)) {
- case ICP_NO_MATCH:
- case ICP_OUT_OF_RANGE:
case ICP_ABORTED_BY_USER:
+ mtr_commit(&mtr);
+ err = DB_INTERRUPTED;
+ goto unlock_and_exit;
case ICP_ERROR:
+ case ICP_NO_MATCH:
+ case ICP_OUT_OF_RANGE:
goto shortcut_mismatch;
case ICP_MATCH:
goto shortcut_match;
@@ -4528,14 +4585,11 @@ row_search_mvcc(
shortcut_match:
mtr.commit();
-
+ err = DB_SUCCESS;
+ unlock_and_exit:
/* NOTE that we do NOT store the cursor
position */
-
- err = DB_SUCCESS;
-
- rw_lock_s_unlock(btr_get_search_latch(index));
-
+ rw_lock_s_unlock(latch);
goto func_exit;
case SEL_EXHAUSTED:
@@ -4543,13 +4597,7 @@ row_search_mvcc(
mtr.commit();
err = DB_RECORD_NOT_FOUND;
-
- rw_lock_s_unlock(btr_get_search_latch(index));
-
- /* NOTE that we do NOT store the cursor
- position */
-
- goto func_exit;
+ goto unlock_and_exit;
case SEL_RETRY:
break;
@@ -4561,7 +4609,7 @@ row_search_mvcc(
mtr.commit();
mtr.start();
- rw_lock_s_unlock(btr_get_search_latch(index));
+ rw_lock_s_unlock(latch);
}
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -5282,8 +5330,10 @@ no_gap_lock:
buf, prebuilt, rec, offsets)) {
case ICP_NO_MATCH:
goto next_rec;
- case ICP_OUT_OF_RANGE:
case ICP_ABORTED_BY_USER:
+ err = DB_INTERRUPTED;
+ goto idx_cond_failed;
+ case ICP_OUT_OF_RANGE:
case ICP_ERROR:
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
@@ -5342,9 +5392,11 @@ locks_ok_del_marked:
row_unlock_for_mysql(prebuilt, TRUE);
}
goto next_rec;
+ case ICP_ABORTED_BY_USER:
+ err = DB_INTERRUPTED;
+ goto idx_cond_failed;
case ICP_OUT_OF_RANGE:
- case ICP_ABORTED_BY_USER:
- case ICP_ERROR:
+ case ICP_ERROR:
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
case ICP_MATCH:
@@ -5995,8 +6047,8 @@ row_search_autoinc_read_column(
const byte* data;
ib_uint64_t value;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(page_rec_is_leaf(rec));
diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc
index 5e512c602e6..618e161bee4 100644
--- a/storage/innobase/row/row0trunc.cc
+++ b/storage/innobase/row/row0trunc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -39,6 +39,7 @@ Created 2013-04-12 Sunny Bains
#include "os0file.h"
#include "que0que.h"
#include "trx0undo.h"
+#include "btr0sea.h"
/* FIXME: For temporary tables, use a simple approach of btr_free()
and btr_create() of each index tree. */
@@ -1953,7 +1954,6 @@ dberr_t row_truncate_table_for_mysql(dict_table_t* table, trx_t* trx)
for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
index != NULL;
index = UT_LIST_GET_NEXT(indexes, index)) {
-
err = dict_truncate_index_tree_in_mem(index);
if (err != DB_SUCCESS) {
@@ -2003,6 +2003,15 @@ dberr_t row_truncate_table_for_mysql(dict_table_t* table, trx_t* trx)
os_thread_sleep(2000000);
DBUG_SUICIDE(););
+#ifdef BTR_CUR_HASH_ADAPT
+ dict_table_x_unlock_indexes(table);
+ for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index;
+ index = UT_LIST_GET_NEXT(indexes, index)) {
+ index = index->clone_if_needed();
+ }
+ dict_table_x_lock_indexes(table);
+#endif /* BTR_CUR_HASH_ADAPT */
+
/* Step-10: Re-create new indexes. */
if (!dict_table_is_temporary(table)) {
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 7d0664006bb..54fa244fca6 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -114,7 +114,7 @@ row_undo_ins_remove_clust_rec(
if (online && dict_index_is_online_ddl(index)) {
const rec_t* rec = btr_cur_get_rec(btr_cur);
mem_heap_t* heap = NULL;
- const ulint* offsets = rec_get_offsets(
+ const rec_offs* offsets = rec_get_offsets(
rec, index, NULL, true, ULINT_UNDEFINED, &heap);
row_log_table_delete(rec, index, offsets, NULL);
mem_heap_free(heap);
@@ -536,8 +536,8 @@ row_undo_ins(
already be holding dict_sys->mutex, which
would be acquired when updating statistics. */
if (!dict_locked) {
- dict_stats_update_if_needed(
- node->table, node->trx->mysql_thd);
+ dict_stats_update_if_needed(node->table,
+ *node->trx);
}
}
}
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index 3d4065cbab6..80d90f40379 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -75,7 +75,7 @@ dberr_t
row_undo_mod_clust_low(
/*===================*/
undo_node_t* node, /*!< in: row undo node */
- ulint** offsets,/*!< out: rec_get_offsets() on the record */
+ rec_offs** offsets,/*!< out: rec_get_offsets() on the record */
mem_heap_t** offsets_heap,
/*!< in/out: memory heap that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
@@ -169,12 +169,15 @@ row_undo_mod_remove_clust_low(
/* Find out if the record has been purged already
or if we can remove it. */
- if (!btr_pcur_restore_position(mode, &node->pcur, mtr)
- || row_vers_must_preserve_del_marked(node->new_trx_id,
- node->table->name,
- mtr)) {
+ if (!btr_pcur_restore_position(mode, &node->pcur, mtr)) {
+ return DB_SUCCESS;
+ }
- return(DB_SUCCESS);
+ DEBUG_SYNC_C("rollback_purge_clust");
+
+ if (row_vers_must_preserve_del_marked(node->new_trx_id,
+ node->table->name, mtr)) {
+ return DB_SUCCESS;
}
btr_cur = btr_pcur_get_btr_cur(&node->pcur);
@@ -184,7 +187,7 @@ row_undo_mod_remove_clust_low(
if (!trx_id_offset) {
mem_heap_t* heap = NULL;
ulint trx_id_col;
- const ulint* offsets;
+ const rec_offs* offsets;
ulint len;
trx_id_col = dict_index_get_sys_col_pos(
@@ -285,7 +288,7 @@ row_undo_mod_clust(
mem_heap_t* heap = mem_heap_create(1024);
mem_heap_t* offsets_heap = NULL;
- ulint* offsets = NULL;
+ rec_offs* offsets = NULL;
const dtuple_t* rebuilt_old_pk;
byte sys[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN];
@@ -361,6 +364,7 @@ row_undo_mod_clust(
== node->new_trx_id);
btr_pcur_commit_specify_mtr(pcur, &mtr);
+ DEBUG_SYNC_C("rollback_undo_pk");
if (err == DB_SUCCESS && node->rec_type == TRX_UNDO_UPD_DEL_REC) {
@@ -665,7 +669,7 @@ try_again:
switch (search_result) {
mem_heap_t* heap;
mem_heap_t* offsets_heap;
- ulint* offsets;
+ rec_offs* offsets;
case ROW_BUFFERED:
case ROW_NOT_DELETED_REF:
/* These are invalid outcomes, because the mode passed
@@ -880,7 +884,7 @@ row_undo_mod_upd_del_sec(
does not exist. However, this situation may
only occur during the rollback of incomplete
transactions. */
- ut_a(thr_is_recv(thr));
+ ut_a(thr_get_trx(thr) == trx_roll_crash_recv_trx);
} else {
err = row_undo_mod_del_mark_or_remove_sec(
node, thr, index, entry);
@@ -1297,8 +1301,8 @@ row_undo_mod(
already be holding dict_sys->mutex, which
would be acquired when updating statistics. */
if (update_statistics && !dict_locked) {
- dict_stats_update_if_needed(
- node->table, node->trx->mysql_thd);
+ dict_stats_update_if_needed(node->table,
+ *node->trx);
} else {
node->table->stat_modified_counter++;
}
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index 7a245f8279c..b65b173fedb 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -167,8 +167,8 @@ row_undo_search_clust_to_pcur(
row_ext_t** ext;
const rec_t* rec;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(!node->table->skip_alter_undo);
@@ -350,17 +350,16 @@ row_undo_step(
err = row_undo(node, thr);
- trx->error_state = err;
-
- if (err != DB_SUCCESS) {
- /* SQL error detected */
+#ifdef ENABLED_DEBUG_SYNC
+ if (trx->mysql_thd) {
+ DEBUG_SYNC_C("trx_after_rollback_row");
+ }
+#endif /* ENABLED_DEBUG_SYNC */
- if (err == DB_OUT_OF_FILE_SPACE) {
- ib::fatal() << "Out of tablespace during rollback."
- " Consider increasing your tablespace.";
- }
+ trx->error_state = err;
- ib::fatal() << "Error (" << ut_strerr(err) << ") in rollback.";
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
+ ib::fatal() << "Error (" << err << ") in rollback.";
}
return(thr);
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 0153d618ab8..10156c7d3ab 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -214,7 +214,7 @@ row_upd_check_references_constraints(
cursor position is lost in this function! */
dict_table_t* table, /*!< in: table in question */
dict_index_t* index, /*!< in: index of the cursor */
- ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr) /*!< in: mtr */
{
@@ -223,7 +223,6 @@ row_upd_check_references_constraints(
dtuple_t* entry;
trx_t* trx;
const rec_t* rec;
- ulint n_ext;
dberr_t err;
ibool got_s_lock = FALSE;
@@ -240,7 +239,7 @@ row_upd_check_references_constraints(
heap = mem_heap_create(500);
- entry = row_rec_to_index_entry(rec, index, offsets, &n_ext, heap);
+ entry = row_rec_to_index_entry(rec, index, offsets, heap);
mtr_commit(mtr);
@@ -364,7 +363,7 @@ wsrep_row_upd_check_foreign_constraints(
cursor position is lost in this function! */
dict_table_t* table, /*!< in: table in question */
dict_index_t* index, /*!< in: index of the cursor */
- ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr) /*!< in: mtr */
{
@@ -373,7 +372,6 @@ wsrep_row_upd_check_foreign_constraints(
dtuple_t* entry;
trx_t* trx;
const rec_t* rec;
- ulint n_ext;
dberr_t err;
ibool got_s_lock = FALSE;
ibool opened = FALSE;
@@ -391,8 +389,7 @@ wsrep_row_upd_check_foreign_constraints(
heap = mem_heap_create(500);
- entry = row_rec_to_index_entry(rec, index, offsets,
- &n_ext, heap);
+ entry = row_rec_to_index_entry(rec, index, offsets, heap);
mtr_commit(mtr);
@@ -467,7 +464,7 @@ func_exit:
inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
{
- if (!wsrep_on_trx(trx)) {
+ if (!trx->is_wsrep()) {
return false;
}
return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
@@ -505,7 +502,7 @@ row_upd_rec_sys_fields_in_recovery(
/*===============================*/
rec_t* rec, /*!< in/out: record */
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
ulint pos, /*!< in: TRX_ID position in rec */
trx_id_t trx_id, /*!< in: transaction id */
roll_ptr_t roll_ptr)/*!< in: roll ptr of the undo log record */
@@ -571,7 +568,7 @@ ibool
row_upd_changes_field_size_or_external(
/*===================================*/
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
const upd_t* update) /*!< in: update vector */
{
const upd_field_t* upd_field;
@@ -686,7 +683,7 @@ row_upd_rec_in_place(
/*=================*/
rec_t* rec, /*!< in/out: record where replaced */
dict_index_t* index, /*!< in: the index the record belongs to */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */
page_zip_des_t* page_zip)/*!< in: compressed page with enough space
available, or NULL */
@@ -964,7 +961,7 @@ row_upd_build_sec_rec_difference_binary(
/*====================================*/
const rec_t* rec, /*!< in: secondary index record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
const dtuple_t* entry, /*!< in: entry to insert */
mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
@@ -1044,7 +1041,7 @@ row_upd_build_difference_binary(
dict_index_t* index,
const dtuple_t* entry,
const rec_t* rec,
- const ulint* offsets,
+ const rec_offs* offsets,
bool no_sys,
trx_t* trx,
mem_heap_t* heap,
@@ -1057,7 +1054,7 @@ row_upd_build_difference_binary(
ulint n_diff;
ulint trx_id_pos;
ulint i;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
ulint n_fld = dtuple_get_n_fields(entry);
ulint n_v_fld = dtuple_get_n_v_fields(entry);
rec_offs_init(offsets_);
@@ -1119,10 +1116,6 @@ row_upd_build_difference_binary(
for purge/mvcc purpose) */
if (n_v_fld > 0) {
row_ext_t* ext;
- mem_heap_t* v_heap = NULL;
- byte* record;
- VCOL_STORAGE* vcol_storage;
-
THD* thd;
if (trx == NULL) {
@@ -1133,9 +1126,8 @@ row_upd_build_difference_binary(
ut_ad(!update->old_vrow);
- innobase_allocate_row_for_vcol(thd, index, &v_heap,
- &mysql_table,
- &record, &vcol_storage);
+ ib_vcol_row vc(NULL);
+ uchar *record = vc.record(thd, index, &mysql_table);
for (i = 0; i < n_v_fld; i++) {
const dict_v_col_t* col
@@ -1153,10 +1145,9 @@ row_upd_build_difference_binary(
dfield_t* vfield = innobase_get_computed_value(
update->old_vrow, col, index,
- &v_heap, heap, NULL, thd, mysql_table, record,
+ &vc.heap, heap, NULL, thd, mysql_table, record,
NULL, NULL, NULL);
if (vfield == NULL) {
- if (v_heap) mem_heap_free(v_heap);
*error = DB_COMPUTE_VALUE_FAILED;
return(NULL);
}
@@ -1185,12 +1176,6 @@ row_upd_build_difference_binary(
}
}
-
- if (v_heap) {
- if (vcol_storage)
- innobase_free_row_for_vcol(vcol_storage);
- mem_heap_free(v_heap);
- }
}
update->n_fields = n_diff;
@@ -1209,7 +1194,9 @@ containing also the reference to the external part
@param[in,out] len input - length of prefix to
fetch; output: fetched length of the prefix
@param[in,out] heap heap where to allocate
-@return BLOB prefix */
+@return BLOB prefix
+@retval NULL if the record is incomplete (should only happen
+in row_vers_vc_matches_cluster() executed concurrently with another purge) */
static
byte*
row_upd_ext_fetch(
@@ -1224,10 +1211,7 @@ row_upd_ext_fetch(
*len = btr_copy_externally_stored_field_prefix(
buf, *len, page_size, data, local_len);
- /* We should never update records containing a half-deleted BLOB. */
- ut_a(*len);
-
- return(buf);
+ return *len ? buf : NULL;
}
/** Replaces the new column value stored in the update vector in
@@ -1238,9 +1222,11 @@ the given index entry field.
@param[in] uf update field
@param[in,out] heap memory heap for allocating and copying
the new value
-@param[in] page_size page size */
+@param[in] page_size page size
+@return whether the previous version was built successfully */
+MY_ATTRIBUTE((nonnull, warn_unused_result))
static
-void
+bool
row_upd_index_replace_new_col_val(
dfield_t* dfield,
const dict_field_t* field,
@@ -1255,7 +1241,7 @@ row_upd_index_replace_new_col_val(
dfield_copy_data(dfield, &uf->new_val);
if (dfield_is_null(dfield)) {
- return;
+ return true;
}
len = dfield_get_len(dfield);
@@ -1273,6 +1259,9 @@ row_upd_index_replace_new_col_val(
data = row_upd_ext_fetch(data, l, page_size,
&len, heap);
+ if (UNIV_UNLIKELY(!data)) {
+ return false;
+ }
}
len = dtype_get_at_most_n_mbchars(col->prtype,
@@ -1286,7 +1275,7 @@ row_upd_index_replace_new_col_val(
dfield_dup(dfield, heap);
}
- return;
+ return true;
}
switch (uf->orig_len) {
@@ -1325,6 +1314,8 @@ row_upd_index_replace_new_col_val(
dfield_set_ext(dfield);
break;
}
+
+ return true;
}
/***********************************************************//**
@@ -1382,68 +1373,57 @@ row_upd_index_replace_new_col_vals_index_pos(
update, i, false);
}
- if (uf) {
- row_upd_index_replace_new_col_val(
- dtuple_get_nth_field(entry, i),
- field, col, uf, heap, page_size);
+ if (uf && UNIV_UNLIKELY(!row_upd_index_replace_new_col_val(
+ dtuple_get_nth_field(entry, i),
+ field, col, uf, heap,
+ page_size))) {
+ ut_error;
}
}
}
-/***********************************************************//**
-Replaces the new column values stored in the update vector to the index entry
-given. */
-void
-row_upd_index_replace_new_col_vals(
-/*===============================*/
- dtuple_t* entry, /*!< in/out: index entry where replaced;
- the clustered index record must be
- covered by a lock or a page latch to
- prevent deletion (rollback or purge) */
- dict_index_t* index, /*!< in: index; NOTE that this may also be a
- non-clustered index */
- const upd_t* update, /*!< in: an update vector built for the
- CLUSTERED index so that the field number in
- an upd_field is the clustered index position */
- mem_heap_t* heap) /*!< in: memory heap for allocating and
- copying the new values */
+/** Replace the new column values stored in the update vector,
+during trx_undo_prev_version_build().
+@param entry clustered index tuple where the values are replaced
+ (the clustered index leaf page latch must be held)
+@param index clustered index
+@param update update vector for the clustered index
+@param heap memory heap for allocating and copying values
+@return whether the previous version was built successfully */
+bool
+row_upd_index_replace_new_col_vals(dtuple_t *entry, const dict_index_t &index,
+ const upd_t *update, mem_heap_t *heap)
{
- ulint i;
- const dict_index_t* clust_index
- = dict_table_get_first_index(index->table);
- const page_size_t& page_size = dict_table_page_size(index->table);
-
- ut_ad(!index->table->skip_alter_undo);
-
- dtuple_set_info_bits(entry, update->info_bits);
-
- for (i = 0; i < dict_index_get_n_fields(index); i++) {
- const dict_field_t* field;
- const dict_col_t* col;
- const upd_field_t* uf;
-
- field = dict_index_get_nth_field(index, i);
- col = dict_field_get_col(field);
- if (dict_col_is_virtual(col)) {
- const dict_v_col_t* vcol = reinterpret_cast<
- const dict_v_col_t*>(
- col);
-
- uf = upd_get_field_by_field_no(
- update, vcol->v_pos, true);
- } else {
- uf = upd_get_field_by_field_no(
- update,
- dict_col_get_clust_pos(col, clust_index),
- false);
- }
-
- if (uf) {
- row_upd_index_replace_new_col_val(
- dtuple_get_nth_field(entry, i),
- field, col, uf, heap, page_size);
- }
- }
+ ut_ad(index.is_primary());
+ const page_size_t& page_size= dict_table_page_size(index.table);
+
+ ut_ad(!index.table->skip_alter_undo);
+ dtuple_set_info_bits(entry, update->info_bits);
+
+ for (ulint i= 0; i < index.n_fields; i++)
+ {
+ const dict_field_t *field= &index.fields[i];
+ const dict_col_t* col= dict_field_get_col(field);
+ const upd_field_t *uf;
+
+ if (col->is_virtual())
+ {
+ const dict_v_col_t *vcol= reinterpret_cast<const dict_v_col_t*>(col);
+ uf= upd_get_field_by_field_no(update, vcol->v_pos, true);
+ }
+ else
+ uf= upd_get_field_by_field_no(update, dict_col_get_clust_pos(col, &index),
+ false);
+
+ if (!uf)
+ continue;
+
+ if (!row_upd_index_replace_new_col_val(dtuple_get_nth_field(entry, i),
+ field, col, uf, heap, page_size))
+ return false;
+ }
+
+ return true;
}
/** Replaces the virtual column values stored in the update vector.
@@ -1870,7 +1850,9 @@ row_upd_changes_ord_field_binary_func(
/* Silence a compiler warning without
silencing a Valgrind error. */
dfield_len = 0;
- UNIV_MEM_INVALID(&dfield_len, sizeof dfield_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&dfield_len, sizeof dfield_len);
+#endif /* HAVE_valgrind_or_MSAN */
/* See if the column is stored externally. */
buf = row_ext_lookup(ext, col_no, &dfield_len);
@@ -1885,7 +1867,8 @@ row_upd_changes_ord_field_binary_func(
when the server had crashed before
storing the field. */
ut_ad(thr->graph->trx->is_recovered);
- ut_ad(trx_is_recv(thr->graph->trx));
+ ut_ad(thr->graph->trx
+ == trx_roll_crash_recv_trx);
return(TRUE);
}
@@ -2070,7 +2053,7 @@ void
row_upd_copy_columns(
/*=================*/
rec_t* rec, /*!< in: record in a clustered index */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
sym_node_t* column) /*!< in: first column in a column list, or
NULL */
{
@@ -2118,23 +2101,19 @@ row_upd_eval_new_vals(
@param[in,out] node row update node
@param[in] update an update vector if it is update
@param[in] thd mysql thread handle
-@param[in,out] mysql_table mysql table object */
+@param[in,out] mysql_table mysql table object
+@return true if success
+ false if virtual column value computation fails. */
static
-void
+bool
row_upd_store_v_row(
upd_node_t* node,
const upd_t* update,
THD* thd,
TABLE* mysql_table)
{
- mem_heap_t* heap = NULL;
dict_index_t* index = dict_table_get_first_index(node->table);
- byte* record= 0;
- VCOL_STORAGE *vcol_storage= 0;
-
- if (!update)
- innobase_allocate_row_for_vcol(thd, index, &heap, &mysql_table,
- &record, &vcol_storage);
+ ib_vcol_row vc(NULL);
for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(node->table);
col_no++) {
@@ -2184,32 +2163,37 @@ row_upd_store_v_row(
dfield_dup(dfield, node->heap);
}
} else {
+ uchar *record = vc.record(thd, index,
+ &mysql_table);
/* Need to compute, this happens when
deleting row */
- innobase_get_computed_value(
- node->row, col, index,
- &heap, node->heap, NULL,
- thd, mysql_table, record, NULL,
- NULL, NULL);
+ dfield_t* vfield =
+ innobase_get_computed_value(
+ node->row, col, index,
+ &vc.heap, node->heap,
+ NULL, thd, mysql_table,
+ record, NULL, NULL,
+ NULL);
+ if (vfield == NULL) {
+ return false;
+ }
}
}
}
}
- if (heap) {
- if (vcol_storage)
- innobase_free_row_for_vcol(vcol_storage);
- mem_heap_free(heap);
- }
-
+ return true;
}
/** Stores to the heap the row on which the node->pcur is positioned.
@param[in] node row update node
@param[in] thd mysql thread handle
@param[in,out] mysql_table NULL, or mysql table object when
- user thread invokes dml */
-void
+ user thread invokes dml
+@return false if virtual column value computation fails
+ true otherwise. */
+static
+bool
row_upd_store_row(
upd_node_t* node,
THD* thd,
@@ -2219,8 +2203,8 @@ row_upd_store_row(
rec_t* rec;
mem_heap_t* heap = NULL;
row_ext_t** ext;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- const ulint* offsets;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ const rec_offs* offsets;
rec_offs_init(offsets_);
ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES);
@@ -2253,8 +2237,12 @@ row_upd_store_row(
NULL, NULL, NULL, ext, node->heap);
if (node->table->n_v_cols) {
- row_upd_store_v_row(node, node->is_delete ? NULL : node->update,
+ bool ok = row_upd_store_v_row(node,
+ node->is_delete ? NULL : node->update,
thd, mysql_table);
+ if (!ok) {
+ return false;
+ }
}
if (node->is_delete) {
@@ -2269,6 +2257,7 @@ row_upd_store_row(
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
+ return true;
}
/***********************************************************//**
@@ -2437,7 +2426,7 @@ row_upd_sec_index_entry(
#ifdef UNIV_DEBUG
mtr_commit(&mtr);
mtr_start(&mtr);
- ut_ad(btr_validate_index(index, 0, false));
+ ut_ad(btr_validate_index(index, 0, false) == DB_SUCCESS);
ut_ad(0);
#endif /* UNIV_DEBUG */
break;
@@ -2459,7 +2448,7 @@ row_upd_sec_index_entry(
&& wsrep_must_process_fk(node, trx)
&& !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
- ulint* offsets = rec_get_offsets(
+ rec_offs* offsets = rec_get_offsets(
rec, index, NULL, true,
ULINT_UNDEFINED, &heap);
@@ -2473,7 +2462,7 @@ row_upd_sec_index_entry(
err = DB_SUCCESS;
break;
case DB_LOCK_WAIT:
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::warn() << "WSREP: sec index FK lock wait"
<< " index " << index->name
<< " table " << index->table->name
@@ -2481,7 +2470,7 @@ row_upd_sec_index_entry(
}
break;
case DB_DEADLOCK:
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::warn() << "WSREP: sec index FK check fail for deadlock"
<< " index " << index->name
<< " table " << index->table->name
@@ -2489,7 +2478,7 @@ row_upd_sec_index_entry(
}
break;
default:
- ib::error() << "WSREP: referenced FK check fail: " << ut_strerr(err)
+ ib::error() << "WSREP: referenced FK check fail: " << err
<< " index " << index->name
<< " table " << index->table->name
<< " query " << wsrep_thd_query(trx->mysql_thd);
@@ -2504,7 +2493,7 @@ row_upd_sec_index_entry(
if (referenced) {
- ulint* offsets;
+ rec_offs* offsets;
offsets = rec_get_offsets(
rec, index, NULL, true, ULINT_UNDEFINED,
@@ -2586,7 +2575,7 @@ row_upd_clust_rec_by_insert_inherit_func(
/*=====================================*/
const rec_t* rec, /*!< in: old record, or NULL */
#ifdef UNIV_DEBUG
- const ulint* offsets,/*!< in: rec_get_offsets(rec), or NULL */
+ const rec_offs* offsets,/*!< in: rec_get_offsets(rec), or NULL */
#endif /* UNIV_DEBUG */
dtuple_t* entry, /*!< in/out: updated entry to be
inserted into the clustered index */
@@ -2687,10 +2676,13 @@ row_upd_clust_rec_by_insert(
dtuple_t* entry;
dberr_t err;
rec_t* rec;
- ulint* offsets = NULL;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets = offsets_;
ut_ad(dict_index_is_clust(index));
+ rec_offs_init(offsets_);
+
trx = thr_get_trx(thr);
table = node->table;
pcur = node->pcur;
@@ -2718,7 +2710,7 @@ row_upd_clust_rec_by_insert(
we update the primary key. Delete-mark the old record
in the clustered index and prepare to insert a new entry. */
rec = btr_cur_get_rec(btr_cur);
- offsets = rec_get_offsets(rec, index, NULL, true,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
ut_ad(page_rec_is_user_rec(rec));
@@ -2785,14 +2777,14 @@ check_fk:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::warn() << "WSREP: sec index FK check fail for deadlock"
<< " index " << index->name
<< " table " << index->table->name;
}
goto err_exit;
default:
- ib::error() << "WSREP: referenced FK check fail: " << ut_strerr(err)
+ ib::error() << "WSREP: referenced FK check fail: " << err
<< " index " << index->name
<< " table " << index->table->name;
goto err_exit;
@@ -2804,8 +2796,7 @@ check_fk:
mtr_commit(mtr);
err = row_ins_clust_index_entry(
- index, entry, thr,
- node->upd_ext ? node->upd_ext->n_ext : 0);
+ index, entry, thr, dtuple_get_n_ext(entry));
node->state = UPD_NODE_INSERT_CLUSTERED;
mem_heap_free(heap);
@@ -2825,7 +2816,7 @@ row_upd_clust_rec(
ulint flags, /*!< in: undo logging and locking flags */
upd_node_t* node, /*!< in: row update node */
dict_index_t* index, /*!< in: clustered index */
- ulint* offsets,/*!< in: rec_get_offsets() on node->pcur */
+ rec_offs* offsets,/*!< in: rec_get_offsets() on node->pcur */
mem_heap_t** offsets_heap,
/*!< in/out: memory heap, can be emptied */
que_thr_t* thr, /*!< in: query thread */
@@ -2956,7 +2947,7 @@ row_upd_del_mark_clust_rec(
/*=======================*/
upd_node_t* node, /*!< in: row update node */
dict_index_t* index, /*!< in: clustered index */
- ulint* offsets,/*!< in/out: rec_get_offsets() for the
+ rec_offs* offsets,/*!< in/out: rec_get_offsets() for the
record under the cursor */
que_thr_t* thr, /*!< in: query thread */
ibool referenced,
@@ -2982,9 +2973,12 @@ row_upd_del_mark_clust_rec(
/* Store row because we have to build also the secondary index
entries */
- row_upd_store_row(node, trx->mysql_thd,
+ if (!row_upd_store_row(node, trx->mysql_thd,
thr->prebuilt && thr->prebuilt->table == node->table
- ? thr->prebuilt->m_mysql_table : NULL);
+ ? thr->prebuilt->m_mysql_table : NULL)) {
+ err = DB_COMPUTE_VALUE_FAILED;
+ return err;
+ }
/* Mark the clustered index record deleted; we do not have to check
locks, because we assume that we have an x-lock on the record */
@@ -3012,14 +3006,14 @@ row_upd_del_mark_clust_rec(
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::warn() << "WSREP: sec index FK check fail for deadlock"
<< " index " << index->name
<< " table " << index->table->name;
}
break;
default:
- ib::error() << "WSREP: referenced FK check fail: " << ut_strerr(err)
+ ib::error() << "WSREP: referenced FK check fail: " << err
<< " index " << index->name
<< " table " << index->table->name;
@@ -3051,8 +3045,8 @@ row_upd_clust_step(
mtr_t mtr;
rec_t* rec;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets;
+ rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets;
ibool referenced;
trx_t* trx = thr_get_trx(thr);
@@ -3193,8 +3187,11 @@ row_upd_clust_step(
goto exit_func;
}
- row_upd_store_row(node, trx->mysql_thd,
- thr->prebuilt ? thr->prebuilt->m_mysql_table : NULL);
+ if(!row_upd_store_row(node, trx->mysql_thd,
+ thr->prebuilt ? thr->prebuilt->m_mysql_table : NULL)) {
+ err = DB_COMPUTE_VALUE_FAILED;
+ goto exit_func;
+ }
if (row_upd_changes_ord_field_binary(index, node->update, thr,
node->row, node->ext)) {
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index f2a574b8331..2d8704764d1 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -86,24 +86,27 @@ row_vers_impl_x_locked_low(
dict_index_t* clust_index,
const rec_t* rec,
dict_index_t* index,
- const ulint* offsets,
+ const rec_offs* offsets,
mtr_t* mtr)
{
rec_t* prev_version = NULL;
- ulint* clust_offsets;
+ rec_offs clust_offsets_[REC_OFFS_NORMAL_SIZE];
+ rec_offs* clust_offsets;
mem_heap_t* heap;
dtuple_t* ientry = NULL;
mem_heap_t* v_heap = NULL;
dtuple_t* cur_vrow = NULL;
+ rec_offs_init(clust_offsets_);
+
DBUG_ENTER("row_vers_impl_x_locked_low");
ut_ad(rec_offs_validate(rec, index, offsets));
heap = mem_heap_create(1024);
- clust_offsets = rec_get_offsets(
- clust_rec, clust_index, NULL, true, ULINT_UNDEFINED, &heap);
+ clust_offsets = rec_get_offsets(clust_rec, clust_index, clust_offsets_,
+ true, ULINT_UNDEFINED, &heap);
const trx_id_t trx_id = row_get_rec_trx_id(
clust_rec, clust_index, clust_offsets);
@@ -116,7 +119,7 @@ row_vers_impl_x_locked_low(
if (trx == 0) {
/* The transaction that modified or inserted clust_rec is no
longer active, or it is corrupt: no implicit lock on rec */
- if (corrupt) {
+ if (UNIV_UNLIKELY(corrupt)) {
lock_report_trx_id_insanity(
trx_id, clust_rec, clust_index, clust_offsets,
trx_sys_get_max_trx_id());
@@ -133,15 +136,13 @@ row_vers_impl_x_locked_low(
const ulint rec_del = rec_get_deleted_flag(rec, comp);
if (dict_index_has_virtual(index)) {
- ulint n_ext;
ulint est_size = DTUPLE_EST_ALLOC(index->n_fields);
/* Allocate the dtuple for virtual columns extracted from undo
log with its own heap, so to avoid it being freed as we
iterating in the version loop below. */
v_heap = mem_heap_create(est_size);
- ientry = row_rec_to_index_entry(
- rec, index, offsets, &n_ext, v_heap);
+ ientry = row_rec_to_index_entry(rec, index, offsets, v_heap);
}
/* We look up if some earlier version, which was modified by
@@ -221,7 +222,7 @@ not_locked:
}
clust_offsets = rec_get_offsets(
- prev_version, clust_index, NULL, true,
+ prev_version, clust_index, clust_offsets_, true,
ULINT_UNDEFINED, &heap);
vers_del = rec_get_deleted_flag(prev_version, comp);
@@ -368,7 +369,7 @@ trx_t*
row_vers_impl_x_locked(
const rec_t* rec,
dict_index_t* index,
- const ulint* offsets)
+ const rec_offs* offsets)
{
mtr_t mtr;
trx_t* trx;
@@ -444,9 +445,11 @@ row_vers_must_preserve_del_marked(
@param[in] clust_index clustered index
@param[in] index the secondary index
@param[in] heap heap used to build virtual dtuple
-@param[in,out] vcol_info virtual column information. */
+@param[in,out] vcol_info virtual column information.
+@return true in case of success
+ false if virtual column computation fails */
static
-void
+bool
row_vers_build_clust_v_col(
dtuple_t* row,
dict_index_t* clust_index,
@@ -454,11 +457,8 @@ row_vers_build_clust_v_col(
mem_heap_t* heap,
purge_vcol_info_t* vcol_info)
{
- mem_heap_t* local_heap = NULL;
- VCOL_STORAGE *vcol_storage= NULL;
THD* thd= current_thd;
TABLE* maria_table= 0;
- byte* record= 0;
ut_ad(dict_index_has_virtual(index));
ut_ad(index->table == clust_index->table);
@@ -467,17 +467,14 @@ row_vers_build_clust_v_col(
vcol_info->set_used();
maria_table = vcol_info->table();
}
- DEBUG_SYNC(current_thd, "ib_clust_v_col_before_row_allocated");
- innobase_allocate_row_for_vcol(thd, index,
- &local_heap,
- &maria_table,
- &record,
- &vcol_storage);
+ ib_vcol_row vc(NULL);
+ byte *record = vc.record(thd, index, &maria_table);
if (vcol_info && !vcol_info->table()) {
vcol_info->set_table(maria_table);
- goto func_exit;
+ // wait for second fetch
+ return true;
}
for (ulint i = 0; i < dict_index_get_n_fields(index); i++) {
@@ -490,19 +487,18 @@ row_vers_build_clust_v_col(
col = reinterpret_cast<const dict_v_col_t*>(
ind_field->col);
- innobase_get_computed_value(
- row, col, clust_index, &local_heap,
+ dfield_t *vfield = innobase_get_computed_value(
+ row, col, clust_index, &vc.heap,
heap, NULL, thd, maria_table, record, NULL,
NULL, NULL);
+ if (vfield == NULL) {
+ innobase_report_computed_value_failed(row);
+ ut_ad(0);
+ return false;
+ }
}
}
-
-func_exit:
- if (local_heap) {
- if (vcol_storage)
- innobase_free_row_for_vcol(vcol_storage);
- mem_heap_free(local_heap);
- }
+ return true;
}
/** Build latest virtual column data from undo log
@@ -522,7 +518,7 @@ row_vers_build_cur_vrow_low(
bool in_purge,
const rec_t* rec,
dict_index_t* clust_index,
- ulint* clust_offsets,
+ rec_offs* clust_offsets,
dict_index_t* index,
roll_ptr_t roll_ptr,
trx_id_t trx_id,
@@ -618,7 +614,6 @@ row_vers_build_cur_vrow_low(
/** Check a virtual column value index secondary virtual index matches
that of current cluster index record, which is recreated from information
stored in undo log
-@param[in] in_purge called by purge thread
@param[in] rec record in the clustered index
@param[in] icentry the index entry built from a cluster row
@param[in] clust_index cluster index
@@ -634,11 +629,10 @@ stored in undo log
static
bool
row_vers_vc_matches_cluster(
- bool in_purge,
const rec_t* rec,
const dtuple_t* icentry,
dict_index_t* clust_index,
- ulint* clust_offsets,
+ rec_offs* clust_offsets,
dict_index_t* index,
const dtuple_t* ientry,
roll_ptr_t roll_ptr,
@@ -695,12 +689,6 @@ row_vers_vc_matches_cluster(
version = rec;
- /* If this is called by purge thread, set TRX_UNDO_PREV_IN_PURGE
- bit to search the undo log until we hit the current undo log with
- roll_ptr */
- ulint status = (in_purge ? TRX_UNDO_PREV_IN_PURGE : 0)
- | TRX_UNDO_GET_OLD_V_VALUE;
-
while (n_cmp_v_col < n_fields - n_non_v_col) {
heap2 = heap;
heap = mem_heap_create(1024);
@@ -708,11 +696,12 @@ row_vers_vc_matches_cluster(
version, clust_index, clust_offsets);
ut_ad(cur_roll_ptr != 0);
- ut_ad(in_purge == (roll_ptr != 0));
+ ut_ad(roll_ptr != 0);
trx_undo_prev_version_build(
rec, mtr, version, clust_index, clust_offsets,
- heap, &prev_version, NULL, vrow, status);
+ heap, &prev_version, NULL, vrow,
+ TRX_UNDO_PREV_IN_PURGE | TRX_UNDO_GET_OLD_V_VALUE);
if (heap2) {
mem_heap_free(heap2);
@@ -814,7 +803,7 @@ row_vers_build_cur_vrow(
bool in_purge,
const rec_t* rec,
dict_index_t* clust_index,
- ulint** clust_offsets,
+ rec_offs** clust_offsets,
dict_index_t* index,
const dtuple_t* ientry,
roll_ptr_t roll_ptr,
@@ -846,8 +835,11 @@ row_vers_build_cur_vrow(
mtr->commit();
}
- row_vers_build_clust_v_col(
+ bool res = row_vers_build_clust_v_col(
row, clust_index, index, heap, vcol_info);
+ if (!res) {
+ return NULL;
+ }
if (vcol_info != NULL && vcol_info->is_first_fetch()) {
return NULL;
@@ -899,7 +891,7 @@ row_vers_old_has_index_entry(
const rec_t* version;
rec_t* prev_version;
dict_index_t* clust_index;
- ulint* clust_offsets;
+ rec_offs* clust_offsets;
mem_heap_t* heap;
mem_heap_t* heap2;
dtuple_t* row;
@@ -968,10 +960,14 @@ row_vers_old_has_index_entry(
mtr->commit();
}
- row_vers_build_clust_v_col(
+ bool res = row_vers_build_clust_v_col(
row, clust_index, index, heap,
vcol_info);
+ if (!res) {
+ goto unsafe_to_purge;
+ }
+
if (vcol_info && vcol_info->is_first_fetch()) {
goto unsafe_to_purge;
}
@@ -996,7 +992,7 @@ row_vers_old_has_index_entry(
secondary indexes.) */
if (entry && row_vers_vc_matches_cluster(
- also_curr, rec, entry,
+ rec, entry,
clust_index, clust_offsets,
index, ientry, roll_ptr,
trx_id, NULL, &vrow, mtr)) {
@@ -1157,7 +1153,7 @@ row_vers_build_for_consistent_read(
of this records */
mtr_t* mtr, /*!< in: mtr holding the latch on rec */
dict_index_t* index, /*!< in: the clustered index */
- ulint** offsets,/*!< in/out: offsets returned by
+ rec_offs** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
ReadView* view, /*!< in: the consistent read view */
mem_heap_t** offset_heap,/*!< in/out: memory heap from which
@@ -1272,7 +1268,7 @@ row_vers_build_for_semi_consistent_read(
of this records */
mtr_t* mtr, /*!< in: mtr holding the latch on rec */
dict_index_t* index, /*!< in: the clustered index */
- ulint** offsets,/*!< in/out: offsets returned by
+ rec_offs** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
diff --git a/storage/innobase/srv/srv0conc.cc b/storage/innobase/srv/srv0conc.cc
index 347e604479a..b420ca6d8ee 100644
--- a/storage/innobase/srv/srv0conc.cc
+++ b/storage/innobase/srv/srv0conc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2018, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -122,9 +122,8 @@ srv_conc_enter_innodb_with_atomics(
for (;;) {
ulint sleep_in_us;
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_trx_is_aborting(trx->mysql_thd)) {
- if (wsrep_debug) {
+ if (trx->is_wsrep() && wsrep_trx_is_aborting(trx->mysql_thd)) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::info() <<
"srv_conc_enter due to MUST_ABORT";
}
@@ -325,14 +324,14 @@ wsrep_srv_conc_cancel_wait(
srv_conc_enter_innodb_with_atomics(). No need to cancel here,
thr will wake up after os_sleep and let to enter innodb
*/
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::info() << "WSREP: conc slot cancel, no atomics";
}
#else
// JAN: TODO: MySQL 5.7
//os_fast_mutex_lock(&srv_conc_mutex);
if (trx->wsrep_event) {
- if (wsrep_debug) {
+ if (UNIV_UNLIKELY(wsrep_debug)) {
ib::info() << "WSREP: conc slot cancel";
}
os_event_set(trx->wsrep_event);
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 2c33496ca52..f1216dcd51e 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -3,7 +3,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -507,7 +507,9 @@ current_time % 60 == 0 and no tasks will be performed when
current_time % 5 != 0. */
# define SRV_MASTER_CHECKPOINT_INTERVAL (7)
-# define SRV_MASTER_PURGE_INTERVAL (10)
+#ifdef MEM_PERIODIC_CHECK
+# define SRV_MASTER_MEM_VALIDATE_INTERVAL (13)
+#endif /* MEM_PERIODIC_CHECK */
# define SRV_MASTER_DICT_LRU_INTERVAL (47)
/** Simulate compression failures. */
@@ -1331,7 +1333,8 @@ srv_printf_innodb_monitor(
ibuf_print(file);
#ifdef BTR_CUR_HASH_ADAPT
- for (ulint i = 0; i < btr_ahi_parts; ++i) {
+ btr_search_x_lock_all();
+ for (ulint i = 0; i < btr_ahi_parts && btr_search_enabled; ++i) {
const hash_table_t* table = btr_search_sys->hash_tables[i];
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
@@ -1355,6 +1358,7 @@ srv_printf_innodb_monitor(
", node heap has " ULINTPF " buffer(s)\n",
table->n_cells, heap->base.count - !heap->free_block);
}
+ btr_search_x_unlock_all();
fprintf(file,
"%.2f hash searches/s, %.2f non-hash searches/s\n",
@@ -1798,7 +1802,7 @@ loop:
srv_refresh_innodb_monitor_stats();
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
goto exit_func;
}
@@ -1910,7 +1914,7 @@ loop:
os_event_wait_time_low(srv_error_event, 1000000, sig_count);
- if (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
goto loop;
}
@@ -1960,7 +1964,7 @@ srv_get_active_thread_type(void)
srv_sys_mutex_exit();
- if (ret == SRV_NONE && srv_shutdown_state != SRV_SHUTDOWN_NONE
+ if (ret == SRV_NONE && srv_shutdown_state > SRV_SHUTDOWN_INITIATED
&& purge_sys != NULL) {
/* Check only on shutdown. */
switch (trx_purge_state()) {
@@ -2215,7 +2219,7 @@ srv_master_do_active_tasks(void)
ut_d(srv_master_do_disabled_loop());
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
return;
}
@@ -2240,7 +2244,7 @@ srv_master_do_active_tasks(void)
/* Now see if various tasks that are performed at defined
intervals need to be performed. */
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
return;
}
@@ -2265,7 +2269,7 @@ srv_master_do_active_tasks(void)
early and often to avoid those situations. */
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", return;);
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
return;
}
@@ -2308,7 +2312,7 @@ srv_master_do_idle_tasks(void)
ut_d(srv_master_do_disabled_loop());
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
return;
}
@@ -2324,7 +2328,7 @@ srv_master_do_idle_tasks(void)
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time);
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
return;
}
@@ -2352,7 +2356,7 @@ srv_master_do_idle_tasks(void)
early and often to avoid those situations. */
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", return;);
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
return;
}
@@ -2361,6 +2365,10 @@ srv_master_do_idle_tasks(void)
log_checkpoint(true);
MONITOR_INC_TIME_IN_MICRO_SECS(MONITOR_SRV_CHECKPOINT_MICROSECOND,
counter_time);
+
+ /* This is a workaround to avoid the InnoDB hang when OS datetime
+ changed backwards.*/
+ os_event_set(buf_flush_event);
}
/** Perform shutdown tasks.
@@ -2450,8 +2458,7 @@ DECLARE_THREAD(srv_master_thread)(
ut_a(slot == srv_sys.sys_threads);
loop:
- while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
-
+ while (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
srv_master_sleep();
MONITOR_INC(MONITOR_MASTER_THREAD_SLEEP);
@@ -2466,6 +2473,7 @@ loop:
switch (srv_shutdown_state) {
case SRV_SHUTDOWN_NONE:
+ case SRV_SHUTDOWN_INITIATED:
break;
case SRV_SHUTDOWN_FLUSH_PHASE:
case SRV_SHUTDOWN_LAST_PHASE:
@@ -2504,8 +2512,7 @@ static
bool
srv_purge_should_exit(ulint n_purged)
{
- ut_ad(srv_shutdown_state == SRV_SHUTDOWN_NONE
- || srv_shutdown_state == SRV_SHUTDOWN_CLEANUP);
+ ut_ad(srv_shutdown_state <= SRV_SHUTDOWN_CLEANUP);
if (srv_undo_sources) {
return(false);
@@ -2514,18 +2521,20 @@ srv_purge_should_exit(ulint n_purged)
return(true);
}
/* Slow shutdown was requested. */
- if (n_purged) {
-#if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY
+ if (ulint history_size = n_purged ? trx_sys->rseg_history_len : 0) {
static time_t progress_time;
time_t now = time(NULL);
if (now - progress_time >= 15) {
progress_time = now;
+#if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY
service_manager_extend_timeout(
INNODB_EXTEND_TIMEOUT_INTERVAL,
"InnoDB: to purge " ULINTPF " transactions",
- trx_sys->rseg_history_len);
- }
+ history_size);
#endif
+ ib::info() << "to purge " << history_size
+ << " transactions";
+ }
/* The previous round still did some work. */
return(false);
}
@@ -2598,13 +2607,6 @@ DECLARE_THREAD(srv_worker_thread)(
slot = srv_reserve_slot(SRV_WORKER);
-#ifdef UNIV_DEBUG
- UT_LIST_INIT(slot->debug_sync,
- &srv_slot_t::debug_sync_t::debug_sync_list);
- rw_lock_create(PFS_NOT_INSTRUMENTED, &slot->debug_sync_lock,
- SYNC_NO_ORDER_CHECK);
-#endif
-
ut_a(srv_n_purge_threads > 1);
ut_a(ulong(my_atomic_loadlint(&srv_sys.n_threads_active[SRV_WORKER]))
< srv_n_purge_threads);
@@ -2782,7 +2784,7 @@ srv_purge_coordinator_suspend(
rw_lock_x_lock(&purge_sys->latch);
- stop = (srv_shutdown_state == SRV_SHUTDOWN_NONE
+ stop = (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& purge_sys->state == PURGE_STATE_STOP);
if (!stop) {
@@ -2852,19 +2854,13 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
slot = srv_reserve_slot(SRV_PURGE);
-#ifdef UNIV_DEBUG
- UT_LIST_INIT(slot->debug_sync,
- &srv_slot_t::debug_sync_t::debug_sync_list);
- rw_lock_create(PFS_NOT_INSTRUMENTED, &slot->debug_sync_lock,
- SYNC_NO_ORDER_CHECK);
-#endif
ulint rseg_history_len = trx_sys->rseg_history_len;
do {
/* If there are no records to purge or the last
purge didn't purge any records then wait for activity. */
- if (srv_shutdown_state == SRV_SHUTDOWN_NONE
+ if (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& srv_undo_sources
&& (purge_sys->state == PURGE_STATE_STOP
|| n_total_purged == 0)) {
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 75bdf17eab7..0d8ebbe98cd 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -3,7 +3,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -696,6 +696,7 @@ static bool srv_undo_tablespace_open(const char* name, ulint space_id,
if (create_new_db) {
space->size = file->size = ulint(size >> srv_page_size_shift);
space->size_in_header = SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
+ space->committed_size = SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
} else {
success = file->read_page0(true);
if (!success) {
@@ -874,6 +875,7 @@ srv_undo_tablespaces_init(bool create_new_db)
break;
}
/* fall through */
+ case SRV_OPERATION_RESTORE_ROLLBACK_XA:
case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_EXPORT:
ut_ad(!create_new_db);
@@ -1043,7 +1045,7 @@ srv_undo_tablespaces_init(bool create_new_db)
fsp_header_init(
*it, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
- mtr_x_lock(fil_space_get_latch(*it, NULL), &mtr);
+ mtr_x_lock_space(*it, &mtr);
for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
@@ -1091,7 +1093,7 @@ srv_start_wait_for_purge_to_start()
ut_a(state != PURGE_STATE_DISABLED);
- while (srv_shutdown_state == SRV_SHUTDOWN_NONE
+ while (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND
&& state == PURGE_STATE_INIT) {
@@ -1280,6 +1282,7 @@ srv_shutdown_all_bg_threads()
case SRV_OPERATION_RESTORE_DELTA:
break;
case SRV_OPERATION_NORMAL:
+ case SRV_OPERATION_RESTORE_ROLLBACK_XA:
case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_EXPORT:
if (!buf_page_cleaner_is_active
@@ -1327,7 +1330,7 @@ srv_init_abort_low(
#ifdef UNIV_DEBUG
" at " << innobase_basename(file) << "[" << line << "]"
#endif /* UNIV_DEBUG */
- " with error " << ut_strerr(err) << ". You may need"
+ " with error " << err << ". You may need"
" to delete the ibdata1 file before trying to start"
" up again.";
} else {
@@ -1335,7 +1338,7 @@ srv_init_abort_low(
#ifdef UNIV_DEBUG
" at " << innobase_basename(file) << "[" << line << "]"
#endif /* UNIV_DEBUG */
- " with error " << ut_strerr(err);
+ " with error " << err;
}
srv_shutdown_all_bg_threads();
@@ -1471,8 +1474,7 @@ innobase_start_or_create_for_mysql()
unsigned i = 0;
ut_ad(srv_operation == SRV_OPERATION_NORMAL
- || srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_EXPORT);
+ || is_mariabackup_restore_or_export());
if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
srv_read_only_mode = true;
@@ -1950,14 +1952,9 @@ innobase_start_or_create_for_mysql()
srv_read_only_mode);
if (err == DB_NOT_FOUND) {
- if (i == 0) {
- if (srv_operation
- == SRV_OPERATION_RESTORE
- || srv_operation
- == SRV_OPERATION_RESTORE_EXPORT) {
- return(DB_SUCCESS);
- }
- }
+ if (i == 0
+ && is_mariabackup_restore_or_export())
+ return (DB_SUCCESS);
/* opened all files */
break;
@@ -1984,10 +1981,7 @@ innobase_start_or_create_for_mysql()
if (i == 0) {
if (size == 0
- && (srv_operation
- == SRV_OPERATION_RESTORE
- || srv_operation
- == SRV_OPERATION_RESTORE_EXPORT)) {
+ && is_mariabackup_restore_or_export()) {
/* Tolerate an empty ib_logfile0
from a previous run of
mariabackup --prepare. */
@@ -2217,6 +2211,7 @@ files_checked:
switch (srv_operation) {
case SRV_OPERATION_NORMAL:
+ case SRV_OPERATION_RESTORE_ROLLBACK_XA:
case SRV_OPERATION_RESTORE_EXPORT:
/* Initialize the change buffer. */
err = dict_boot();
@@ -2321,8 +2316,7 @@ files_checked:
recv_recovery_from_checkpoint_finish();
- if (srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_EXPORT) {
+ if (is_mariabackup_restore_or_export()) {
/* After applying the redo log from
SRV_OPERATION_BACKUP, flush the changes
to the data files and truncate or delete the log.
@@ -2337,8 +2331,7 @@ files_checked:
fil_close_log_files(true);
log_group_close_all();
if (err == DB_SUCCESS) {
- bool trunc = srv_operation
- == SRV_OPERATION_RESTORE;
+ bool trunc = is_mariabackup_restore();
/* Delete subsequent log files. */
delete_log_files(logfilename, dirnamelen,
srv_n_log_files_found, trunc);
@@ -2632,7 +2625,9 @@ files_checked:
srv_start_state_set(SRV_START_STATE_MASTER);
}
- if (!srv_read_only_mode && srv_operation == SRV_OPERATION_NORMAL
+ if (!srv_read_only_mode
+ && (srv_operation == SRV_OPERATION_NORMAL
+ || srv_operation == SRV_OPERATION_RESTORE_ROLLBACK_XA)
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
srv_undo_sources = true;
/* Create the dict stats gathering thread */
@@ -2763,6 +2758,7 @@ srv_shutdown_bg_undo_sources()
{
if (srv_undo_sources) {
ut_ad(!srv_read_only_mode);
+ srv_shutdown_state = SRV_SHUTDOWN_INITIATED;
fts_optimize_shutdown();
dict_stats_shutdown();
while (row_get_background_drop_list_len_low()) {
@@ -2783,6 +2779,11 @@ innodb_shutdown()
ut_ad(!srv_undo_sources);
switch (srv_operation) {
+ case SRV_OPERATION_RESTORE_ROLLBACK_XA:
+ if (dberr_t err = fil_write_flushed_lsn(log_sys->lsn))
+ ib::error() << "Writing flushed lsn " << log_sys->lsn
+ << " failed; error=" << err;
+ /* fall through */
case SRV_OPERATION_BACKUP:
case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_DELTA:
@@ -2848,7 +2849,7 @@ innodb_shutdown()
#ifdef BTR_CUR_HASH_ADAPT
if (dict_sys) {
- btr_search_disable(true);
+ btr_search_disable();
}
#endif /* BTR_CUR_HASH_ADAPT */
if (ibuf) {
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc
index 0c942ada430..27650cb1639 100644
--- a/storage/innobase/sync/sync0arr.cc
+++ b/storage/innobase/sync/sync0arr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -979,9 +979,9 @@ sync_array_print_long_waits_low(
return(false);
}
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind
/* Increase the timeouts if running under valgrind because it executes
- extremely slowly. UNIV_DEBUG_VALGRIND does not necessary mean that
+ extremely slowly. HAVE_valgrind does not necessary mean that
we are running under valgrind but we have no better way to tell.
See Bug#58432 innodb.innodb_bug56143 fails under valgrind
for an example */
@@ -1078,7 +1078,7 @@ sync_array_print_long_waits(
sync_array_exit(arr);
}
- if (noticed) {
+ if (noticed && srv_monitor_event) {
ibool old_val;
fprintf(stderr,
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index 3e65c234cd0..edcb886fe5c 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -383,8 +383,7 @@ private:
{
return(latch->get_id() == LATCH_ID_RTR_ACTIVE_MUTEX
|| latch->get_id() == LATCH_ID_RTR_PATH_MUTEX
- || latch->get_id() == LATCH_ID_RTR_MATCH_MUTEX
- || latch->get_id() == LATCH_ID_RTR_SSN_MUTEX);
+ || latch->get_id() == LATCH_ID_RTR_MATCH_MUTEX);
}
private:
@@ -465,7 +464,6 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(SYNC_WORK_QUEUE);
LEVEL_MAP_INSERT(SYNC_FTS_TOKENIZE);
LEVEL_MAP_INSERT(SYNC_FTS_OPTIMIZE);
- LEVEL_MAP_INSERT(SYNC_FTS_BG_THREADS);
LEVEL_MAP_INSERT(SYNC_FTS_CACHE_INIT);
LEVEL_MAP_INSERT(SYNC_RECV);
LEVEL_MAP_INSERT(SYNC_LOG_FLUSH_ORDER);
@@ -474,7 +472,6 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(SYNC_PAGE_CLEANER);
LEVEL_MAP_INSERT(SYNC_PURGE_QUEUE);
LEVEL_MAP_INSERT(SYNC_TRX_SYS_HEADER);
- LEVEL_MAP_INSERT(SYNC_REC_LOCK);
LEVEL_MAP_INSERT(SYNC_THREADS);
LEVEL_MAP_INSERT(SYNC_TRX);
LEVEL_MAP_INSERT(SYNC_TRX_SYS);
@@ -744,7 +741,6 @@ LatchDebug::check_order(
case SYNC_MONITOR_MUTEX:
case SYNC_RECV:
- case SYNC_FTS_BG_THREADS:
case SYNC_WORK_QUEUE:
case SYNC_FTS_TOKENIZE:
case SYNC_FTS_OPTIMIZE:
@@ -846,15 +842,6 @@ LatchDebug::check_order(
}
break;
- case SYNC_REC_LOCK:
-
- if (find(latches, SYNC_LOCK_SYS) != 0) {
- basic_check(latches, level, SYNC_REC_LOCK - 1);
- } else {
- basic_check(latches, level, SYNC_REC_LOCK);
- }
- break;
-
case SYNC_IBUF_BITMAP:
/* Either the thread must own the master mutex to all
@@ -1316,14 +1303,8 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(FLUSH_LIST, SYNC_BUF_FLUSH_LIST, flush_list_mutex_key);
- LATCH_ADD_MUTEX(FTS_BG_THREADS, SYNC_FTS_BG_THREADS,
- fts_bg_threads_mutex_key);
-
LATCH_ADD_MUTEX(FTS_DELETE, SYNC_FTS_OPTIMIZE, fts_delete_mutex_key);
- LATCH_ADD_MUTEX(FTS_OPTIMIZE, SYNC_FTS_OPTIMIZE,
- fts_optimize_mutex_key);
-
LATCH_ADD_MUTEX(FTS_DOC_ID, SYNC_FTS_OPTIMIZE, fts_doc_id_mutex_key);
LATCH_ADD_MUTEX(FTS_PLL_TOKENIZE, SYNC_FTS_TOKENIZE,
@@ -1375,8 +1356,6 @@ sync_latch_meta_init()
rw_lock_debug_mutex_key);
#endif /* UNIV_DEBUG */
- LATCH_ADD_MUTEX(RTR_SSN_MUTEX, SYNC_ANY_LATCH, rtr_ssn_mutex_key);
-
LATCH_ADD_MUTEX(RTR_ACTIVE_MUTEX, SYNC_ANY_LATCH,
rtr_active_mutex_key);
@@ -1514,8 +1493,6 @@ sync_latch_meta_init()
PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(MTFLUSH_MUTEX, SYNC_NO_ORDER_CHECK,
PFS_NOT_INSTRUMENTED);
- LATCH_ADD_MUTEX(FIL_CRYPT_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(FIL_CRYPT_STAT_MUTEX, SYNC_NO_ORDER_CHECK,
PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(FIL_CRYPT_DATA_MUTEX, SYNC_NO_ORDER_CHECK,
@@ -1580,7 +1557,7 @@ struct CreateTracker {
~CreateTracker()
UNIV_NOTHROW
{
- ut_d(m_files.empty());
+ ut_ad(m_files.empty());
m_mutex.destroy();
}
diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc
index 96108ab0bf1..b46126bde58 100644
--- a/storage/innobase/sync/sync0rw.cc
+++ b/storage/innobase/sync/sync0rw.cc
@@ -293,15 +293,15 @@ rw_lock_s_lock_spin(
ut_ad(rw_lock_validate(lock));
+ rw_lock_stats.rw_s_spin_wait_count.inc();
+
lock_loop:
/* Spin waiting for the writer field to become free */
HMT_low();
+ ulint j = i;
while (i < srv_n_spin_wait_rounds && lock->lock_word <= 0) {
- if (srv_spin_wait_delay) {
- ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
- }
-
+ ut_delay(srv_spin_wait_delay);
i++;
}
@@ -310,7 +310,7 @@ lock_loop:
os_thread_yield();
}
- ++spin_count;
+ spin_count += lint(i - j);
/* We try once again to obtain the lock */
if (rw_lock_s_lock_low(lock, pass, file_name, line)) {
@@ -420,13 +420,9 @@ rw_lock_x_lock_wait_func(
ut_ad(lock->lock_word <= threshold);
+ HMT_low();
while (lock->lock_word < threshold) {
-
-
- HMT_low();
- if (srv_spin_wait_delay) {
- ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
- }
+ ut_delay(srv_spin_wait_delay);
if (i < srv_n_spin_wait_rounds) {
i++;
@@ -435,7 +431,7 @@ rw_lock_x_lock_wait_func(
HMT_medium();
/* If there is still a reader, then go to sleep.*/
- ++n_spins;
+ n_spins += i;
sync_cell_t* cell;
@@ -661,6 +657,12 @@ rw_lock_x_lock_func(
ut_ad(rw_lock_validate(lock));
ut_ad(!rw_lock_own(lock, RW_LOCK_S));
+ if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
+ /* Locking succeeded */
+ return;
+ }
+ rw_lock_stats.rw_x_spin_wait_count.inc();
+
lock_loop:
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
@@ -680,19 +682,16 @@ lock_loop:
/* Spin waiting for the lock_word to become free */
HMT_low();
+ ulint j = i;
while (i < srv_n_spin_wait_rounds
&& lock->lock_word <= X_LOCK_HALF_DECR) {
- if (srv_spin_wait_delay) {
- ut_delay(ut_rnd_interval(
- 0, srv_spin_wait_delay));
- }
-
+ ut_delay(srv_spin_wait_delay);
i++;
}
HMT_medium();
- spin_count += i;
+ spin_count += lint(i - j);
if (i >= srv_n_spin_wait_rounds) {
@@ -760,11 +759,17 @@ rw_lock_sx_lock_func(
sync_array_t* sync_arr;
ulint spin_count = 0;
uint64_t count_os_wait = 0;
- ulint spin_wait_count = 0;
ut_ad(rw_lock_validate(lock));
ut_ad(!rw_lock_own(lock, RW_LOCK_S));
+ if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
+ /* Locking succeeded */
+ return;
+ }
+
+ rw_lock_stats.rw_sx_spin_wait_count.inc();
+
lock_loop:
if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
@@ -776,28 +781,22 @@ lock_loop:
}
rw_lock_stats.rw_sx_spin_round_count.add(spin_count);
- rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count);
/* Locking succeeded */
return;
} else {
- ++spin_wait_count;
-
/* Spin waiting for the lock_word to become free */
+ ulint j = i;
while (i < srv_n_spin_wait_rounds
&& lock->lock_word <= X_LOCK_HALF_DECR) {
- if (srv_spin_wait_delay) {
- ut_delay(ut_rnd_interval(
- 0, srv_spin_wait_delay));
- }
-
+ ut_delay(srv_spin_wait_delay);
i++;
}
- spin_count += i;
+ spin_count += lint(i - j);
if (i >= srv_n_spin_wait_rounds) {
@@ -829,7 +828,6 @@ lock_loop:
}
rw_lock_stats.rw_sx_spin_round_count.add(spin_count);
- rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count);
/* Locking succeeded */
return;
diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc
index 0a81f9c00e7..2e5558a3294 100644
--- a/storage/innobase/sync/sync0sync.cc
+++ b/storage/innobase/sync/sync0sync.cc
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -45,9 +46,7 @@ mysql_pfs_key_t dict_sys_mutex_key;
mysql_pfs_key_t file_format_max_mutex_key;
mysql_pfs_key_t fil_system_mutex_key;
mysql_pfs_key_t flush_list_mutex_key;
-mysql_pfs_key_t fts_bg_threads_mutex_key;
mysql_pfs_key_t fts_delete_mutex_key;
-mysql_pfs_key_t fts_optimize_mutex_key;
mysql_pfs_key_t fts_doc_id_mutex_key;
mysql_pfs_key_t fts_pll_tokenize_mutex_key;
mysql_pfs_key_t hash_table_mutex_key;
@@ -73,7 +72,6 @@ mysql_pfs_key_t rw_lock_debug_mutex_key;
mysql_pfs_key_t rtr_active_mutex_key;
mysql_pfs_key_t rtr_match_mutex_key;
mysql_pfs_key_t rtr_path_mutex_key;
-mysql_pfs_key_t rtr_ssn_mutex_key;
mysql_pfs_key_t rw_lock_list_mutex_key;
mysql_pfs_key_t rw_lock_mutex_key;
mysql_pfs_key_t srv_innodb_monitor_mutex_key;
diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc
index 6dba53dee6b..2b9d6c96acd 100644
--- a/storage/innobase/trx/trx0i_s.cc
+++ b/storage/innobase/trx/trx0i_s.cc
@@ -450,7 +450,6 @@ fill_trx_row(
which to copy volatile
strings */
{
- size_t stmt_len;
const char* s;
ut_ad(lock_mutex_own());
@@ -485,16 +484,14 @@ fill_trx_row(
row->trx_mysql_thread_id = thd_get_thread_id(trx->mysql_thd);
char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
- stmt_len = innobase_get_stmt_safe(trx->mysql_thd, query, sizeof(query));
-
- if (stmt_len > 0) {
-
+ if (size_t stmt_len = thd_query_safe(trx->mysql_thd, query,
+ sizeof query)) {
row->trx_query = static_cast<const char*>(
ha_storage_put_memlim(
cache->storage, query, stmt_len + 1,
MAX_ALLOWED_FOR_STORAGE(cache)));
- row->trx_query_cs = innobase_get_charset(trx->mysql_thd);
+ row->trx_query_cs = thd_charset(trx->mysql_thd);
if (row->trx_query == NULL) {
@@ -599,7 +596,7 @@ put_nth_field(
ulint n, /*!< in: number of field */
const dict_index_t* index, /*!< in: index */
const rec_t* rec, /*!< in: record */
- const ulint* offsets)/*!< in: record offsets, returned
+ const rec_offs* offsets)/*!< in: record offsets, returned
by rec_get_offsets() */
{
const byte* data;
@@ -680,8 +677,8 @@ fill_lock_data(
const dict_index_t* index;
ulint n_fields;
mem_heap_t* heap;
- ulint offsets_onstack[REC_OFFS_NORMAL_SIZE];
- ulint* offsets;
+ rec_offs offsets_onstack[REC_OFFS_NORMAL_SIZE];
+ rec_offs* offsets;
char buf[TRX_I_S_LOCK_DATA_MAX_LEN];
ulint buf_used;
ulint i;
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 732435ccefb..2025ac70beb 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -383,7 +383,7 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
}
if (fseg_free_step_not_header(
- seg_hdr + TRX_UNDO_FSEG_HEADER, false, &mtr)) {
+ seg_hdr + TRX_UNDO_FSEG_HEADER, &mtr)) {
break;
}
@@ -413,7 +413,7 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
is not flooded with bufferfixed pages: see the note in
fsp0fsp.cc. */
- } while (!fseg_free_step(seg_hdr + TRX_UNDO_FSEG_HEADER, false, &mtr));
+ } while (!fseg_free_step(seg_hdr + TRX_UNDO_FSEG_HEADER, &mtr));
hist_size = mtr_read_ulint(rseg_hdr + TRX_RSEG_HISTORY_SIZE,
MLOG_4BYTES, &mtr);
@@ -698,12 +698,11 @@ namespace undo {
os_file_close(handle);
- if (err != DB_SUCCESS) {
-
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
ib::info()
<< "Unable to read '"
<< log_file_name << "' : "
- << ut_strerr(err);
+ << err;
os_file_delete(
innodb_log_file_key, log_file_name);
@@ -996,7 +995,7 @@ trx_purge_initiate_truncate(
mtr_t mtr;
const ulint size = SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
mtr.start();
- mtr_x_lock(&space->latch, &mtr);
+ mtr.x_lock_space(space, __FILE__, __LINE__);
fil_truncate_log(space, size, &mtr);
fsp_header_init(space_id, size, &mtr);
mutex_enter(&fil_system->mutex);
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index e23f29fa735..623d8990381 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -848,7 +848,7 @@ trx_undo_page_report_modify(
delete marking is done */
const rec_t* rec, /*!< in: clustered index record which
has NOT yet been modified */
- const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec, index) */
const upd_t* update, /*!< in: update vector which tells the
columns to be updated; in the case of
a delete, this should be set to NULL */
@@ -1565,9 +1565,7 @@ trx_undo_update_rec_get_update(
<< " fields " << BUG_REPORT_MSG
<< ". Run also CHECK TABLE "
<< index->table->name << "."
- " n_fields = " << n_fields << ", i = " << i
- << ", ptr " << ptr;
-
+ " n_fields = " << n_fields << ", i = " << i;
ut_ad(0);
*upd = NULL;
return(NULL);
@@ -2017,7 +2015,7 @@ trx_undo_report_row_operation(
const rec_t* rec, /*!< in: case of an update or delete
marking, the record in the clustered
index; NULL if insert */
- const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ const rec_offs* offsets, /*!< in: rec_get_offsets(rec) */
roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
undo log record */
{
@@ -2292,7 +2290,7 @@ trx_undo_prev_version_build(
index_rec page and purge_view */
const rec_t* rec, /*!< in: version of a clustered index record */
dict_index_t* index, /*!< in: clustered index */
- ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ rec_offs* offsets,/*!< in/out: rec_get_offsets(rec, index) */
mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
rec_t** old_vers,/*!< out, own: previous version, or NULL if
@@ -2404,8 +2402,6 @@ trx_undo_prev_version_build(
ut_a(ptr);
if (row_upd_changes_field_size_or_external(index, offsets, update)) {
- ulint n_ext;
-
/* We should confirm the existence of disowned external data,
if the previous version record is delete marked. If the trx_id
of the previous record is seen by purge view, we should treat
@@ -2446,13 +2442,18 @@ trx_undo_prev_version_build(
those fields that update updates to become externally stored
fields. Store the info: */
- entry = row_rec_to_index_entry(
- rec, index, offsets, &n_ext, heap);
- n_ext += btr_push_update_extern_fields(entry, update, heap);
+ entry = row_rec_to_index_entry(rec, index, offsets, heap);
/* The page containing the clustered index record
corresponding to entry is latched in mtr. Thus the
following call is safe. */
- row_upd_index_replace_new_col_vals(entry, index, update, heap);
+ if (!row_upd_index_replace_new_col_vals(entry, *index, update,
+ heap)) {
+ ut_a(v_status & TRX_UNDO_PREV_IN_PURGE);
+ return false;
+ }
+
+ /* Get number of externally stored columns in updated record */
+ const ulint n_ext = dtuple_get_n_ext(entry);
buf = static_cast<byte*>(mem_heap_alloc(
heap, rec_get_converted_size(index, entry, n_ext)));
@@ -2476,8 +2477,10 @@ trx_undo_prev_version_build(
}
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+ rec_offs offsets_dbg[REC_OFFS_NORMAL_SIZE];
+ rec_offs_init(offsets_dbg);
ut_a(!rec_offs_any_null_extern(
- *old_vers, rec_get_offsets(*old_vers, index, NULL, true,
+ *old_vers, rec_get_offsets(*old_vers, index, offsets_dbg, true,
ULINT_UNDEFINED, &heap)));
#endif // defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 20798323802..c5f70452bf2 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -189,6 +189,9 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
case TRX_STATE_NOT_STARTED:
trx->will_lock = 0;
ut_ad(trx->in_mysql_trx_list);
+#ifdef WITH_WSREP
+ trx->wsrep = false;
+#endif
return(DB_SUCCESS);
case TRX_STATE_ACTIVE:
@@ -200,10 +203,21 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
case TRX_STATE_PREPARED_RECOVERED:
ut_ad(!trx_is_autocommit_non_locking(trx));
if (trx->has_logged_persistent()) {
- /* Change the undo log state back from
- TRX_UNDO_PREPARED to TRX_UNDO_ACTIVE
- so that if the system gets killed,
- recovery will perform the rollback. */
+ /* The XA ROLLBACK of a XA PREPARE transaction
+ will consist of multiple mini-transactions.
+
+ As the very first step of XA ROLLBACK, we must
+ change the undo log state back from
+ TRX_UNDO_PREPARED to TRX_UNDO_ACTIVE, in order
+ to ensure that recovery will complete the
+ rollback.
+
+ Failure to perform this step could cause a
+ situation where we would roll back part of
+ a XA PREPARE transaction, the server would be
+ killed, and finally, the transaction would be
+ recovered in XA PREPARE state, with some of
+ the actions already having been rolled back. */
trx_undo_ptr_t* undo_ptr = &trx->rsegs.m_redo;
mtr_t mtr;
mtr.start();
@@ -219,29 +233,15 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
true, &mtr);
}
mutex_exit(&trx->rsegs.m_redo.rseg->mutex);
- /* Persist the XA ROLLBACK, so that crash
- recovery will replay the rollback in case
- the redo log gets applied past this point. */
+ /* Write the redo log for the XA ROLLBACK
+ state change to the global buffer. It is
+ not necessary to flush the redo log. If
+ a durable log write of a later mini-transaction
+ takes place for whatever reason, then this state
+ change will be durable as well. */
mtr.commit();
ut_ad(mtr.commit_lsn() > 0);
}
-#ifdef ENABLED_DEBUG_SYNC
- if (trx->mysql_thd == NULL) {
- /* We could be executing XA ROLLBACK after
- XA PREPARE and a server restart. */
- } else if (!trx->has_logged_persistent()) {
- /* innobase_close_connection() may roll back a
- transaction that did not generate any
- persistent undo log. The DEBUG_SYNC
- would cause an assertion failure for a
- disconnected thread.
-
- NOTE: InnoDB will not know about the XID
- if no persistent undo log was generated. */
- } else {
- DEBUG_SYNC_C("trx_xa_rollback");
- }
-#endif /* ENABLED_DEBUG_SYNC */
return(trx_rollback_for_mysql_low(trx));
case TRX_STATE_COMMITTED_IN_MEMORY:
@@ -412,9 +412,8 @@ trx_rollback_to_savepoint_for_mysql_low(
trx->op_info = "";
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- trx->lock.was_chosen_as_deadlock_victim) {
- trx->lock.was_chosen_as_deadlock_victim = FALSE;
+ if (trx->is_wsrep()) {
+ trx->lock.was_chosen_as_deadlock_victim = false;
}
#endif
return(err);
@@ -553,19 +552,6 @@ trx_release_savepoint_for_mysql(
}
/*******************************************************************//**
-Determines if this transaction is rolling back an incomplete transaction
-in crash recovery.
-@return TRUE if trx is an incomplete transaction that is being rolled
-back in crash recovery */
-ibool
-trx_is_recv(
-/*========*/
- const trx_t* trx) /*!< in: transaction */
-{
- return(trx == trx_roll_crash_recv_trx);
-}
-
-/*******************************************************************//**
Returns a transaction savepoint taken at this point in time.
@return savepoint */
trx_savept_t
@@ -628,7 +614,7 @@ trx_rollback_active(
if (trx->error_state != DB_SUCCESS) {
ut_ad(trx->error_state == DB_INTERRUPTED);
- ut_ad(!srv_is_being_started);
+ ut_ad(srv_shutdown_state != SRV_SHUTDOWN_NONE);
ut_ad(!srv_undo_sources);
ut_ad(srv_fast_shutdown);
ut_ad(!dictionary_locked);
@@ -718,7 +704,7 @@ func_exit:
trx_free_resurrected(trx);
return(TRUE);
case TRX_STATE_ACTIVE:
- if (!srv_is_being_started
+ if (srv_shutdown_state != SRV_SHUTDOWN_NONE
&& !srv_undo_sources && srv_fast_shutdown) {
fake_prepared:
trx->state = TRX_STATE_PREPARED;
@@ -764,7 +750,7 @@ trx_roll_must_shutdown()
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE
- && !srv_is_being_started
+ && srv_shutdown_state != SRV_SHUTDOWN_NONE
&& !srv_undo_sources && srv_fast_shutdown) {
return true;
}
@@ -935,12 +921,6 @@ trx_roll_try_truncate(trx_t* trx)
trx_undo_truncate_end(undo, undo_no, true);
mutex_exit(&undo->rseg->mutex);
}
-
-#ifdef WITH_WSREP_OUT
- if (wsrep_on(trx->mysql_thd)) {
- trx->lock.was_chosen_as_deadlock_victim = FALSE;
- }
-#endif /* WITH_WSREP */
}
/***********************************************************************//**
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index e76695b7e43..ac946adc8b5 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -53,11 +53,11 @@ trx_rseg_header_create(
buf_block_t* block;
ut_ad(mtr);
- ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ ut_ad(mtr_memo_contains(mtr, fil_space_get(space),
+ MTR_MEMO_SPACE_X_LOCK));
/* Allocate a new file segment for the rollback segment */
- block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
+ block = fseg_create(space, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
if (block == NULL) {
/* No space left */
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 415afc4a90b..8d00bd824a2 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -422,7 +422,7 @@ trx_sysf_create(
mtr_x_lock_space(TRX_SYS_SPACE, mtr);
/* Create the trx sys file block in a new allocated file segment */
- block = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
+ block = fseg_create(TRX_SYS_SPACE, TRX_SYS + TRX_SYS_FSEG_HEADER,
mtr);
buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 7e72b909e2d..13b4efb973b 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -105,7 +105,7 @@ trx_init(
trx->op_info = "";
- trx->active_commit_ordered = 0;
+ trx->active_commit_ordered = false;
trx->isolation_level = TRX_ISO_REPEATABLE_READ;
@@ -202,6 +202,15 @@ struct TrxFactory {
@param trx the transaction for which to release resources */
static void destroy(trx_t* trx)
{
+#ifdef __SANITIZE_ADDRESS__
+ /* Unpoison the memory for AddressSanitizer */
+ MEM_UNDEFINED(trx, sizeof *trx);
+#else
+ /* Declare the contents as initialized for Valgrind;
+ we checked this in trx_t::free(). */
+ MEM_MAKE_DEFINED(trx, sizeof *trx);
+#endif
+
ut_a(trx->magic_n == TRX_MAGIC_N);
ut_ad(!trx->in_rw_trx_list);
ut_ad(!trx->in_mysql_trx_list);
@@ -229,39 +238,6 @@ struct TrxFactory {
trx->lock.table_locks.~lock_list();
}
-
- /** Enforce any invariants here, this is called before the transaction
- is added to the pool.
- @return true if all OK */
- static bool debug(const trx_t* trx)
- {
- ut_a(trx->error_state == DB_SUCCESS);
-
- ut_a(trx->magic_n == TRX_MAGIC_N);
-
- ut_ad(!trx->read_only);
-
- ut_ad(trx->state == TRX_STATE_NOT_STARTED);
-
- ut_ad(trx->dict_operation == TRX_DICT_OP_NONE);
-
- ut_ad(trx->mysql_thd == 0);
-
- ut_ad(!trx->in_rw_trx_list);
- ut_ad(!trx->in_mysql_trx_list);
-
- ut_a(trx->lock.wait_thr == NULL);
- ut_a(trx->lock.wait_lock == NULL);
- ut_a(trx->dict_operation_lock_mode == 0);
-
- ut_a(UT_LIST_GET_LEN(trx->lock.trx_locks) == 0);
-
- ut_ad(trx->autoinc_locks == NULL);
-
- ut_ad(trx->lock.table_locks.empty());
-
- return(true);
- }
};
/** The lock strategy for TrxPool */
@@ -338,13 +314,23 @@ trx_pool_close()
trx_pools = 0;
}
-/** @return a trx_t instance from trx_pools. */
-static
-trx_t*
-trx_create_low()
+/** @return allocated transaction object for internal operations */
+trx_t *trx_allocate_for_background()
{
trx_t* trx = trx_pools->get();
+#ifdef __SANITIZE_ADDRESS__
+ /* Unpoison the memory for AddressSanitizer.
+ It may have been poisoned in trx_t::free().*/
+ MEM_UNDEFINED(trx, sizeof *trx);
+#else
+ /* Declare the memory initialized for Valgrind.
+ The trx_t that are released to the pool are
+ actually initialized; we checked that by
+ MEM_CHECK_DEFINED() in trx_t::free(). */
+ MEM_MAKE_DEFINED(trx, sizeof *trx);
+#endif
+
assert_trx_is_free(trx);
mem_heap_t* heap;
@@ -360,14 +346,9 @@ trx_create_low()
alloc = ib_heap_allocator_create(heap);
- /* Remember to free the vector explicitly in trx_free(). */
trx->autoinc_locks = ib_vector_create(alloc, sizeof(void**), 4);
- /* Should have been either just initialized or .clear()ed by
- trx_free(). */
ut_ad(trx->mod_tables.empty());
- ut_ad(trx->lock.table_locks.empty());
- ut_ad(UT_LIST_GET_LEN(trx->lock.trx_locks) == 0);
ut_ad(trx->lock.n_rec_locks == 0);
ut_ad(trx->lock.table_cached == 0);
ut_ad(trx->lock.rec_cached == 0);
@@ -379,59 +360,119 @@ trx_create_low()
return(trx);
}
-/**
-Release a trx_t instance back to the pool.
-@param trx the instance to release. */
-static
-void
-trx_free(trx_t*& trx)
+/** Free the memory to trx_pools */
+inline void trx_t::free()
{
- assert_trx_is_free(trx);
-
- trx->mysql_thd = 0;
- trx->mysql_log_file_name = 0;
-
- // FIXME: We need to avoid this heap free/alloc for each commit.
- if (trx->autoinc_locks != NULL) {
- ut_ad(ib_vector_is_empty(trx->autoinc_locks));
- /* We allocated a dedicated heap for the vector. */
- ib_vector_free(trx->autoinc_locks);
- trx->autoinc_locks = NULL;
- }
+ assert_trx_is_inactive(this);
- trx->mod_tables.clear();
-
- ut_ad(trx->read_view == NULL);
+ MEM_CHECK_DEFINED(this, sizeof *this);
- /* trx locking state should have been reset before returning trx
- to pool */
- ut_ad(trx->will_lock == 0);
+ ut_ad(!read_view);
+ ut_ad(!will_lock);
+ ut_ad(error_state == DB_SUCCESS);
+ ut_ad(magic_n == TRX_MAGIC_N);
+ ut_ad(!read_only);
+ ut_ad(!in_mysql_trx_list);
+ ut_ad(!lock.wait_lock);
- trx_pools->mem_free(trx);
- /* Unpoison the memory for innodb_monitor_set_option;
- it is operating also on the freed transaction objects. */
- MEM_UNDEFINED(&trx->mutex, sizeof trx->mutex);
- MEM_UNDEFINED(&trx->undo_mutex, sizeof trx->undo_mutex);
- /* Declare the contents as initialized for Valgrind;
- we checked that it was initialized in trx_pools->mem_free(trx). */
- UNIV_MEM_VALID(&trx->mutex, sizeof trx->mutex);
- UNIV_MEM_VALID(&trx->undo_mutex, sizeof trx->undo_mutex);
-
- trx = NULL;
-}
+ mysql_thd= NULL;
+ mysql_log_file_name= NULL;
-/********************************************************************//**
-Creates a transaction object for background operations by the master thread.
-@return own: transaction object */
-trx_t*
-trx_allocate_for_background(void)
-/*=============================*/
-{
- trx_t* trx;
+ // FIXME: We need to avoid this heap free/alloc for each commit.
+ if (autoinc_locks)
+ {
+ ut_ad(ib_vector_is_empty(autoinc_locks));
+ /* We allocated a dedicated heap for the vector. */
+ ib_vector_free(autoinc_locks);
+ autoinc_locks= NULL;
+ }
- trx = trx_create_low();
+ mod_tables.clear();
- return(trx);
+ MEM_NOACCESS(&n_ref, sizeof n_ref);
+ /* do not poison mutex */
+ MEM_NOACCESS(&id, sizeof id);
+ MEM_NOACCESS(&no, sizeof no);
+ /* state is accessed by innobase_kill_connection() */
+ MEM_NOACCESS(&is_recovered, sizeof is_recovered);
+#ifdef WITH_WSREP
+ MEM_NOACCESS(&wsrep, sizeof wsrep);
+#endif
+ MEM_NOACCESS(&read_view, sizeof read_view);
+ MEM_NOACCESS(&trx_list, sizeof trx_list);
+ MEM_NOACCESS(&no_list, sizeof no_list);
+ MEM_NOACCESS(&lock, sizeof lock);
+ MEM_NOACCESS(&op_info, sizeof op_info);
+ MEM_NOACCESS(&isolation_level, sizeof isolation_level);
+ MEM_NOACCESS(&check_foreigns, sizeof check_foreigns);
+ MEM_NOACCESS(&is_registered, sizeof is_registered);
+ MEM_NOACCESS(&active_commit_ordered, sizeof active_commit_ordered);
+ MEM_NOACCESS(&check_unique_secondary, sizeof check_unique_secondary);
+ MEM_NOACCESS(&flush_log_later, sizeof flush_log_later);
+ MEM_NOACCESS(&must_flush_log_later, sizeof must_flush_log_later);
+ MEM_NOACCESS(&duplicates, sizeof duplicates);
+ MEM_NOACCESS(&dict_operation, sizeof dict_operation);
+ MEM_NOACCESS(&declared_to_be_inside_innodb, sizeof declared_to_be_inside_innodb);
+ MEM_NOACCESS(&n_tickets_to_enter_innodb, sizeof n_tickets_to_enter_innodb);
+ MEM_NOACCESS(&dict_operation_lock_mode, sizeof dict_operation_lock_mode);
+ MEM_NOACCESS(&start_time, sizeof start_time);
+ MEM_NOACCESS(&start_time_micro, sizeof start_time_micro);
+ MEM_NOACCESS(&commit_lsn, sizeof commit_lsn);
+ MEM_NOACCESS(&table_id, sizeof table_id);
+ /* mysql_thd is accessed by innobase_kill_connection() */
+ MEM_NOACCESS(&mysql_log_file_name, sizeof mysql_log_file_name);
+ MEM_NOACCESS(&mysql_log_offset, sizeof mysql_log_offset);
+ MEM_NOACCESS(&n_mysql_tables_in_use, sizeof n_mysql_tables_in_use);
+ MEM_NOACCESS(&mysql_n_tables_locked, sizeof mysql_n_tables_locked);
+#ifdef UNIV_DEBUG
+ MEM_NOACCESS(&in_rw_trx_list, sizeof in_rw_trx_list);
+#endif /* UNIV_DEBUG */
+ MEM_NOACCESS(&mysql_trx_list, sizeof mysql_trx_list);
+#ifdef UNIV_DEBUG
+ MEM_NOACCESS(&in_mysql_trx_list, sizeof in_mysql_trx_list);
+#endif /* UNIV_DEBUG */
+ MEM_NOACCESS(&error_state, sizeof error_state);
+ MEM_NOACCESS(&error_info, sizeof error_info);
+ MEM_NOACCESS(&error_key_num, sizeof error_key_num);
+ MEM_NOACCESS(&graph, sizeof graph);
+ MEM_NOACCESS(&trx_savepoints, sizeof trx_savepoints);
+ /* do not poison undo_mutex */
+ MEM_NOACCESS(&undo_no, sizeof undo_no);
+ MEM_NOACCESS(&undo_rseg_space, sizeof undo_rseg_space);
+ MEM_NOACCESS(&last_sql_stat_start, sizeof last_sql_stat_start);
+ MEM_NOACCESS(&rsegs, sizeof rsegs);
+ MEM_NOACCESS(&roll_limit, sizeof roll_limit);
+#ifdef UNIV_DEBUG
+ MEM_NOACCESS(&in_rollback, sizeof in_rollback);
+#endif /* UNIV_DEBUG */
+ MEM_NOACCESS(&pages_undone, sizeof pages_undone);
+ MEM_NOACCESS(&n_autoinc_rows, sizeof n_autoinc_rows);
+ MEM_NOACCESS(&autoinc_locks, sizeof autoinc_locks);
+ MEM_NOACCESS(&read_only, sizeof read_only);
+ MEM_NOACCESS(&auto_commit, sizeof auto_commit);
+ MEM_NOACCESS(&will_lock, sizeof will_lock);
+ MEM_NOACCESS(&fts_trx, sizeof fts_trx);
+ MEM_NOACCESS(&fts_next_doc_id, sizeof fts_next_doc_id);
+ MEM_NOACCESS(&flush_tables, sizeof flush_tables);
+ MEM_NOACCESS(&ddl, sizeof ddl);
+ MEM_NOACCESS(&internal, sizeof internal);
+#ifdef UNIV_DEBUG
+ MEM_NOACCESS(&start_line, sizeof start_line);
+ MEM_NOACCESS(&start_file, sizeof start_file);
+#endif /* UNIV_DEBUG */
+ MEM_NOACCESS(&xid, sizeof xid);
+ MEM_NOACCESS(&mod_tables, sizeof mod_tables);
+ MEM_NOACCESS(&detailed_error, sizeof detailed_error);
+ MEM_NOACCESS(&flush_observer, sizeof flush_observer);
+ MEM_NOACCESS(&n_rec_lock_waits, sizeof n_rec_lock_waits);
+ MEM_NOACCESS(&n_table_lock_waits, sizeof n_table_lock_waits);
+ MEM_NOACCESS(&total_rec_lock_wait_time, sizeof total_rec_lock_wait_time);
+ MEM_NOACCESS(&total_table_lock_wait_time, sizeof total_table_lock_wait_time);
+#ifdef WITH_WSREP
+ MEM_NOACCESS(&wsrep_event, sizeof wsrep_event);
+#endif /* WITH_WSREP */
+ MEM_NOACCESS(&magic_n, sizeof magic_n);
+ trx_pools->mem_free(this);
}
/********************************************************************//**
@@ -466,9 +507,8 @@ trx_validate_state_before_free(trx_t* trx)
ut_ad(!trx->mysql_n_tables_locked);
ut_ad(!trx->internal);
- if (trx->declared_to_be_inside_innodb) {
-
- ib::error() << "Freeing a trx (" << trx << ", "
+ if (UNIV_UNLIKELY(trx->declared_to_be_inside_innodb)) {
+ ib::error() << "Freeing a trx ("
<< trx_get_id_for_print(trx) << ") which is declared"
" to be processing inside InnoDB";
@@ -506,8 +546,7 @@ trx_free_resurrected(trx_t* trx)
trx_validate_state_before_free(trx);
trx_init(trx);
-
- trx_free(trx);
+ trx->free();
}
/** Free a transaction that was allocated by background or user threads.
@@ -516,8 +555,7 @@ void
trx_free_for_background(trx_t* trx)
{
trx_validate_state_before_free(trx);
-
- trx_free(trx);
+ trx->free();
}
/** Transition to committed state, to release implicit locks. */
@@ -584,9 +622,7 @@ trx_free_prepared(
|| (trx->is_recovered
&& (trx_state_eq(trx, TRX_STATE_ACTIVE)
|| trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY))
- && (!srv_was_started
- || srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_EXPORT
+ && (!srv_was_started || is_mariabackup_restore_or_export()
|| srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)));
ut_a(trx->magic_n == TRX_MAGIC_N);
@@ -608,8 +644,7 @@ trx_free_prepared(
trx->state = TRX_STATE_NOT_STARTED;
ut_ad(!UT_LIST_GET_LEN(trx->lock.trx_locks));
trx->id = 0;
-
- trx_free(trx);
+ trx->free();
}
/** Disconnect a transaction from MySQL and optionally mark it as if
@@ -1816,15 +1851,13 @@ trx_commit_in_memory(
trx_mutex_enter(trx);
trx->dict_operation = TRX_DICT_OP_NONE;
-
-#ifdef WITH_WSREP
- if (trx->mysql_thd && wsrep_on(trx->mysql_thd)) {
- trx->lock.was_chosen_as_deadlock_victim = FALSE;
- }
-#endif
+ trx->lock.was_chosen_as_deadlock_victim = false;
DBUG_LOG("trx", "Commit in memory: " << trx);
trx->state = TRX_STATE_NOT_STARTED;
+#ifdef WITH_WSREP
+ trx->wsrep = false;
+#endif
/* trx->in_mysql_trx_list would hold between
trx_allocate_for_mysql() and trx_free_for_mysql(). It does not
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 336506c7b65..5d4fcdcf53f 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -446,9 +446,9 @@ trx_undo_seg_create(
}
/* Allocate a new file segment for the undo log */
- block = fseg_create_general(space, 0,
+ block = fseg_create_general(space,
TRX_UNDO_SEG_HDR
- + TRX_UNDO_FSEG_HEADER, TRUE, mtr);
+ + TRX_UNDO_FSEG_HEADER, TRUE, mtr, NULL);
fil_space_release_free_extents(space, n_reserved);
@@ -869,7 +869,7 @@ trx_undo_free_page(
undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, mtr);
fseg_free_page(header_page + TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER,
- space, page_no, false, mtr);
+ space, page_no, mtr);
last_addr = flst_get_last(header_page + TRX_UNDO_SEG_HDR
+ TRX_UNDO_PAGE_LIST, mtr);
@@ -1092,7 +1092,7 @@ trx_undo_seg_free(
file_seg = seg_header + TRX_UNDO_FSEG_HEADER;
- finished = fseg_free_step(file_seg, false, &mtr);
+ finished = fseg_free_step(file_seg, &mtr);
if (finished) {
/* Update the rseg header */
diff --git a/storage/innobase/ut/ut0crc32.cc b/storage/innobase/ut/ut0crc32.cc
index 44b1c4b30b4..5c62309ee89 100644
--- a/storage/innobase/ut/ut0crc32.cc
+++ b/storage/innobase/ut/ut0crc32.cc
@@ -84,6 +84,7 @@ mysys/my_perf.c, contributed by Facebook under the following license.
#include <string.h>
#include "ut0crc32.h"
+#include "my_valgrind.h"
#ifdef _MSC_VER
#include <intrin.h>
@@ -200,15 +201,17 @@ ut_crc32_8_hw(
const byte** data,
ulint* len)
{
-#ifdef _MSC_VER
+# ifdef _MSC_VER
*crc = _mm_crc32_u8(*crc, (*data)[0]);
-#else
+# elif __has_feature(memory_sanitizer)
+ *crc = __builtin_ia32_crc32qi(*crc, (*data)[0]);
+# else
asm("crc32b %1, %0"
/* output operands */
: "+r" (*crc)
/* input operands */
: "rm" ((*data)[0]));
-#endif
+# endif
(*data)++;
(*len)--;
@@ -225,22 +228,24 @@ ut_crc32_64_low_hw(
uint64_t data)
{
uint64_t crc_64bit = crc;
-#ifdef _MSC_VER
-#ifdef _M_X64
+# ifdef _MSC_VER
+# ifdef _M_X64
crc_64bit = _mm_crc32_u64(crc_64bit, data);
-#elif defined(_M_IX86)
+# elif defined(_M_IX86)
crc = _mm_crc32_u32(crc, static_cast<uint32_t>(data));
crc_64bit = _mm_crc32_u32(crc, static_cast<uint32_t>(data >> 32));
-#else
-#error Not Supported processors type.
-#endif
-#else
+# else
+# error Not Supported processors type.
+# endif
+# elif __has_feature(memory_sanitizer)
+ crc_64bit = __builtin_ia32_crc32di(crc_64bit, data);
+# else
asm("crc32q %1, %0"
/* output operands */
: "+r" (crc_64bit)
/* input operands */
: "rm" (data));
-#endif
+# endif
return(static_cast<uint32_t>(crc_64bit));
}
diff --git a/storage/innobase/ut/ut0rnd.cc b/storage/innobase/ut/ut0rnd.cc
index 3c1e51536a1..8265121ef2e 100644
--- a/storage/innobase/ut/ut0rnd.cc
+++ b/storage/innobase/ut/ut0rnd.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,6 +26,9 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0rnd.h"
+/** Seed value of ut_rnd_gen() */
+int32 ut_rnd_current;
+
/** These random numbers are used in ut_find_prime */
/*@{*/
#define UT_RANDOM_1 1.0412321
@@ -32,9 +36,6 @@ Created 5/11/1994 Heikki Tuuri
#define UT_RANDOM_3 1.0132677
/*@}*/
-/** Seed value of ut_rnd_gen_ulint(). */
-ulint ut_rnd_ulint_counter = 65654363;
-
/***********************************************************//**
Looks for a prime number slightly greater than the given argument.
The prime is chosen so that it is not near any power of 2.
diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc
index 252f3a50ae1..1b3d100f9ee 100644
--- a/storage/innobase/ut/ut0ut.cc
+++ b/storage/innobase/ut/ut0ut.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -168,8 +168,6 @@ ut_print_buf(
const byte* data;
ulint i;
- UNIV_MEM_ASSERT_RW(buf, len);
-
fprintf(file, " len " ULINTPF "; hex ", len);
for (data = (const byte*) buf, i = 0; i < len; i++) {
@@ -204,8 +202,6 @@ ut_print_buf_hex(
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
- UNIV_MEM_ASSERT_RW(buf, len);
-
o << "(0x";
for (data = static_cast<const byte*>(buf), i = 0; i < len; i++) {
@@ -228,8 +224,6 @@ ut_print_buf(
const byte* data;
ulint i;
- UNIV_MEM_ASSERT_RW(buf, len);
-
for (data = static_cast<const byte*>(buf), i = 0; i < len; i++) {
int c = static_cast<int>(*data++);
o << (isprint(c) ? static_cast<char>(c) : ' ');
@@ -614,6 +608,12 @@ ut_basename_noext(
namespace ib {
+ATTRIBUTE_COLD logger& logger::operator<<(dberr_t err)
+{
+ m_oss << ut_strerr(err);
+ return *this;
+}
+
info::~info()
{
sql_print_information("InnoDB: %s", m_oss.str().c_str());
@@ -624,9 +624,13 @@ warn::~warn()
sql_print_warning("InnoDB: %s", m_oss.str().c_str());
}
+/** true if error::~error() was invoked, false otherwise */
+bool error::logged;
+
error::~error()
{
sql_print_error("InnoDB: %s", m_oss.str().c_str());
+ logged = true;
}
#ifdef _MSC_VER
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index e82c76fd938..f1cabfd2039 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -296,7 +296,7 @@ static MYSQL_SYSVAR_BOOL(encrypt_tables, maria_encrypt_tables, PLUGIN_VAR_OPCMDA
"and not FIXED/DYNAMIC)",
0, 0, 0);
-#ifdef HAVE_PSI_INTERFACE
+#if defined HAVE_PSI_INTERFACE && !defined EMBEDDED_LIBRARY
static PSI_mutex_info all_aria_mutexes[]=
{
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index ad6d085b12a..ef529a4be3d 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -1288,6 +1288,7 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
uint byte= 6 * (last_insert_page / 16);
first_pattern= last_insert_page % 16;
data= bitmap->map+byte;
+ first_found= 0; /* Don't update full_head_size */
DBUG_ASSERT(data <= end);
}
else
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index c6858ff63b8..2795528a044 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -3199,6 +3199,7 @@ static int write_page(MARIA_SHARE *share, File file,
args.page= buff;
args.pageno= (pgcache_page_no_t) (pos / share->block_size);
args.data= (uchar*) share;
+ args.crypt_buf= NULL;
(* share->kfile.pre_write_hook)(&args);
res= my_pwrite(file, args.page, block_size, pos, myf_rw);
(* share->kfile.post_write_hook)(res, &args);
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index 03501dc49cf..7d4271c794c 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -20,7 +20,7 @@
to open other files during the time we flush the cache and close this file
*/
-#include "maria_def.h"
+#include "ma_ftdefs.h"
#include "ma_crypt.h"
int maria_close(register MARIA_HA *info)
@@ -86,6 +86,7 @@ int maria_close(register MARIA_HA *info)
share->open_list= list_delete(share->open_list, &info->share_list);
}
+ maria_ftparser_call_deinitializer(info);
my_free(info->rec_buff);
(*share->end)(info);
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 2c9c15d8a2a..dc041b79f06 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -75,7 +75,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
uint max_field_lengths, extra_header_size, column_nr;
uint internal_table= flags & HA_CREATE_INTERNAL_TABLE;
ulong reclength, real_reclength,min_pack_length;
- char kfilename[FN_REFLEN], klinkname[FN_REFLEN], *klinkname_ptr;
+ char kfilename[FN_REFLEN], klinkname[FN_REFLEN], *klinkname_ptr= NullS;
char dfilename[FN_REFLEN], dlinkname[FN_REFLEN], *dlinkname_ptr= 0;
ulong pack_reclength;
ulonglong tot_length,max_rows, tmp;
@@ -318,7 +318,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
{
options|= HA_OPTION_TMP_TABLE;
tmp_table= TRUE;
- create_mode|= O_NOFOLLOW;
+ create_mode|= O_NOFOLLOW | (internal_table ? 0 : O_EXCL);
/* "CREATE TEMPORARY" tables are not crash-safe (dropped at restart) */
ci->transactional= FALSE;
flags&= ~HA_CREATE_PAGE_CHECKSUM;
@@ -886,10 +886,9 @@ int maria_create(const char *name, enum data_file_type datafile_type,
{
char *iext= strrchr(name, '.');
int have_iext= iext && !strcmp(iext, MARIA_NAME_IEXT);
- fn_format(kfilename, name, "", MARIA_NAME_IEXT,
- MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
+ fn_format(kfilename, name, "", MARIA_NAME_IEXT, MY_UNPACK_FILENAME |
+ (internal_table ? 0 : MY_RETURN_REAL_PATH) |
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
- klinkname_ptr= NullS;
/*
Replace the current file.
Don't sync dir now if the data file has the same path.
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 1d5bfba182d..b98fbe29e1f 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -1,4 +1,5 @@
/* Copyright (C) 2007 MySQL AB & Sanja Belkin. 2010 Monty Program Ab.
+ Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3613,7 +3614,8 @@ my_bool translog_init_with_table(const char *directory,
int old_log_was_recovered= 0, logs_found= 0;
uint old_flags= flags;
uint32 start_file_num= 1;
- TRANSLOG_ADDRESS sure_page, last_page, last_valid_page, checkpoint_lsn;
+ TRANSLOG_ADDRESS UNINIT_VAR(sure_page), last_page, last_valid_page,
+ checkpoint_lsn;
my_bool version_changed= 0;
DBUG_ENTER("translog_init_with_table");
@@ -5440,15 +5442,15 @@ static uchar *translog_get_LSN_from_diff(LSN base_lsn, uchar *src, uchar *dst)
src + 1 + LSN_STORE_SIZE));
DBUG_RETURN(src + 1 + LSN_STORE_SIZE);
}
- rec_offset= LSN_OFFSET(base_lsn) - ((first_byte << 8) + *((uint8*)src));
+ rec_offset= LSN_OFFSET(base_lsn) - ((first_byte << 8) | *((uint8*)src));
break;
case 1:
diff= uint2korr(src);
- rec_offset= LSN_OFFSET(base_lsn) - ((first_byte << 16) + diff);
+ rec_offset= LSN_OFFSET(base_lsn) - ((first_byte << 16) | diff);
break;
case 2:
diff= uint3korr(src);
- rec_offset= LSN_OFFSET(base_lsn) - ((first_byte << 24) + diff);
+ rec_offset= LSN_OFFSET(base_lsn) - ((first_byte << 24) | diff);
break;
case 3:
{
diff --git a/storage/maria/ma_packrec.c b/storage/maria/ma_packrec.c
index e2c1e353616..eab079f4fb8 100644
--- a/storage/maria/ma_packrec.c
+++ b/storage/maria/ma_packrec.c
@@ -1,4 +1,5 @@
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1157,10 +1158,10 @@ static void decode_bytes(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
bit_buff->error=1;
return; /* Can't be right */
}
- bit_buff->current_byte= (bit_buff->current_byte << 32) +
- ((((uint) bit_buff->pos[3])) +
- (((uint) bit_buff->pos[2]) << 8) +
- (((uint) bit_buff->pos[1]) << 16) +
+ bit_buff->current_byte= (bit_buff->current_byte << 32) |
+ ((((uint) bit_buff->pos[3])) |
+ (((uint) bit_buff->pos[2]) << 8) |
+ (((uint) bit_buff->pos[1]) << 16) |
(((uint) bit_buff->pos[0]) << 24));
bit_buff->pos+=4;
bits+=32;
@@ -1251,23 +1252,23 @@ static void decode_bytes(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
return; /* Can't be right */
}
#if BITS_SAVED == 32
- bit_buff->current_byte= (bit_buff->current_byte << 24) +
- (((uint) ((uchar) bit_buff->pos[2]))) +
- (((uint) ((uchar) bit_buff->pos[1])) << 8) +
+ bit_buff->current_byte= (bit_buff->current_byte << 24) |
+ (((uint) ((uchar) bit_buff->pos[2]))) |
+ (((uint) ((uchar) bit_buff->pos[1])) << 8) |
(((uint) ((uchar) bit_buff->pos[0])) << 16);
bit_buff->pos+=3;
bits+=24;
#else
if (bits) /* We must have at leasts 9 bits */
{
- bit_buff->current_byte= (bit_buff->current_byte << 8) +
+ bit_buff->current_byte= (bit_buff->current_byte << 8) |
(uint) ((uchar) bit_buff->pos[0]);
bit_buff->pos++;
bits+=8;
}
else
{
- bit_buff->current_byte= ((uint) ((uchar) bit_buff->pos[0]) << 8) +
+ bit_buff->current_byte= ((uint) ((uchar) bit_buff->pos[0]) << 8) |
((uint) ((uchar) bit_buff->pos[1]));
bit_buff->pos+=2;
bits+=16;
@@ -1291,14 +1292,14 @@ static void decode_bytes(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
if (bits < 8)
{ /* We don't need to check end */
#if BITS_SAVED == 32
- bit_buff->current_byte= (bit_buff->current_byte << 24) +
- (((uint) ((uchar) bit_buff->pos[2]))) +
- (((uint) ((uchar) bit_buff->pos[1])) << 8) +
+ bit_buff->current_byte= (bit_buff->current_byte << 24) |
+ (((uint) ((uchar) bit_buff->pos[2]))) |
+ (((uint) ((uchar) bit_buff->pos[1])) << 8) |
(((uint) ((uchar) bit_buff->pos[0])) << 16);
bit_buff->pos+=3;
bits+=24;
#else
- bit_buff->current_byte= (bit_buff->current_byte << 8) +
+ bit_buff->current_byte= (bit_buff->current_byte << 8) |
(uint) ((uchar) bit_buff->pos[0]);
bit_buff->pos+=1;
bits+=8;
@@ -1488,25 +1489,25 @@ static void fill_buffer(MARIA_BIT_BUFF *bit_buff)
return;
}
#if BITS_SAVED == 64
- bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) +
- (((uint) ((uchar) bit_buff->pos[6])) << 8) +
- (((uint) ((uchar) bit_buff->pos[5])) << 16) +
- (((uint) ((uchar) bit_buff->pos[4])) << 24) +
+ bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) |
+ (((uint) ((uchar) bit_buff->pos[6])) << 8) |
+ (((uint) ((uchar) bit_buff->pos[5])) << 16) |
+ (((uint) ((uchar) bit_buff->pos[4])) << 24) |
((ulonglong)
- ((((uint) ((uchar) bit_buff->pos[3]))) +
- (((uint) ((uchar) bit_buff->pos[2])) << 8) +
- (((uint) ((uchar) bit_buff->pos[1])) << 16) +
+ ((((uint) ((uchar) bit_buff->pos[3]))) |
+ (((uint) ((uchar) bit_buff->pos[2])) << 8) |
+ (((uint) ((uchar) bit_buff->pos[1])) << 16) |
(((uint) ((uchar) bit_buff->pos[0])) << 24)) << 32));
bit_buff->pos+=8;
#else
#if BITS_SAVED == 32
- bit_buff->current_byte= (((uint) ((uchar) bit_buff->pos[3])) +
- (((uint) ((uchar) bit_buff->pos[2])) << 8) +
- (((uint) ((uchar) bit_buff->pos[1])) << 16) +
+ bit_buff->current_byte= (((uint) ((uchar) bit_buff->pos[3])) |
+ (((uint) ((uchar) bit_buff->pos[2])) << 8) |
+ (((uint) ((uchar) bit_buff->pos[1])) << 16) |
(((uint) ((uchar) bit_buff->pos[0])) << 24));
bit_buff->pos+=4;
#else
- bit_buff->current_byte= (uint) (((uint) ((uchar) bit_buff->pos[1]))+
+ bit_buff->current_byte= (uint) (((uint) ((uchar) bit_buff->pos[1])) |
(((uint) ((uchar) bit_buff->pos[0])) << 8));
bit_buff->pos+=2;
#endif
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index 9cd68a208b9..e55c5288d1d 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -1,4 +1,5 @@
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -112,7 +113,7 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
if (lock != PAGECACHE_LOCK_LEFT_UNLOCKED)
{
- DBUG_ASSERT(lock == PAGECACHE_LOCK_WRITE || PAGECACHE_LOCK_READ);
+ DBUG_ASSERT(lock == PAGECACHE_LOCK_WRITE || lock == PAGECACHE_LOCK_READ);
page_link.unlock= (lock == PAGECACHE_LOCK_WRITE ?
PAGECACHE_LOCK_WRITE_UNLOCK :
PAGECACHE_LOCK_READ_UNLOCK);
diff --git a/storage/maria/ma_pagecrc.c b/storage/maria/ma_pagecrc.c
index b0c02e60929..4d73ced3b11 100644
--- a/storage/maria/ma_pagecrc.c
+++ b/storage/maria/ma_pagecrc.c
@@ -251,7 +251,8 @@ my_bool maria_page_crc_check_index(int res, PAGECACHE_IO_HOOK_ARGS *args)
if (length > share->block_size - CRC_SIZE)
{
DBUG_PRINT("error", ("Wrong page length: %u", length));
- return (my_errno= HA_ERR_WRONG_CRC);
+ my_errno= HA_ERR_WRONG_CRC;
+ return 1;
}
return maria_page_crc_check(page, (uint32) page_no, share,
MARIA_NO_CRC_NORMAL_PAGE,
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index c8031030361..96b678b8695 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -949,6 +949,7 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE)
char *old_name, *new_name;
int error= 1;
MARIA_HA *info= NULL;
+ my_bool from_table_is_crashed= 0;
DBUG_ENTER("exec_REDO_LOGREC_REDO_RENAME_TABLE");
if (skip_DDLs)
@@ -1018,15 +1019,15 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE)
}
if (maria_is_crashed(info))
{
- tprint(tracef, ", is crashed, can't rename it");
- ALERT_USER();
- goto end;
+ tprint(tracef, "is crashed, can't be used for rename ; new-name table ");
+ from_table_is_crashed= 1;
}
if (close_one_table(info->s->open_file_name.str, rec->lsn) ||
maria_close(info))
goto end;
info= NULL;
- tprint(tracef, ", is ok for renaming; new-name table ");
+ if (!from_table_is_crashed)
+ tprint(tracef, "is ok for renaming; new-name table ");
}
else /* one or two files absent, or header corrupted... */
{
@@ -1091,11 +1092,19 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE)
goto end;
info= NULL;
/* abnormal situation */
- tprint(tracef, ", exists but is older than record, can't rename it");
+ tprint(tracef, "exists but is older than record, can't rename it");
goto end;
}
else /* one or two files absent, or header corrupted... */
- tprint(tracef, ", can't be opened, probably does not exist");
+ tprint(tracef, "can't be opened, probably does not exist");
+
+ if (from_table_is_crashed)
+ {
+ eprint(tracef, "Aborting rename as old table was crashed");
+ ALERT_USER();
+ goto end;
+ }
+
tprint(tracef, ", renaming '%s'", old_name);
if (maria_rename(old_name, new_name))
{
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 126554fffdb..826ff40baaf 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -335,12 +335,6 @@ err:
my_errno == HA_ERR_NULL_IN_SPATIAL ||
my_errno == HA_ERR_OUT_OF_MEM)
{
- if (info->bulk_insert)
- {
- uint j;
- for (j=0 ; j < share->base.keys ; j++)
- maria_flush_bulk_insert(info, j);
- }
info->errkey= i < share->base.keys ? (int) i : -1;
/*
We delete keys in the reverse order of insertion. This is the order that
@@ -366,6 +360,7 @@ err:
{
if (_ma_ft_del(info,i,buff,record,filepos))
{
+ fatal_error= 1;
if (local_lock_tree)
mysql_rwlock_unlock(&keyinfo->root_lock);
break;
@@ -380,6 +375,7 @@ err:
filepos,
info->trn->trid)))
{
+ fatal_error= 1;
if (local_lock_tree)
mysql_rwlock_unlock(&keyinfo->root_lock);
break;
@@ -399,6 +395,13 @@ err:
fatal_error= 1;
}
+ if (info->bulk_insert)
+ {
+ uint j;
+ for (j=0 ; j < share->base.keys ; j++)
+ maria_flush_bulk_insert(info, j);
+ }
+
if (fatal_error)
{
maria_print_error(info->s, HA_ERR_CRASHED);
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index 5166ae63758..6f2d9fe8a5d 100644
--- a/storage/maria/maria_pack.c
+++ b/storage/maria/maria_pack.c
@@ -782,27 +782,29 @@ static HUFF_COUNTS *init_huff_count(MARIA_HA *info,my_off_t records)
for (i=0 ; i < info->s->base.fields ; i++)
{
enum en_fieldtype type;
- count[i].field_length=info->s->columndef[i].length;
- type= count[i].field_type= (enum en_fieldtype) info->s->columndef[i].type;
+ uint col_nr = info->s->columndef[i].column_nr;
+ count[col_nr].field_length=info->s->columndef[i].length;
+ type= count[col_nr].field_type=
+ (enum en_fieldtype) info->s->columndef[i].type;
if (type == FIELD_INTERVALL ||
type == FIELD_CONSTANT ||
type == FIELD_ZERO)
type = FIELD_NORMAL;
- if (count[i].field_length <= 8 &&
+ if (count[col_nr].field_length <= 8 &&
(type == FIELD_NORMAL ||
type == FIELD_SKIP_ZERO))
- count[i].max_zero_fill= count[i].field_length;
+ count[col_nr].max_zero_fill= count[col_nr].field_length;
/*
For every column initialize a tree, which is used to detect distinct
column values. 'int_tree' works together with 'tree_buff' and
'tree_pos'. It's keys are implemented by pointers into 'tree_buff'.
This is accomplished by '-1' as the element size.
*/
- init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree, NULL,
+ init_tree(&count[col_nr].int_tree,0,0,-1,(qsort_cmp2) compare_tree, NULL,
NULL, MYF(0));
if (records && type != FIELD_BLOB && type != FIELD_VARCHAR)
- count[i].tree_pos=count[i].tree_buff =
- my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,
+ count[col_nr].tree_pos=count[col_nr].tree_buff =
+ my_malloc(count[col_nr].field_length > 1 ? tree_buff_length : 2,
MYF(MY_WME));
}
}
diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp
index dfa28222de5..9db992bb86d 100644
--- a/storage/mroonga/mrn_table.cpp
+++ b/storage/mroonga/mrn_table.cpp
@@ -932,7 +932,7 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
share->wrap_key_info = NULL;
share->wrap_primary_key = MAX_KEY;
}
- memcpy(wrap_table_share, table->s, sizeof(*wrap_table_share));
+ *wrap_table_share= *table->s;
mrn_init_sql_alloc(current_thd, &(wrap_table_share->mem_root));
wrap_table_share->keys = share->wrap_keys;
wrap_table_share->key_info = share->wrap_key_info;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_decimal.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_decimal.result
index 015afdb5cf6..cb8a1c61306 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_decimal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_decimal.result
@@ -30,7 +30,7 @@ c2 c3
123.456000000000000000000000000000 0.000000000000000000000000000001
98765432109876543210987654321098765.432109876543210987654321098765 -123.456000000000000000000000000000
insert into t1 values(6,123.456,0.000000000000000000000000000001);
-ERROR 23000: Duplicate entry '123.456000000000000000000000000000-0.000000000000000000000000000' for key 'uk1'
+ERROR 23000: Duplicate entry '123.456000000000000000000000000000-0.000000000000000000000000...' for key 'uk1'
delete from t1 where c1 = 1;
insert into t1 values(1,123.456,0.000000000000000000000000000001);
drop table t1;
diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c
index cba22aa0e64..f3769f9aa4c 100644
--- a/storage/mroonga/vendor/groonga/lib/db.c
+++ b/storage/mroonga/vendor/groonga/lib/db.c
@@ -445,6 +445,9 @@ grn_db_close(grn_ctx *ctx, grn_obj *db)
ctx_used_db = ctx->impl && ctx->impl->db == db;
if (ctx_used_db) {
+#ifdef GRN_WITH_MECAB
+ grn_db_fin_mecab_tokenizer(ctx);
+#endif
grn_ctx_loader_clear(ctx);
if (ctx->impl->parser) {
grn_expr_parser_close(ctx);
diff --git a/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h b/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h
index e90dbfc0b31..81ac2ab6c46 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h
@@ -30,6 +30,7 @@ grn_rc grn_tokenizers_init(void);
grn_rc grn_tokenizers_fin(void);
grn_rc grn_db_init_mecab_tokenizer(grn_ctx *ctx);
+void grn_db_fin_mecab_tokenizer(grn_ctx *ctx);
grn_rc grn_db_init_builtin_tokenizers(grn_ctx *ctx);
#ifdef __cplusplus
diff --git a/storage/mroonga/vendor/groonga/lib/tokenizers.c b/storage/mroonga/vendor/groonga/lib/tokenizers.c
index 11f274e72db..3daacce7ef9 100644
--- a/storage/mroonga/vendor/groonga/lib/tokenizers.c
+++ b/storage/mroonga/vendor/groonga/lib/tokenizers.c
@@ -797,6 +797,36 @@ grn_db_init_mecab_tokenizer(grn_ctx *ctx)
}
}
+void
+grn_db_fin_mecab_tokenizer(grn_ctx *ctx)
+{
+ switch (GRN_CTX_GET_ENCODING(ctx)) {
+ case GRN_ENC_EUC_JP :
+ case GRN_ENC_UTF8 :
+ case GRN_ENC_SJIS :
+#if defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB)
+ {
+ GRN_PLUGIN_DECLARE_FUNCTIONS(tokenizers_mecab);
+ GRN_PLUGIN_IMPL_NAME_TAGGED(fin, tokenizers_mecab)(ctx);
+ }
+#else /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */
+ {
+ const char *mecab_plugin_name = "tokenizers/mecab";
+ char *path;
+ path = grn_plugin_find_path(ctx, mecab_plugin_name);
+ if (path) {
+ GRN_FREE(path);
+ grn_plugin_unregister(ctx, mecab_plugin_name);
+ }
+ }
+#endif /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */
+ break;
+ default :
+ break;
+ }
+ return;
+}
+
#define DEF_TOKENIZER(name, init, next, fin, vars)\
(grn_proc_create(ctx, (name), (sizeof(name) - 1),\
GRN_PROC_TOKENIZER, (init), (next), (fin), 3, (vars)))
diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c b/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
index 3dd969a89c5..cabf2c94e53 100644
--- a/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
+++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <ctype.h>
+static unsigned int sole_mecab_init_counter = 0;
static mecab_t *sole_mecab = NULL;
static grn_plugin_mutex *sole_mecab_mutex = NULL;
static grn_encoding sole_mecab_encoding = GRN_ENC_NONE;
@@ -563,6 +564,11 @@ check_mecab_dictionary_encoding(grn_ctx *ctx)
grn_rc
GRN_PLUGIN_INIT(grn_ctx *ctx)
{
+ ++sole_mecab_init_counter;
+ if (sole_mecab_init_counter > 1)
+ {
+ return GRN_SUCCESS;
+ }
{
char env[GRN_ENV_BUFFER_SIZE];
@@ -636,6 +642,11 @@ GRN_PLUGIN_REGISTER(grn_ctx *ctx)
grn_rc
GRN_PLUGIN_FIN(grn_ctx *ctx)
{
+ --sole_mecab_init_counter;
+ if (sole_mecab_init_counter > 0)
+ {
+ return GRN_SUCCESS;
+ }
if (sole_mecab) {
mecab_destroy(sole_mecab);
sole_mecab = NULL;
diff --git a/storage/myisam/ftbench/Ecompare.pl b/storage/myisam/ftbench/Ecompare.pl
index 07132ef9001..a97f126e64e 100755
--- a/storage/myisam/ftbench/Ecompare.pl
+++ b/storage/myisam/ftbench/Ecompare.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/myisam/ftbench/Ecreate.pl b/storage/myisam/ftbench/Ecreate.pl
index 86af9f9c0a5..78962466c80 100755
--- a/storage/myisam/ftbench/Ecreate.pl
+++ b/storage/myisam/ftbench/Ecreate.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/myisam/ftbench/Ereport.pl b/storage/myisam/ftbench/Ereport.pl
index d3f8961ec85..a8c7c57e1be 100755
--- a/storage/myisam/ftbench/Ereport.pl
+++ b/storage/myisam/ftbench/Ereport.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index b18ffb99a11..d9b9bb5af4a 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -1586,6 +1586,8 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info,
sort_param.filepos=new_header_length;
param->read_cache.end_of_file=sort_info.filelength=
mysql_file_seek(info->dfile, 0L, MY_SEEK_END, MYF(0));
+ if (info->state->data_file_length == 0)
+ info->state->data_file_length= sort_info.filelength;
sort_info.dupp=0;
sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master=1;
@@ -2290,6 +2292,8 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
sort_info.buff=0;
param->read_cache.end_of_file=sort_info.filelength=
mysql_file_seek(param->read_cache.file, 0L, MY_SEEK_END, MYF(0));
+ if (info->state->data_file_length == 0)
+ info->state->data_file_length= sort_info.filelength;
sort_param.wordlist=NULL;
init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0,
@@ -2757,6 +2761,8 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
sort_info.buff=0;
param->read_cache.end_of_file=sort_info.filelength=
mysql_file_seek(param->read_cache.file, 0L, MY_SEEK_END, MYF(0));
+ if (info->state->data_file_length == 0)
+ info->state->data_file_length= sort_info.filelength;
if (share->data_file_type == DYNAMIC_RECORD)
rec_length=MY_MAX(share->base.min_pack_length+1,share->base.min_block_length);
diff --git a/storage/myisam/mi_close.c b/storage/myisam/mi_close.c
index e09219e1c85..ca5c7355812 100644
--- a/storage/myisam/mi_close.c
+++ b/storage/myisam/mi_close.c
@@ -20,7 +20,7 @@
to open other files during the time we flush the cache and close this file
*/
-#include "myisamdef.h"
+#include "ftdefs.h"
int mi_close(register MI_INFO *info)
{
@@ -60,6 +60,8 @@ int mi_close(register MI_INFO *info)
mysql_mutex_unlock(&share->intern_lock);
my_free(mi_get_rec_buff_ptr(info, info->rec_buff));
+ ftparser_call_deinitializer(info);
+
if (flag)
{
DBUG_EXECUTE_IF("crash_before_flush_keys",
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index fd230698acc..de516d9fb6a 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -46,7 +46,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
uint aligned_key_start, block_length, res;
uint internal_table= flags & HA_CREATE_INTERNAL_TABLE;
ulong reclength, real_reclength,min_pack_length;
- char kfilename[FN_REFLEN],klinkname[FN_REFLEN], *klinkname_ptr;
+ char kfilename[FN_REFLEN],klinkname[FN_REFLEN], *klinkname_ptr= 0;
char dfilename[FN_REFLEN],dlinkname[FN_REFLEN], *dlinkname_ptr= 0;
ulong pack_reclength;
ulonglong tot_length,max_rows, tmp;
@@ -184,7 +184,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (flags & HA_CREATE_TMP_TABLE)
{
options|= HA_OPTION_TMP_TABLE;
- create_mode|= O_NOFOLLOW;
+ create_mode|= O_NOFOLLOW | (internal_table ? 0 : O_EXCL);
}
if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
{
@@ -619,10 +619,9 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
char *iext= strrchr(name, '.');
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
- fn_format(kfilename, name, "", MI_NAME_IEXT,
- MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
+ fn_format(kfilename, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME |
+ (internal_table ? 0 : MY_RETURN_REAL_PATH) |
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
- klinkname_ptr= 0;
/* Replace the current file */
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
}
diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c
index 72ce17b6a78..572fe690da8 100644
--- a/storage/myisam/mi_packrec.c
+++ b/storage/myisam/mi_packrec.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1111,10 +1112,10 @@ static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to,
bit_buff->error=1;
return; /* Can't be right */
}
- bit_buff->current_byte= (bit_buff->current_byte << 32) +
- ((((uint) bit_buff->pos[3])) +
- (((uint) bit_buff->pos[2]) << 8) +
- (((uint) bit_buff->pos[1]) << 16) +
+ bit_buff->current_byte= (bit_buff->current_byte << 32) |
+ ((((uint) bit_buff->pos[3])) |
+ (((uint) bit_buff->pos[2]) << 8) |
+ (((uint) bit_buff->pos[1]) << 16) |
(((uint) bit_buff->pos[0]) << 24));
bit_buff->pos+=4;
bits+=32;
@@ -1205,23 +1206,23 @@ static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
return; /* Can't be right */
}
#if BITS_SAVED == 32
- bit_buff->current_byte= (bit_buff->current_byte << 24) +
- (((uint) ((uchar) bit_buff->pos[2]))) +
- (((uint) ((uchar) bit_buff->pos[1])) << 8) +
+ bit_buff->current_byte= (bit_buff->current_byte << 24) |
+ (((uint) ((uchar) bit_buff->pos[2]))) |
+ (((uint) ((uchar) bit_buff->pos[1])) << 8) |
(((uint) ((uchar) bit_buff->pos[0])) << 16);
bit_buff->pos+=3;
bits+=24;
#else
if (bits) /* We must have at leasts 9 bits */
{
- bit_buff->current_byte= (bit_buff->current_byte << 8) +
+ bit_buff->current_byte= (bit_buff->current_byte << 8) |
(uint) ((uchar) bit_buff->pos[0]);
bit_buff->pos++;
bits+=8;
}
else
{
- bit_buff->current_byte= ((uint) ((uchar) bit_buff->pos[0]) << 8) +
+ bit_buff->current_byte= ((uint) ((uchar) bit_buff->pos[0]) << 8) |
((uint) ((uchar) bit_buff->pos[1]));
bit_buff->pos+=2;
bits+=16;
@@ -1245,14 +1246,14 @@ static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
if (bits < 8)
{ /* We don't need to check end */
#if BITS_SAVED == 32
- bit_buff->current_byte= (bit_buff->current_byte << 24) +
- (((uint) ((uchar) bit_buff->pos[2]))) +
- (((uint) ((uchar) bit_buff->pos[1])) << 8) +
+ bit_buff->current_byte= (bit_buff->current_byte << 24) |
+ (((uint) ((uchar) bit_buff->pos[2]))) |
+ (((uint) ((uchar) bit_buff->pos[1])) << 8) |
(((uint) ((uchar) bit_buff->pos[0])) << 16);
bit_buff->pos+=3;
bits+=24;
#else
- bit_buff->current_byte= (bit_buff->current_byte << 8) +
+ bit_buff->current_byte= (bit_buff->current_byte << 8) |
(uint) ((uchar) bit_buff->pos[0]);
bit_buff->pos+=1;
bits+=8;
@@ -1439,25 +1440,25 @@ static void fill_buffer(MI_BIT_BUFF *bit_buff)
}
#if BITS_SAVED == 64
- bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) +
- (((uint) ((uchar) bit_buff->pos[6])) << 8) +
- (((uint) ((uchar) bit_buff->pos[5])) << 16) +
- (((uint) ((uchar) bit_buff->pos[4])) << 24) +
+ bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) |
+ (((uint) ((uchar) bit_buff->pos[6])) << 8) |
+ (((uint) ((uchar) bit_buff->pos[5])) << 16) |
+ (((uint) ((uchar) bit_buff->pos[4])) << 24) |
((ulonglong)
- ((((uint) ((uchar) bit_buff->pos[3]))) +
- (((uint) ((uchar) bit_buff->pos[2])) << 8) +
- (((uint) ((uchar) bit_buff->pos[1])) << 16) +
+ ((((uint) ((uchar) bit_buff->pos[3]))) |
+ (((uint) ((uchar) bit_buff->pos[2])) << 8) |
+ (((uint) ((uchar) bit_buff->pos[1])) << 16) |
(((uint) ((uchar) bit_buff->pos[0])) << 24)) << 32));
bit_buff->pos+=8;
#else
#if BITS_SAVED == 32
- bit_buff->current_byte= (((uint) ((uchar) bit_buff->pos[3])) +
- (((uint) ((uchar) bit_buff->pos[2])) << 8) +
- (((uint) ((uchar) bit_buff->pos[1])) << 16) +
+ bit_buff->current_byte= (((uint) ((uchar) bit_buff->pos[3])) |
+ (((uint) ((uchar) bit_buff->pos[2])) << 8) |
+ (((uint) ((uchar) bit_buff->pos[1])) << 16) |
(((uint) ((uchar) bit_buff->pos[0])) << 24));
bit_buff->pos+=4;
#else
- bit_buff->current_byte= (uint) (((uint) ((uchar) bit_buff->pos[1]))+
+ bit_buff->current_byte= (uint) (((uint) ((uchar) bit_buff->pos[1])) |
(((uint) ((uchar) bit_buff->pos[0])) << 8));
bit_buff->pos+=2;
#endif
diff --git a/storage/myisammrg/myrg_extra.c b/storage/myisammrg/myrg_extra.c
index 43dfc18c710..2b3861b9f7f 100644
--- a/storage/myisammrg/myrg_extra.c
+++ b/storage/myisammrg/myrg_extra.c
@@ -31,7 +31,7 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function,
DBUG_PRINT("info",("function: %lu", (ulong) function));
if (!info->children_attached)
- DBUG_RETURN(1);
+ DBUG_RETURN(0);
if (function == HA_EXTRA_CACHE)
{
info->cache_in_use=1;
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index 46a801802a1..bf91213dbb0 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates
+ Copyright (c) 2010, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,7 +39,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
int save_errno,errpos=0;
uint files= 0, i, dir_length, length, UNINIT_VAR(key_parts), min_keys= 0;
ulonglong file_offset=0;
- char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
+ char name_buff[FN_REFLEN*2],buff[FN_REFLEN];
MYRG_INFO *m_info=0;
File fd;
IO_CACHE file;
@@ -62,8 +63,9 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
dir_length=dirname_part(name_buff, name, &name_buff_length);
while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
{
- if ((end=buff+length)[-1] == '\n')
- end[-1]='\0';
+ char *end= &buff[length - 1];
+ if (*end == '\n')
+ *end= '\0';
if (buff[0] && buff[0] != '#')
files++;
}
@@ -71,8 +73,9 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
my_b_seek(&file, 0);
while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
{
- if ((end=buff+length)[-1] == '\n')
- *--end='\0';
+ char *end= &buff[length - 1];
+ if (*end == '\n')
+ *end= '\0';
if (!buff[0])
continue; /* Skip empty lines */
if (buff[0] == '#')
diff --git a/storage/perfschema/CMakeLists.txt b/storage/perfschema/CMakeLists.txt
index 7db67700fac..e1839bc5b00 100644
--- a/storage/perfschema/CMakeLists.txt
+++ b/storage/perfschema/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/cursor_by_account.cc b/storage/perfschema/cursor_by_account.cc
index 2e75b8d51bd..f26318c42fc 100644
--- a/storage/perfschema/cursor_by_account.cc
+++ b/storage/perfschema/cursor_by_account.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_account.h b/storage/perfschema/cursor_by_account.h
index 150615b9c54..c14a563b712 100644
--- a/storage/perfschema/cursor_by_account.h
+++ b/storage/perfschema/cursor_by_account.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_host.cc b/storage/perfschema/cursor_by_host.cc
index d16f8b24b8e..c3397234e2e 100644
--- a/storage/perfschema/cursor_by_host.cc
+++ b/storage/perfschema/cursor_by_host.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_host.h b/storage/perfschema/cursor_by_host.h
index db33bbad808..ac68acf3945 100644
--- a/storage/perfschema/cursor_by_host.h
+++ b/storage/perfschema/cursor_by_host.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_thread.cc b/storage/perfschema/cursor_by_thread.cc
index 2fa9202fcf0..afdc9010b1f 100644
--- a/storage/perfschema/cursor_by_thread.cc
+++ b/storage/perfschema/cursor_by_thread.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_thread.h b/storage/perfschema/cursor_by_thread.h
index 5a77edf325f..db130088920 100644
--- a/storage/perfschema/cursor_by_thread.h
+++ b/storage/perfschema/cursor_by_thread.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_thread_connect_attr.cc b/storage/perfschema/cursor_by_thread_connect_attr.cc
index 2d5399cdac1..90a200b809a 100644
--- a/storage/perfschema/cursor_by_thread_connect_attr.cc
+++ b/storage/perfschema/cursor_by_thread_connect_attr.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/cursor_by_thread_connect_attr.h b/storage/perfschema/cursor_by_thread_connect_attr.h
index b5059918f7f..69d1b5ec0c0 100644
--- a/storage/perfschema/cursor_by_thread_connect_attr.h
+++ b/storage/perfschema/cursor_by_thread_connect_attr.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/cursor_by_user.cc b/storage/perfschema/cursor_by_user.cc
index 37ecbf17fee..273d186b01c 100644
--- a/storage/perfschema/cursor_by_user.cc
+++ b/storage/perfschema/cursor_by_user.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_user.h b/storage/perfschema/cursor_by_user.h
index d6e997766b6..06554ebb228 100644
--- a/storage/perfschema/cursor_by_user.h
+++ b/storage/perfschema/cursor_by_user.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/gen_pfs_lex_token.cc b/storage/perfschema/gen_pfs_lex_token.cc
index dcf25c79706..5a51a8aeb2f 100644
--- a/storage/perfschema/gen_pfs_lex_token.cc
+++ b/storage/perfschema/gen_pfs_lex_token.cc
@@ -2,13 +2,20 @@
Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc
index 864c41e5a05..17d33aeadb7 100644
--- a/storage/perfschema/ha_perfschema.cc
+++ b/storage/perfschema/ha_perfschema.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h
index 9c56fc1928e..0fbfdeba325 100644
--- a/storage/perfschema/ha_perfschema.h
+++ b/storage/perfschema/ha_perfschema.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc
index 8d55e1b0393..dbad7e966a5 100644
--- a/storage/perfschema/pfs.cc
+++ b/storage/perfschema/pfs.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs.h b/storage/perfschema/pfs.h
index da5e11edab7..8e0d9b760ed 100644
--- a/storage/perfschema/pfs.h
+++ b/storage/perfschema/pfs.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_account.cc b/storage/perfschema/pfs_account.cc
index 5ac16b7636e..be2153e84ae 100644
--- a/storage/perfschema/pfs_account.cc
+++ b/storage/perfschema/pfs_account.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_account.h b/storage/perfschema/pfs_account.h
index 544abf913ae..cd7b1520df5 100644
--- a/storage/perfschema/pfs_account.h
+++ b/storage/perfschema/pfs_account.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_atomic.h b/storage/perfschema/pfs_atomic.h
index def9339d06d..00d1197970b 100644
--- a/storage/perfschema/pfs_atomic.h
+++ b/storage/perfschema/pfs_atomic.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_autosize.cc b/storage/perfschema/pfs_autosize.cc
index 2d1723c177a..43c754939a4 100644
--- a/storage/perfschema/pfs_autosize.cc
+++ b/storage/perfschema/pfs_autosize.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_column_types.h b/storage/perfschema/pfs_column_types.h
index ef657b38707..09fce551402 100644
--- a/storage/perfschema/pfs_column_types.h
+++ b/storage/perfschema/pfs_column_types.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_column_values.cc b/storage/perfschema/pfs_column_values.cc
index 87fa9f0b639..697010e46b8 100644
--- a/storage/perfschema/pfs_column_values.cc
+++ b/storage/perfschema/pfs_column_values.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_column_values.h b/storage/perfschema/pfs_column_values.h
index eb25a5977e3..55ffa139fe0 100644
--- a/storage/perfschema/pfs_column_values.h
+++ b/storage/perfschema/pfs_column_values.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_con_slice.cc b/storage/perfschema/pfs_con_slice.cc
index bce4918ae9e..9f9deb0919c 100644
--- a/storage/perfschema/pfs_con_slice.cc
+++ b/storage/perfschema/pfs_con_slice.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_con_slice.h b/storage/perfschema/pfs_con_slice.h
index f83764339c3..ed17de5f2b0 100644
--- a/storage/perfschema/pfs_con_slice.h
+++ b/storage/perfschema/pfs_con_slice.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_defaults.cc b/storage/perfschema/pfs_defaults.cc
index ec2da41e30b..f879c527b4f 100644
--- a/storage/perfschema/pfs_defaults.cc
+++ b/storage/perfschema/pfs_defaults.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_defaults.h b/storage/perfschema/pfs_defaults.h
index d95c4914e9d..7751b55b83b 100644
--- a/storage/perfschema/pfs_defaults.h
+++ b/storage/perfschema/pfs_defaults.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_digest.cc b/storage/perfschema/pfs_digest.cc
index 1362ef2676b..7d66731ce3a 100644
--- a/storage/perfschema/pfs_digest.cc
+++ b/storage/perfschema/pfs_digest.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_digest.h b/storage/perfschema/pfs_digest.h
index 543fa7858a4..352f495a80c 100644
--- a/storage/perfschema/pfs_digest.h
+++ b/storage/perfschema/pfs_digest.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc
index 8e521dcd486..08c0fe8ecfe 100644
--- a/storage/perfschema/pfs_engine_table.cc
+++ b/storage/perfschema/pfs_engine_table.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_engine_table.h b/storage/perfschema/pfs_engine_table.h
index d3c4a0e43e6..c53cd205d71 100644
--- a/storage/perfschema/pfs_engine_table.h
+++ b/storage/perfschema/pfs_engine_table.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_events.h b/storage/perfschema/pfs_events.h
index 09c3935816f..ca2fd8582ad 100644
--- a/storage/perfschema/pfs_events.h
+++ b/storage/perfschema/pfs_events.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_events_stages.cc b/storage/perfschema/pfs_events_stages.cc
index 673d2cb95f5..a68b0729e96 100644
--- a/storage/perfschema/pfs_events_stages.cc
+++ b/storage/perfschema/pfs_events_stages.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_events_stages.h b/storage/perfschema/pfs_events_stages.h
index ea879bcd211..f61a7c3c077 100644
--- a/storage/perfschema/pfs_events_stages.h
+++ b/storage/perfschema/pfs_events_stages.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_events_statements.cc b/storage/perfschema/pfs_events_statements.cc
index 66a98e3f7d8..1942787665a 100644
--- a/storage/perfschema/pfs_events_statements.cc
+++ b/storage/perfschema/pfs_events_statements.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_events_statements.h b/storage/perfschema/pfs_events_statements.h
index a56423d3863..e47e2e79280 100644
--- a/storage/perfschema/pfs_events_statements.h
+++ b/storage/perfschema/pfs_events_statements.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_events_waits.cc b/storage/perfschema/pfs_events_waits.cc
index f99a1f31bd9..c3961461f34 100644
--- a/storage/perfschema/pfs_events_waits.cc
+++ b/storage/perfschema/pfs_events_waits.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_events_waits.h b/storage/perfschema/pfs_events_waits.h
index 25784fd52ba..702f7e3ce07 100644
--- a/storage/perfschema/pfs_events_waits.h
+++ b/storage/perfschema/pfs_events_waits.h
@@ -2,13 +2,20 @@
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_global.cc b/storage/perfschema/pfs_global.cc
index 25dd817b149..afa31ffa903 100644
--- a/storage/perfschema/pfs_global.cc
+++ b/storage/perfschema/pfs_global.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_global.h b/storage/perfschema/pfs_global.h
index d8636a09d57..9c85506d7c2 100644
--- a/storage/perfschema/pfs_global.h
+++ b/storage/perfschema/pfs_global.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_host.cc b/storage/perfschema/pfs_host.cc
index 2d24a5f4b97..d6461ef3851 100644
--- a/storage/perfschema/pfs_host.cc
+++ b/storage/perfschema/pfs_host.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_host.h b/storage/perfschema/pfs_host.h
index 4e6b24bf6c6..d52207d3571 100644
--- a/storage/perfschema/pfs_host.h
+++ b/storage/perfschema/pfs_host.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc
index d52af3e80df..675679f9b4d 100644
--- a/storage/perfschema/pfs_instr.cc
+++ b/storage/perfschema/pfs_instr.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_instr.h b/storage/perfschema/pfs_instr.h
index 76eeabb99da..12447c0c4e7 100644
--- a/storage/perfschema/pfs_instr.h
+++ b/storage/perfschema/pfs_instr.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc
index f4b32c4a438..c75418b28e9 100644
--- a/storage/perfschema/pfs_instr_class.cc
+++ b/storage/perfschema/pfs_instr_class.cc
@@ -1,13 +1,21 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
@@ -612,6 +620,7 @@ static void init_instr_class(PFS_instr_class *klass,
DBUG_ASSERT(name_length <= PFS_MAX_INFO_NAME_LENGTH);
memset(klass, 0, sizeof(PFS_instr_class));
strncpy(klass->m_name, name, name_length);
+ klass->m_name[PFS_MAX_INFO_NAME_LENGTH - 1]= '\0';
klass->m_name_length= name_length;
klass->m_flags= flags;
klass->m_enabled= true;
diff --git a/storage/perfschema/pfs_instr_class.h b/storage/perfschema/pfs_instr_class.h
index 038814b07e2..9d256fac78a 100644
--- a/storage/perfschema/pfs_instr_class.h
+++ b/storage/perfschema/pfs_instr_class.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_lock.h b/storage/perfschema/pfs_lock.h
index 4011cba2070..b74131c79e1 100644
--- a/storage/perfschema/pfs_lock.h
+++ b/storage/perfschema/pfs_lock.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_server.cc b/storage/perfschema/pfs_server.cc
index 9dd6fbf4762..77574f1ce49 100644
--- a/storage/perfschema/pfs_server.cc
+++ b/storage/perfschema/pfs_server.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_server.h b/storage/perfschema/pfs_server.h
index aea86a576cc..0532dcb7eba 100644
--- a/storage/perfschema/pfs_server.h
+++ b/storage/perfschema/pfs_server.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_setup_actor.cc b/storage/perfschema/pfs_setup_actor.cc
index 42c32b12411..c4cec6c9ff8 100644
--- a/storage/perfschema/pfs_setup_actor.cc
+++ b/storage/perfschema/pfs_setup_actor.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_setup_actor.h b/storage/perfschema/pfs_setup_actor.h
index 92a1617c304..613d5454a9c 100644
--- a/storage/perfschema/pfs_setup_actor.h
+++ b/storage/perfschema/pfs_setup_actor.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_setup_object.cc b/storage/perfschema/pfs_setup_object.cc
index 128091a398b..f33030e927f 100644
--- a/storage/perfschema/pfs_setup_object.cc
+++ b/storage/perfschema/pfs_setup_object.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_setup_object.h b/storage/perfschema/pfs_setup_object.h
index 0d343f552b2..ee40742941c 100644
--- a/storage/perfschema/pfs_setup_object.h
+++ b/storage/perfschema/pfs_setup_object.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_stat.h b/storage/perfschema/pfs_stat.h
index 9e4da7957f6..8a049e3013b 100644
--- a/storage/perfschema/pfs_stat.h
+++ b/storage/perfschema/pfs_stat.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_timer.cc b/storage/perfschema/pfs_timer.cc
index 5e2c27c217b..8533dffcb27 100644
--- a/storage/perfschema/pfs_timer.cc
+++ b/storage/perfschema/pfs_timer.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_timer.h b/storage/perfschema/pfs_timer.h
index a4f55c20994..738e0b365fb 100644
--- a/storage/perfschema/pfs_timer.h
+++ b/storage/perfschema/pfs_timer.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_user.cc b/storage/perfschema/pfs_user.cc
index d923d4158a5..14b86e1478e 100644
--- a/storage/perfschema/pfs_user.cc
+++ b/storage/perfschema/pfs_user.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_user.h b/storage/perfschema/pfs_user.h
index f2b1c4409c7..3d0457eae59 100644
--- a/storage/perfschema/pfs_user.h
+++ b/storage/perfschema/pfs_user.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_visitor.cc b/storage/perfschema/pfs_visitor.cc
index 3df7ef91bb3..097965fde17 100644
--- a/storage/perfschema/pfs_visitor.cc
+++ b/storage/perfschema/pfs_visitor.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_visitor.h b/storage/perfschema/pfs_visitor.h
index c3ada2f4e0b..120b5928045 100644
--- a/storage/perfschema/pfs_visitor.h
+++ b/storage/perfschema/pfs_visitor.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_accounts.cc b/storage/perfschema/table_accounts.cc
index 007fcb25550..708f8269a69 100644
--- a/storage/perfschema/table_accounts.cc
+++ b/storage/perfschema/table_accounts.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_accounts.h b/storage/perfschema/table_accounts.h
index f72eb39ed39..dfc2cc322e0 100644
--- a/storage/perfschema/table_accounts.h
+++ b/storage/perfschema/table_accounts.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_all_instr.cc b/storage/perfschema/table_all_instr.cc
index 05ec9f09c11..d48028b1539 100644
--- a/storage/perfschema/table_all_instr.cc
+++ b/storage/perfschema/table_all_instr.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_all_instr.h b/storage/perfschema/table_all_instr.h
index 7c9d5d9b0d6..072221ba86e 100644
--- a/storage/perfschema/table_all_instr.h
+++ b/storage/perfschema/table_all_instr.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_esgs_by_account_by_event_name.cc b/storage/perfschema/table_esgs_by_account_by_event_name.cc
index 3bc76f899ad..22e4e0040f1 100644
--- a/storage/perfschema/table_esgs_by_account_by_event_name.cc
+++ b/storage/perfschema/table_esgs_by_account_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_account_by_event_name.h b/storage/perfschema/table_esgs_by_account_by_event_name.h
index 5afd68cd7d9..ee855d42818 100644
--- a/storage/perfschema/table_esgs_by_account_by_event_name.h
+++ b/storage/perfschema/table_esgs_by_account_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_host_by_event_name.cc b/storage/perfschema/table_esgs_by_host_by_event_name.cc
index bbef6a8d16d..86cc2eb1b86 100644
--- a/storage/perfschema/table_esgs_by_host_by_event_name.cc
+++ b/storage/perfschema/table_esgs_by_host_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_host_by_event_name.h b/storage/perfschema/table_esgs_by_host_by_event_name.h
index afc6d529428..6042e6396af 100644
--- a/storage/perfschema/table_esgs_by_host_by_event_name.h
+++ b/storage/perfschema/table_esgs_by_host_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_thread_by_event_name.cc b/storage/perfschema/table_esgs_by_thread_by_event_name.cc
index 57ef634acad..dfda9702abb 100644
--- a/storage/perfschema/table_esgs_by_thread_by_event_name.cc
+++ b/storage/perfschema/table_esgs_by_thread_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_thread_by_event_name.h b/storage/perfschema/table_esgs_by_thread_by_event_name.h
index 7db8d1be408..6ff677a95e2 100644
--- a/storage/perfschema/table_esgs_by_thread_by_event_name.h
+++ b/storage/perfschema/table_esgs_by_thread_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_user_by_event_name.cc b/storage/perfschema/table_esgs_by_user_by_event_name.cc
index f8e8518bde3..af73c1fc5fd 100644
--- a/storage/perfschema/table_esgs_by_user_by_event_name.cc
+++ b/storage/perfschema/table_esgs_by_user_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_user_by_event_name.h b/storage/perfschema/table_esgs_by_user_by_event_name.h
index 8f48747c8c8..bc545c2438a 100644
--- a/storage/perfschema/table_esgs_by_user_by_event_name.h
+++ b/storage/perfschema/table_esgs_by_user_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_global_by_event_name.cc b/storage/perfschema/table_esgs_global_by_event_name.cc
index 83a4dbf43fd..6c5f0866671 100644
--- a/storage/perfschema/table_esgs_global_by_event_name.cc
+++ b/storage/perfschema/table_esgs_global_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_global_by_event_name.h b/storage/perfschema/table_esgs_global_by_event_name.h
index 2b0ac8b6218..b8884355676 100644
--- a/storage/perfschema/table_esgs_global_by_event_name.h
+++ b/storage/perfschema/table_esgs_global_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_account_by_event_name.cc b/storage/perfschema/table_esms_by_account_by_event_name.cc
index d8f04d7af23..7afdabcbbfe 100644
--- a/storage/perfschema/table_esms_by_account_by_event_name.cc
+++ b/storage/perfschema/table_esms_by_account_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_account_by_event_name.h b/storage/perfschema/table_esms_by_account_by_event_name.h
index ff212291760..64f2053cff6 100644
--- a/storage/perfschema/table_esms_by_account_by_event_name.h
+++ b/storage/perfschema/table_esms_by_account_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_digest.cc b/storage/perfschema/table_esms_by_digest.cc
index ae648378b2a..5295c29dc40 100644
--- a/storage/perfschema/table_esms_by_digest.cc
+++ b/storage/perfschema/table_esms_by_digest.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_digest.h b/storage/perfschema/table_esms_by_digest.h
index 682dc70ab10..903b86110f6 100644
--- a/storage/perfschema/table_esms_by_digest.h
+++ b/storage/perfschema/table_esms_by_digest.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_host_by_event_name.cc b/storage/perfschema/table_esms_by_host_by_event_name.cc
index 7233b340bd2..42629ab6c09 100644
--- a/storage/perfschema/table_esms_by_host_by_event_name.cc
+++ b/storage/perfschema/table_esms_by_host_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_host_by_event_name.h b/storage/perfschema/table_esms_by_host_by_event_name.h
index def5e19ecdc..a6985b48149 100644
--- a/storage/perfschema/table_esms_by_host_by_event_name.h
+++ b/storage/perfschema/table_esms_by_host_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_thread_by_event_name.cc b/storage/perfschema/table_esms_by_thread_by_event_name.cc
index f62d974aa76..0a7cf46986c 100644
--- a/storage/perfschema/table_esms_by_thread_by_event_name.cc
+++ b/storage/perfschema/table_esms_by_thread_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_thread_by_event_name.h b/storage/perfschema/table_esms_by_thread_by_event_name.h
index 7c50307c483..72645d03389 100644
--- a/storage/perfschema/table_esms_by_thread_by_event_name.h
+++ b/storage/perfschema/table_esms_by_thread_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_user_by_event_name.cc b/storage/perfschema/table_esms_by_user_by_event_name.cc
index 66afe288f12..f8708ac9a14 100644
--- a/storage/perfschema/table_esms_by_user_by_event_name.cc
+++ b/storage/perfschema/table_esms_by_user_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_user_by_event_name.h b/storage/perfschema/table_esms_by_user_by_event_name.h
index 65284122043..d1d1e5df85d 100644
--- a/storage/perfschema/table_esms_by_user_by_event_name.h
+++ b/storage/perfschema/table_esms_by_user_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_global_by_event_name.cc b/storage/perfschema/table_esms_global_by_event_name.cc
index 96957bf028e..7d9584752b0 100644
--- a/storage/perfschema/table_esms_global_by_event_name.cc
+++ b/storage/perfschema/table_esms_global_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_global_by_event_name.h b/storage/perfschema/table_esms_global_by_event_name.h
index 7453d635848..b90c14c0c0f 100644
--- a/storage/perfschema/table_esms_global_by_event_name.h
+++ b/storage/perfschema/table_esms_global_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_events_stages.cc b/storage/perfschema/table_events_stages.cc
index 757c42b59c4..0a09d2c83fa 100644
--- a/storage/perfschema/table_events_stages.cc
+++ b/storage/perfschema/table_events_stages.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_stages.h b/storage/perfschema/table_events_stages.h
index cbc0f9a42bb..ae8760cd953 100644
--- a/storage/perfschema/table_events_stages.h
+++ b/storage/perfschema/table_events_stages.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_statements.cc b/storage/perfschema/table_events_statements.cc
index 4470e5bda43..392f1f747f2 100644
--- a/storage/perfschema/table_events_statements.cc
+++ b/storage/perfschema/table_events_statements.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_statements.h b/storage/perfschema/table_events_statements.h
index 6f8bc1621d0..cec28628f3e 100644
--- a/storage/perfschema/table_events_statements.h
+++ b/storage/perfschema/table_events_statements.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_waits.cc b/storage/perfschema/table_events_waits.cc
index b16688e3983..d6955a46984 100644
--- a/storage/perfschema/table_events_waits.cc
+++ b/storage/perfschema/table_events_waits.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_waits.h b/storage/perfschema/table_events_waits.h
index 3e09fa487ad..90c1d341e5d 100644
--- a/storage/perfschema/table_events_waits.h
+++ b/storage/perfschema/table_events_waits.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_waits_summary.cc b/storage/perfschema/table_events_waits_summary.cc
index 2f5c83d57d3..03477f6d542 100644
--- a/storage/perfschema/table_events_waits_summary.cc
+++ b/storage/perfschema/table_events_waits_summary.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_waits_summary.h b/storage/perfschema/table_events_waits_summary.h
index a4f063bb66a..53f1bed7987 100644
--- a/storage/perfschema/table_events_waits_summary.h
+++ b/storage/perfschema/table_events_waits_summary.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_ews_by_account_by_event_name.cc b/storage/perfschema/table_ews_by_account_by_event_name.cc
index 0b86a4ac1dc..fa6258ec9ac 100644
--- a/storage/perfschema/table_ews_by_account_by_event_name.cc
+++ b/storage/perfschema/table_ews_by_account_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_account_by_event_name.h b/storage/perfschema/table_ews_by_account_by_event_name.h
index b46008e2675..7cde09183e3 100644
--- a/storage/perfschema/table_ews_by_account_by_event_name.h
+++ b/storage/perfschema/table_ews_by_account_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_host_by_event_name.cc b/storage/perfschema/table_ews_by_host_by_event_name.cc
index e82c734431c..e3ef7ca3720 100644
--- a/storage/perfschema/table_ews_by_host_by_event_name.cc
+++ b/storage/perfschema/table_ews_by_host_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_host_by_event_name.h b/storage/perfschema/table_ews_by_host_by_event_name.h
index c631da36ec5..8ce44a96617 100644
--- a/storage/perfschema/table_ews_by_host_by_event_name.h
+++ b/storage/perfschema/table_ews_by_host_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_thread_by_event_name.cc b/storage/perfschema/table_ews_by_thread_by_event_name.cc
index 7b3e220e973..33f9765310b 100644
--- a/storage/perfschema/table_ews_by_thread_by_event_name.cc
+++ b/storage/perfschema/table_ews_by_thread_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_thread_by_event_name.h b/storage/perfschema/table_ews_by_thread_by_event_name.h
index cf94e7a81a2..b67664bfced 100644
--- a/storage/perfschema/table_ews_by_thread_by_event_name.h
+++ b/storage/perfschema/table_ews_by_thread_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_user_by_event_name.cc b/storage/perfschema/table_ews_by_user_by_event_name.cc
index 577a9ef6676..cb99f749a9c 100644
--- a/storage/perfschema/table_ews_by_user_by_event_name.cc
+++ b/storage/perfschema/table_ews_by_user_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_user_by_event_name.h b/storage/perfschema/table_ews_by_user_by_event_name.h
index e987cf1bcec..f4f29534be4 100644
--- a/storage/perfschema/table_ews_by_user_by_event_name.h
+++ b/storage/perfschema/table_ews_by_user_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_global_by_event_name.cc b/storage/perfschema/table_ews_global_by_event_name.cc
index 9a5ba4f2375..7420c6351fd 100644
--- a/storage/perfschema/table_ews_global_by_event_name.cc
+++ b/storage/perfschema/table_ews_global_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_ews_global_by_event_name.h b/storage/perfschema/table_ews_global_by_event_name.h
index 57e3459e373..8157d274112 100644
--- a/storage/perfschema/table_ews_global_by_event_name.h
+++ b/storage/perfschema/table_ews_global_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_instances.cc b/storage/perfschema/table_file_instances.cc
index 7914664e2e0..b323df83ad2 100644
--- a/storage/perfschema/table_file_instances.cc
+++ b/storage/perfschema/table_file_instances.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_instances.h b/storage/perfschema/table_file_instances.h
index e07017911de..5b44e63028e 100644
--- a/storage/perfschema/table_file_instances.h
+++ b/storage/perfschema/table_file_instances.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_summary_by_event_name.cc b/storage/perfschema/table_file_summary_by_event_name.cc
index e98bc528995..459b2bf99a6 100644
--- a/storage/perfschema/table_file_summary_by_event_name.cc
+++ b/storage/perfschema/table_file_summary_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_summary_by_event_name.h b/storage/perfschema/table_file_summary_by_event_name.h
index 7a13fcdc4d9..b8cb293cb07 100644
--- a/storage/perfschema/table_file_summary_by_event_name.h
+++ b/storage/perfschema/table_file_summary_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_summary_by_instance.cc b/storage/perfschema/table_file_summary_by_instance.cc
index b80811d0a5b..3a30984405c 100644
--- a/storage/perfschema/table_file_summary_by_instance.cc
+++ b/storage/perfschema/table_file_summary_by_instance.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_summary_by_instance.h b/storage/perfschema/table_file_summary_by_instance.h
index 872698f8e58..0e7ce6958b2 100644
--- a/storage/perfschema/table_file_summary_by_instance.h
+++ b/storage/perfschema/table_file_summary_by_instance.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_helper.cc b/storage/perfschema/table_helper.cc
index 0dbeeb259c1..d6bdd894483 100644
--- a/storage/perfschema/table_helper.cc
+++ b/storage/perfschema/table_helper.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_helper.h b/storage/perfschema/table_helper.h
index b57abe9c4e6..62f94826754 100644
--- a/storage/perfschema/table_helper.h
+++ b/storage/perfschema/table_helper.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_host_cache.cc b/storage/perfschema/table_host_cache.cc
index 758a2c6dea6..430dcf2763d 100644
--- a/storage/perfschema/table_host_cache.cc
+++ b/storage/perfschema/table_host_cache.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_host_cache.h b/storage/perfschema/table_host_cache.h
index 47abb42444e..8add0b5049c 100644
--- a/storage/perfschema/table_host_cache.h
+++ b/storage/perfschema/table_host_cache.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_hosts.cc b/storage/perfschema/table_hosts.cc
index 2c5377db4ac..8bc5310817c 100644
--- a/storage/perfschema/table_hosts.cc
+++ b/storage/perfschema/table_hosts.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_hosts.h b/storage/perfschema/table_hosts.h
index 60b70ae803e..422b6449b25 100644
--- a/storage/perfschema/table_hosts.h
+++ b/storage/perfschema/table_hosts.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_os_global_by_type.cc b/storage/perfschema/table_os_global_by_type.cc
index cd2ace50c85..b549b0c22e7 100644
--- a/storage/perfschema/table_os_global_by_type.cc
+++ b/storage/perfschema/table_os_global_by_type.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_os_global_by_type.h b/storage/perfschema/table_os_global_by_type.h
index a434961b65b..2b9293ece06 100644
--- a/storage/perfschema/table_os_global_by_type.h
+++ b/storage/perfschema/table_os_global_by_type.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_performance_timers.cc b/storage/perfschema/table_performance_timers.cc
index 8d31c017832..a77f005ab62 100644
--- a/storage/perfschema/table_performance_timers.cc
+++ b/storage/perfschema/table_performance_timers.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_performance_timers.h b/storage/perfschema/table_performance_timers.h
index e1dc93fcbe4..93210ac9882 100644
--- a/storage/perfschema/table_performance_timers.h
+++ b/storage/perfschema/table_performance_timers.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_account_connect_attrs.cc b/storage/perfschema/table_session_account_connect_attrs.cc
index c00f72e36b4..59a36e1cdb0 100644
--- a/storage/perfschema/table_session_account_connect_attrs.cc
+++ b/storage/perfschema/table_session_account_connect_attrs.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_account_connect_attrs.h b/storage/perfschema/table_session_account_connect_attrs.h
index d56d571fb79..483001fcb91 100644
--- a/storage/perfschema/table_session_account_connect_attrs.h
+++ b/storage/perfschema/table_session_account_connect_attrs.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_connect.cc b/storage/perfschema/table_session_connect.cc
index 737ff514555..47dd63a9f49 100644
--- a/storage/perfschema/table_session_connect.cc
+++ b/storage/perfschema/table_session_connect.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_connect.h b/storage/perfschema/table_session_connect.h
index 91d24ab7075..ee1019fe7f2 100644
--- a/storage/perfschema/table_session_connect.h
+++ b/storage/perfschema/table_session_connect.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_connect_attrs.cc b/storage/perfschema/table_session_connect_attrs.cc
index 859c6f2f8b8..a4bb651f291 100644
--- a/storage/perfschema/table_session_connect_attrs.cc
+++ b/storage/perfschema/table_session_connect_attrs.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_connect_attrs.h b/storage/perfschema/table_session_connect_attrs.h
index de18085d8ac..927c3a92af2 100644
--- a/storage/perfschema/table_session_connect_attrs.h
+++ b/storage/perfschema/table_session_connect_attrs.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_actors.cc b/storage/perfschema/table_setup_actors.cc
index fcb32b9cb35..305cfd32169 100644
--- a/storage/perfschema/table_setup_actors.cc
+++ b/storage/perfschema/table_setup_actors.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_actors.h b/storage/perfschema/table_setup_actors.h
index 550e196c8d1..3082c9c3922 100644
--- a/storage/perfschema/table_setup_actors.h
+++ b/storage/perfschema/table_setup_actors.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_consumers.cc b/storage/perfschema/table_setup_consumers.cc
index f00e1fff48d..afd7f41260a 100644
--- a/storage/perfschema/table_setup_consumers.cc
+++ b/storage/perfschema/table_setup_consumers.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_consumers.h b/storage/perfschema/table_setup_consumers.h
index b27c8873550..608ee880435 100644
--- a/storage/perfschema/table_setup_consumers.h
+++ b/storage/perfschema/table_setup_consumers.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_instruments.cc b/storage/perfschema/table_setup_instruments.cc
index 8adea1d3604..4741e944ee0 100644
--- a/storage/perfschema/table_setup_instruments.cc
+++ b/storage/perfschema/table_setup_instruments.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_instruments.h b/storage/perfschema/table_setup_instruments.h
index b2711578d7f..433fdaf056b 100644
--- a/storage/perfschema/table_setup_instruments.h
+++ b/storage/perfschema/table_setup_instruments.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_objects.cc b/storage/perfschema/table_setup_objects.cc
index 8049fcdf48c..168c51cfdda 100644
--- a/storage/perfschema/table_setup_objects.cc
+++ b/storage/perfschema/table_setup_objects.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_objects.h b/storage/perfschema/table_setup_objects.h
index 943cc4a1ad5..66f9fb2c8e8 100644
--- a/storage/perfschema/table_setup_objects.h
+++ b/storage/perfschema/table_setup_objects.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_timers.cc b/storage/perfschema/table_setup_timers.cc
index 26539da2e27..be1ac58cc3e 100644
--- a/storage/perfschema/table_setup_timers.cc
+++ b/storage/perfschema/table_setup_timers.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_timers.h b/storage/perfschema/table_setup_timers.h
index 9eb2f95836c..667c1d94889 100644
--- a/storage/perfschema/table_setup_timers.h
+++ b/storage/perfschema/table_setup_timers.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_instances.cc b/storage/perfschema/table_socket_instances.cc
index 419e19349f4..920531136d5 100644
--- a/storage/perfschema/table_socket_instances.cc
+++ b/storage/perfschema/table_socket_instances.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_instances.h b/storage/perfschema/table_socket_instances.h
index b5e5edb36ed..41b5ee3fd21 100644
--- a/storage/perfschema/table_socket_instances.h
+++ b/storage/perfschema/table_socket_instances.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_summary_by_event_name.cc b/storage/perfschema/table_socket_summary_by_event_name.cc
index 2da45c0d2cd..c813d45b732 100644
--- a/storage/perfschema/table_socket_summary_by_event_name.cc
+++ b/storage/perfschema/table_socket_summary_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_summary_by_event_name.h b/storage/perfschema/table_socket_summary_by_event_name.h
index 9bdeb3104b4..4f679d89b09 100644
--- a/storage/perfschema/table_socket_summary_by_event_name.h
+++ b/storage/perfschema/table_socket_summary_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_summary_by_instance.cc b/storage/perfschema/table_socket_summary_by_instance.cc
index 693f65e4843..a4b1477aa90 100644
--- a/storage/perfschema/table_socket_summary_by_instance.cc
+++ b/storage/perfschema/table_socket_summary_by_instance.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_summary_by_instance.h b/storage/perfschema/table_socket_summary_by_instance.h
index deb8ffab554..a9eab8d18b6 100644
--- a/storage/perfschema/table_socket_summary_by_instance.h
+++ b/storage/perfschema/table_socket_summary_by_instance.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_sync_instances.cc b/storage/perfschema/table_sync_instances.cc
index 6e48468e6c3..f0c7800d24a 100644
--- a/storage/perfschema/table_sync_instances.cc
+++ b/storage/perfschema/table_sync_instances.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_sync_instances.h b/storage/perfschema/table_sync_instances.h
index c6a2ed8adaa..6f7e1bf5523 100644
--- a/storage/perfschema/table_sync_instances.h
+++ b/storage/perfschema/table_sync_instances.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_threads.cc b/storage/perfschema/table_threads.cc
index aff2e818f70..eccf41db971 100644
--- a/storage/perfschema/table_threads.cc
+++ b/storage/perfschema/table_threads.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_threads.h b/storage/perfschema/table_threads.h
index 823f66bf713..927438eec61 100644
--- a/storage/perfschema/table_threads.h
+++ b/storage/perfschema/table_threads.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_tiws_by_index_usage.cc b/storage/perfschema/table_tiws_by_index_usage.cc
index 5d24fcc689b..b49e9280469 100644
--- a/storage/perfschema/table_tiws_by_index_usage.cc
+++ b/storage/perfschema/table_tiws_by_index_usage.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tiws_by_index_usage.h b/storage/perfschema/table_tiws_by_index_usage.h
index f6d935365b2..a284bc7f0bc 100644
--- a/storage/perfschema/table_tiws_by_index_usage.h
+++ b/storage/perfschema/table_tiws_by_index_usage.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tiws_by_table.cc b/storage/perfschema/table_tiws_by_table.cc
index 78535fd6512..db00fd2409e 100644
--- a/storage/perfschema/table_tiws_by_table.cc
+++ b/storage/perfschema/table_tiws_by_table.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tiws_by_table.h b/storage/perfschema/table_tiws_by_table.h
index 9a86d39196c..7427ca797fa 100644
--- a/storage/perfschema/table_tiws_by_table.h
+++ b/storage/perfschema/table_tiws_by_table.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tlws_by_table.cc b/storage/perfschema/table_tlws_by_table.cc
index 5299e7f6a56..d802127d10d 100644
--- a/storage/perfschema/table_tlws_by_table.cc
+++ b/storage/perfschema/table_tlws_by_table.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tlws_by_table.h b/storage/perfschema/table_tlws_by_table.h
index 757adc3f5f5..b5872a07762 100644
--- a/storage/perfschema/table_tlws_by_table.h
+++ b/storage/perfschema/table_tlws_by_table.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_users.cc b/storage/perfschema/table_users.cc
index 6d6bfc5bfaf..883ebd36633 100644
--- a/storage/perfschema/table_users.cc
+++ b/storage/perfschema/table_users.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_users.h b/storage/perfschema/table_users.h
index 1b24dfb9039..912f0f43714 100644
--- a/storage/perfschema/table_users.h
+++ b/storage/perfschema/table_users.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/CMakeLists.txt b/storage/perfschema/unittest/CMakeLists.txt
index b449640b374..7b8c906a4e6 100644
--- a/storage/perfschema/unittest/CMakeLists.txt
+++ b/storage/perfschema/unittest/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/conf.txt b/storage/perfschema/unittest/conf.txt
index 8a14b9ed14b..f84ba3317b1 100644
--- a/storage/perfschema/unittest/conf.txt
+++ b/storage/perfschema/unittest/conf.txt
@@ -1,13 +1,20 @@
# Copyright (c) 2009, 2010, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs-t.cc b/storage/perfschema/unittest/pfs-t.cc
index e2ff73699ec..6e46d772380 100644
--- a/storage/perfschema/unittest/pfs-t.cc
+++ b/storage/perfschema/unittest/pfs-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_account-oom-t.cc b/storage/perfschema/unittest/pfs_account-oom-t.cc
index 71c089ab0f5..1ca66445e0c 100644
--- a/storage/perfschema/unittest/pfs_account-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_account-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_connect_attr-t.cc b/storage/perfschema/unittest/pfs_connect_attr-t.cc
index 3dd62ca5662..7ebfb0c8294 100644
--- a/storage/perfschema/unittest/pfs_connect_attr-t.cc
+++ b/storage/perfschema/unittest/pfs_connect_attr-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_host-oom-t.cc b/storage/perfschema/unittest/pfs_host-oom-t.cc
index e2eba7e6aff..14af1af0352 100644
--- a/storage/perfschema/unittest/pfs_host-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_host-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_instr-oom-t.cc b/storage/perfschema/unittest/pfs_instr-oom-t.cc
index a18902dc3db..231fd1e100b 100644
--- a/storage/perfschema/unittest/pfs_instr-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_instr-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_instr-t.cc b/storage/perfschema/unittest/pfs_instr-t.cc
index 47a91d9bb9a..c9f4bac1171 100644
--- a/storage/perfschema/unittest/pfs_instr-t.cc
+++ b/storage/perfschema/unittest/pfs_instr-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc
index bdb2648c2f3..7eb21a33bd7 100644
--- a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_instr_class-t.cc b/storage/perfschema/unittest/pfs_instr_class-t.cc
index 0d8ec38525d..f1e246dc387 100644
--- a/storage/perfschema/unittest/pfs_instr_class-t.cc
+++ b/storage/perfschema/unittest/pfs_instr_class-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_misc-t.cc b/storage/perfschema/unittest/pfs_misc-t.cc
index c308cf4b82d..7d274c0820d 100644
--- a/storage/perfschema/unittest/pfs_misc-t.cc
+++ b/storage/perfschema/unittest/pfs_misc-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_server_stubs.cc b/storage/perfschema/unittest/pfs_server_stubs.cc
index 3c4b864d742..db1600faf9f 100644
--- a/storage/perfschema/unittest/pfs_server_stubs.cc
+++ b/storage/perfschema/unittest/pfs_server_stubs.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/unittest/pfs_timer-t.cc b/storage/perfschema/unittest/pfs_timer-t.cc
index 9ef111f531c..139454b8649 100644
--- a/storage/perfschema/unittest/pfs_timer-t.cc
+++ b/storage/perfschema/unittest/pfs_timer-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_user-oom-t.cc b/storage/perfschema/unittest/pfs_user-oom-t.cc
index 6e81df8d5e2..ca451f3e457 100644
--- a/storage/perfschema/unittest/pfs_user-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_user-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/stub_pfs_defaults.h b/storage/perfschema/unittest/stub_pfs_defaults.h
index 6b4ee3f0e15..951508733e2 100644
--- a/storage/perfschema/unittest/stub_pfs_defaults.h
+++ b/storage/perfschema/unittest/stub_pfs_defaults.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/unittest/stub_pfs_global.h b/storage/perfschema/unittest/stub_pfs_global.h
index a665ed39704..8a1f9216ba2 100644
--- a/storage/perfschema/unittest/stub_pfs_global.h
+++ b/storage/perfschema/unittest/stub_pfs_global.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/stub_print_error.h b/storage/perfschema/unittest/stub_print_error.h
index 476a6c0e901..2cd2ad5b03c 100644
--- a/storage/perfschema/unittest/stub_print_error.h
+++ b/storage/perfschema/unittest/stub_print_error.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index fa564a603e6..f9384848243 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -54,6 +54,9 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
SKIP_ROCKSDB_PLUGIN("${OLD_COMPILER_MSG}")
ENDIF()
SET(CXX11_FLAGS "-std=c++11")
+ IF (GCC_VERSION VERSION_LESS 5.0)
+ SET(CXX11_FLAGS "-std=c++11 -Wno-missing-field-initializers")
+ ENDIF()
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
IF ((CMAKE_CXX_COMPILER_VERSION AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.3) OR
(CLANG_VERSION_STRING AND CLANG_VERSION_STRING VERSION_LESS 3.3))
@@ -108,9 +111,15 @@ SET(ROCKSDB_SE_SOURCES
# This is a strong requirement coming from RocksDB. No conditional checks here.
#ADD_DEFINITIONS(-DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX
#)
+if(CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
+ SET(ATOMIC_EXTRA_LIBS -latomic)
+else()
+ SET(ATOMIC_EXTRA_LIBS)
+endif()
MYSQL_ADD_PLUGIN(rocksdb ${ROCKSDB_SE_SOURCES} MODULE_ONLY STORAGE_ENGINE
MODULE_OUTPUT_NAME ha_rocksdb
+ LINK_LIBRARIES ${ATOMIC_EXTRA_LIBS}
COMPONENT rocksdb-engine)
IF(NOT TARGET rocksdb)
@@ -161,6 +170,7 @@ TARGET_LINK_LIBRARIES(rocksdb_aux_lib rocksdblib ${ZLIB_LIBRARY})
if (UNIX AND NOT APPLE)
TARGET_LINK_LIBRARIES(rocksdb_aux_lib -lrt)
endif()
+TARGET_LINK_LIBRARIES(rocksdb_aux_lib ${ATOMIC_EXTRA_LIBS})
# IF (WITH_JEMALLOC)
# FIND_LIBRARY(JEMALLOC_LIBRARY
@@ -253,7 +263,7 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/myrocks_hotbackup.py
INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/myrocks_hotbackup COMPONENT rocksdb-engine)
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- SET_TARGET_PROPERTIES(rocksdb_tools sst_dump mysql_ldb PROPERTIES COMPILE_FLAGS -frtti)
+ SET_TARGET_PROPERTIES(rocksdb_tools sst_dump mysql_ldb PROPERTIES COMPILE_FLAGS "-frtti -Wno-error")
ENDIF()
IF(MSVC)
# RocksDB, the storage engine, overdoes "const" by adding
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index ac1307f1037..883ee15f74c 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -18,25 +18,24 @@ if(WIN32)
# include(${ROCKSDB_SOURCE_DIR}/thirdparty.inc)
else()
option(WITH_ROCKSDB_JEMALLOC "build RocksDB with JeMalloc" OFF)
- if(WITH_ROCKSDB_JEMALLOC)
- find_package(JeMalloc REQUIRED)
- add_definitions(-DROCKSDB_JEMALLOC)
- ADD_DEFINITIONS(-DROCKSDB_MALLOC_USABLE_SIZE)
- include_directories(${JEMALLOC_INCLUDE_DIR})
- endif()
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
# FreeBSD has jemaloc as default malloc
add_definitions(-DROCKSDB_JEMALLOC)
ADD_DEFINITIONS(-DROCKSDB_MALLOC_USABLE_SIZE)
set(WITH_JEMALLOC ON)
+ elseif(WITH_ROCKSDB_JEMALLOC)
+ find_package(JeMalloc REQUIRED)
+ add_definitions(-DROCKSDB_JEMALLOC)
+ ADD_DEFINITIONS(-DROCKSDB_MALLOC_USABLE_SIZE)
+ include_directories(${JEMALLOC_INCLUDE_DIR})
endif()
endif()
# Optional compression libraries.
-foreach(compression_lib LZ4 BZIP2 ZSTD snappy)
- FIND_PACKAGE(${compression_lib} QUIET)
+foreach(compression_lib LZ4 BZip2 ZSTD snappy)
+ FIND_PACKAGE(${compression_lib})
SET(WITH_ROCKSDB_${compression_lib} AUTO CACHE STRING
"Build RocksDB with ${compression_lib} compression. Possible values are 'ON', 'OFF', 'AUTO' and default is 'AUTO'")
@@ -54,16 +53,16 @@ if(LZ4_FOUND AND (NOT WITH_ROCKSDB_LZ4 STREQUAL "OFF"))
list(APPEND THIRDPARTY_LIBS ${LZ4_LIBRARY})
endif()
-if(BZIP2_FOUND AND (NOT WITH_ROCKSDB_BZIP2 STREQUAL "OFF"))
+if(BZIP2_FOUND AND (NOT WITH_ROCKSDB_BZip2 STREQUAL "OFF"))
add_definitions(-DBZIP2)
include_directories(${BZIP2_INCLUDE_DIR})
list(APPEND THIRDPARTY_LIBS ${BZIP2_LIBRARIES})
endif()
-if(SNAPPY_FOUND AND (NOT WITH_ROCKSDB_SNAPPY STREQUAL "OFF"))
+if(SNAPPY_FOUND AND (NOT WITH_ROCKSDB_snappy STREQUAL "OFF"))
add_definitions(-DSNAPPY)
- include_directories(${SNAPPY_INCLUDE_DIR})
- list(APPEND THIRDPARTY_LIBS ${SNAPPY_LIBRARIES})
+ include_directories(${snappy_INCLUDE_DIR})
+ list(APPEND THIRDPARTY_LIBS ${snappy_LIBRARIES})
endif()
include(CheckFunctionExists)
@@ -132,6 +131,10 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64")
ADD_DEFINITIONS(-DHAVE_POWER8 -DHAS_ALTIVEC)
endif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64")
+if(CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
+ set(SYSTEM_LIBS ${SYSTEM_LIBS} -latomic)
+endif()
+
option(WITH_FALLOCATE "build with fallocate" ON)
if(WITH_FALLOCATE AND UNIX)
@@ -189,31 +192,32 @@ set(ROCKSDB_SOURCES
cache/clock_cache.cc
cache/lru_cache.cc
cache/sharded_cache.cc
+ db/arena_wrapped_db_iter.cc
db/builder.cc
db/c.cc
db/column_family.cc
db/compacted_db_impl.cc
db/compaction/compaction.cc
db/compaction/compaction_iterator.cc
- db/compaction/compaction_job.cc
db/compaction/compaction_picker.cc
+ db/compaction/compaction_job.cc
db/compaction/compaction_picker_fifo.cc
db/compaction/compaction_picker_level.cc
db/compaction/compaction_picker_universal.cc
db/convenience.cc
db/db_filesnapshot.cc
- db/dbformat.cc
db/db_impl/db_impl.cc
+ db/db_impl/db_impl_write.cc
db/db_impl/db_impl_compaction_flush.cc
- db/db_impl/db_impl_debug.cc
- db/db_impl/db_impl_experimental.cc
db/db_impl/db_impl_files.cc
db/db_impl/db_impl_open.cc
+ db/db_impl/db_impl_debug.cc
+ db/db_impl/db_impl_experimental.cc
db/db_impl/db_impl_readonly.cc
db/db_impl/db_impl_secondary.cc
- db/db_impl/db_impl_write.cc
db/db_info_dumper.cc
db/db_iter.cc
+ db/dbformat.cc
db/error_handler.cc
db/event_helpers.cc
db/experimental.cc
@@ -222,9 +226,10 @@ set(ROCKSDB_SOURCES
db/flush_job.cc
db/flush_scheduler.cc
db/forward_iterator.cc
+ db/import_column_family_job.cc
db/internal_stats.cc
- db/log_reader.cc
db/logs_with_prep_tracker.cc
+ db/log_reader.cc
db/log_writer.cc
db/malloc_stats.cc
db/memtable.cc
@@ -238,22 +243,31 @@ set(ROCKSDB_SOURCES
db/table_cache.cc
db/table_properties_collector.cc
db/transaction_log_impl.cc
+ db/trim_history_scheduler.cc
db/version_builder.cc
db/version_edit.cc
db/version_set.cc
db/wal_manager.cc
- db/write_batch_base.cc
db/write_batch.cc
+ db/write_batch_base.cc
db/write_controller.cc
db/write_thread.cc
env/env.cc
env/env_chroot.cc
+ env/env_encryption.cc
env/env_hdfs.cc
+ env/file_system.cc
env/mock_env.cc
file/delete_scheduler.cc
- file/filename.cc
+ file/file_prefetch_buffer.cc
file/file_util.cc
+ file/filename.cc
+ file/random_access_file_reader.cc
+ file/read_write_util.cc
+ file/readahead_raf.cc
+ file/sequence_file_reader.cc
file/sst_file_manager_impl.cc
+ file/writable_file_writer.cc
logging/auto_roll_logger.cc
logging/event_logger.cc
logging/log_buffer.cc
@@ -268,8 +282,8 @@ set(ROCKSDB_SOURCES
memtable/write_buffer_manager.cc
monitoring/histogram.cc
monitoring/histogram_windowing.cc
- monitoring/instrumented_mutex.cc
monitoring/in_memory_stats_history.cc
+ monitoring/instrumented_mutex.cc
monitoring/iostats_context.cc
monitoring/perf_context.cc
monitoring/perf_level.cc
@@ -277,7 +291,6 @@ set(ROCKSDB_SOURCES
monitoring/statistics.cc
monitoring/thread_status_impl.cc
monitoring/thread_status_updater.cc
- monitoring/thread_status_updater_debug.cc
monitoring/thread_status_util.cc
monitoring/thread_status_util_debug.cc
options/cf_options.cc
@@ -288,21 +301,24 @@ set(ROCKSDB_SOURCES
options/options_sanity_check.cc
port/stack_trace.cc
table/adaptive/adaptive_table_factory.cc
+ table/block_based/block.cc
table/block_based/block_based_filter_block.cc
table/block_based/block_based_table_builder.cc
table/block_based/block_based_table_factory.cc
table/block_based/block_based_table_reader.cc
table/block_based/block_builder.cc
- table/block_based/block.cc
table/block_based/block_prefix_index.cc
- table/block_based/data_block_footer.cc
table/block_based/data_block_hash_index.cc
+ table/block_based/data_block_footer.cc
+ table/block_based/filter_block_reader_common.cc
+ table/block_based/filter_policy.cc
table/block_based/flush_block_policy.cc
table/block_based/full_filter_block.cc
table/block_based/index_builder.cc
+ table/block_based/parsed_full_filter_block.cc
table/block_based/partitioned_filter_block.cc
+ table/block_based/uncompression_dict_reader.cc
table/block_fetcher.cc
- table/bloom_block.cc
table/cuckoo/cuckoo_table_builder.cc
table/cuckoo/cuckoo_table_factory.cc
table/cuckoo/cuckoo_table_reader.cc
@@ -312,6 +328,7 @@ set(ROCKSDB_SOURCES
table/merging_iterator.cc
table/meta_blocks.cc
table/persistent_cache_helper.cc
+ table/plain/plain_table_bloom.cc
table/plain/plain_table_builder.cc
table/plain/plain_table_factory.cc
table/plain/plain_table_index.cc
@@ -323,23 +340,34 @@ set(ROCKSDB_SOURCES
table/two_level_iterator.cc
test_util/sync_point.cc
test_util/sync_point_impl.cc
+ test_util/testutil.cc
+ test_util/transaction_test_util.cc
+ tools/block_cache_analyzer/block_cache_trace_analyzer.cc
+ tools/dump/db_dump_tool.cc
tools/ldb_cmd.cc
tools/ldb_tool.cc
tools/sst_dump_tool.cc
- trace_replay/block_cache_tracer.cc
+ tools/trace_analyzer_tool.cc
trace_replay/trace_replay.cc
- util/bloom.cc
+ trace_replay/block_cache_tracer.cc
util/coding.cc
util/compaction_job_stats_impl.cc
util/comparator.cc
util/compression_context_cache.cc
util/concurrent_task_limiter_impl.cc
- util/crc32c_arm64.cc
util/crc32c.cc
util/dynamic_bloom.cc
- util/file_reader_writer.cc
- util/filter_policy.cc
util/hash.cc
+ util/murmurhash.cc
+ util/random.cc
+ util/rate_limiter.cc
+ util/slice.cc
+ util/file_checksum_helper.cc
+ util/status.cc
+ util/string_util.cc
+ util/thread_local.cc
+ util/threadpool_imp.cc
+ util/xxhash.cc
utilities/backupable/backupable_db.cc
utilities/blob_db/blob_compaction_filter.cc
utilities/blob_db/blob_db.cc
@@ -347,12 +375,11 @@ set(ROCKSDB_SOURCES
utilities/blob_db/blob_db_impl_filesnapshot.cc
utilities/blob_db/blob_dump_tool.cc
utilities/blob_db/blob_file.cc
- utilities/blob_db/blob_log_format.cc
utilities/blob_db/blob_log_reader.cc
utilities/blob_db/blob_log_writer.cc
+ utilities/blob_db/blob_log_format.cc
utilities/checkpoint/checkpoint_impl.cc
utilities/compaction_filters/remove_emptyvalue_compactionfilter.cc
- utilities/convenience/info_log_finder.cc
utilities/debug.cc
utilities/env_mirror.cc
utilities/env_timed.cc
@@ -361,9 +388,11 @@ set(ROCKSDB_SOURCES
utilities/merge_operators/bytesxor.cc
utilities/merge_operators/max.cc
utilities/merge_operators/put.cc
- utilities/merge_operators/string_append/stringappend2.cc
+ utilities/merge_operators/sortlist.cc
utilities/merge_operators/string_append/stringappend.cc
+ utilities/merge_operators/string_append/stringappend2.cc
utilities/merge_operators/uint64add.cc
+ utilities/object_registry.cc
utilities/option_change_migration/option_change_migration.cc
utilities/options/options_util.cc
utilities/persistent_cache/block_cache_tier.cc
@@ -371,11 +400,12 @@ set(ROCKSDB_SOURCES
utilities/persistent_cache/block_cache_tier_metadata.cc
utilities/persistent_cache/persistent_cache_tier.cc
utilities/persistent_cache/volatile_tier_impl.cc
+ utilities/simulator_cache/cache_simulator.cc
utilities/simulator_cache/sim_cache.cc
utilities/table_properties_collectors/compact_on_deletion_collector.cc
utilities/trace/file_trace_reader_writer.cc
- utilities/transactions/optimistic_transaction.cc
utilities/transactions/optimistic_transaction_db_impl.cc
+ utilities/transactions/optimistic_transaction.cc
utilities/transactions/pessimistic_transaction.cc
utilities/transactions/pessimistic_transaction_db.cc
utilities/transactions/snapshot_checker.cc
@@ -390,15 +420,6 @@ set(ROCKSDB_SOURCES
utilities/ttl/db_ttl_impl.cc
utilities/write_batch_with_index/write_batch_with_index.cc
utilities/write_batch_with_index/write_batch_with_index_internal.cc
- util/murmurhash.cc
- util/random.cc
- util/rate_limiter.cc
- util/slice.cc
- util/status.cc
- util/string_util.cc
- util/thread_local.cc
- util/threadpool_imp.cc
- util/xxhash.cc
)
@@ -415,7 +436,8 @@ else()
list(APPEND ROCKSDB_SOURCES
port/port_posix.cc
env/env_posix.cc
- env/io_posix.cc)
+ env/io_posix.cc
+ env/fs_posix.cc)
# ppc64 or ppc64le
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64")
enable_language(ASM)
@@ -423,6 +445,17 @@ else()
util/crc32c_ppc.c
util/crc32c_ppc_asm.S)
endif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64")
+ # aarch
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64")
+ INCLUDE(CheckCXXCompilerFlag)
+ CHECK_CXX_COMPILER_FLAG("-march=armv8-a+crc+crypto" HAS_ARMV8_CRC)
+ if(HAS_ARMV8_CRC)
+ message(STATUS " HAS_ARMV8_CRC yes")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crc+crypto -Wno-unused-function")
+ list(APPEND ROCKSDB_SOURCES
+ util/crc32c_arm64.cc)
+ endif(HAS_ARMV8_CRC)
+ endif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64")
endif()
SET(SOURCES)
FOREACH(s ${ROCKSDB_SOURCES})
@@ -471,6 +504,6 @@ list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/build_version.cc)
ADD_CONVENIENCE_LIBRARY(rocksdblib ${SOURCES})
target_link_libraries(rocksdblib ${THIRDPARTY_LIBS} ${SYSTEM_LIBS})
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- set_target_properties(rocksdblib PROPERTIES COMPILE_FLAGS "-fPIC -fno-builtin-memcmp -frtti")
+ set_target_properties(rocksdblib PROPERTIES COMPILE_FLAGS "-fPIC -fno-builtin-memcmp -frtti -Wno-error")
endif()
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index bf9183d7dea..5cbe4c162a8 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -114,7 +114,6 @@ int thd_binlog_format(const MYSQL_THD thd);
bool thd_binlog_filter_ok(const MYSQL_THD thd);
}
-MYSQL_PLUGIN_IMPORT bool my_disable_leak_check;
extern my_bool opt_core_file;
// Needed in rocksdb_init_func
@@ -5688,13 +5687,6 @@ static int rocksdb_init_func(void *const p) {
}
#endif
- /**
- Rocksdb does not always shutdown its threads, when
- plugin is shut down. Disable server's leak check
- at exit to avoid crash.
- */
- my_disable_leak_check = true;
-
err = my_error_register(rdb_get_error_messages, HA_ERR_ROCKSDB_FIRST,
HA_ERR_ROCKSDB_LAST);
if (err != 0) {
diff --git a/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc b/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc
index 4250b368b1a..81cd2200ae0 100644
--- a/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc
@@ -15,7 +15,7 @@ if ($rpl_inited)
# Send shutdown to the connected server and give
# it 10 seconds to die before zapping it
-shutdown_server 10;
+shutdown_server;
# Write file to make mysql-test-run.pl start up the server again
--exec echo "restart:$_mysqld_option" > $_expect_file_name
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
index c8c12626139..15a7d319c04 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
@@ -41,7 +41,7 @@ perl;
EOF
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
---shutdown_server 10
+--shutdown_server
--error 1
--exec $MYSQLD_CMD --plugin_load=$HA_ROCKSDB_SO --rocksdb_ignore_unknown_options=0 --log-error=$error_log
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/concurrent_alter.test b/storage/rocksdb/mysql-test/rocksdb/t/concurrent_alter.test
index 3ebdd67a1a6..aee653830e2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/concurrent_alter.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/concurrent_alter.test
@@ -30,7 +30,7 @@ $MYSQL_SLAP --silent --delimiter=";" --query="select * from a1 where b=1" --conc
wait
EOF
---exec bash $MYSQL_TMP_DIR/concurrent_alter.sh
+--exec sh $MYSQL_TMP_DIR/concurrent_alter.sh
let $server_charset=`select @@character_set_server`;
--replace_result $server_charset DEFAULT_CHARSET
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
index 46ea7f0eb0a..a24851d9d8c 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
@@ -8,7 +8,7 @@ DROP TABLE IF EXISTS t1;
# reload with load optimized config
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--rocksdb_write_disable_wal=1 --rocksdb_flush_log_at_trx_commit=0 --rocksdb_default_cf_options=write_buffer_size=16k;target_file_size_base=16k;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=256;level0_stop_writes_trigger=256;max_write_buffer_number=16;compression_per_level=kNoCompression;memtable=vector:1024 --rocksdb_override_cf_options=__system__={memtable=skip_list:16} --rocksdb_compaction_sequential_deletes=0 --rocksdb_compaction_sequential_deletes_window=0 --rocksdb_allow_concurrent_memtable_write=0" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
@@ -39,7 +39,7 @@ select count(*), sum(id), sum(i1), sum(i2) from t1;
# reload without load optimized config
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--rocksdb_write_disable_wal=0 --rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test b/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test
index ca9eb5d2ecf..4f4f5ed092b 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test
@@ -21,7 +21,7 @@ optimize table t1;
#wiping block cache
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;disable_auto_compactions=true;level0_stop_writes_trigger=1000 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test
index 7a8f4fc7085..50df3f9c102 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test
@@ -32,7 +32,7 @@ while ($t <= 6) {
# Disable auto compaction so that effects of optimize table are stable
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;disable_auto_compactions=true;level0_stop_writes_trigger=1000 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test b/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test
index 03d1d0a60bc..49e5e5c1172 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test
@@ -10,7 +10,7 @@ DROP TABLE IF EXISTS t1;
--exec echo "wait" >$_expect_file_name
# restart server with correct parameters
-shutdown_server 10;
+shutdown_server;
--exec echo "restart:--rocksdb_persistent_cache_path=$_cache_file_name --rocksdb_persistent_cache_size_mb=100" >$_expect_file_name
--sleep 5
--enable_reconnect
@@ -28,7 +28,7 @@ select * from t1 where a = 1;
# restart server to re-read cache
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
--exec echo "restart:--rocksdb_persistent_cache_path=$_cache_file_name --rocksdb_persistent_cache_size_mb=100" >$_expect_file_name
--sleep 5
--enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test b/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test
index ba625deb514..f76bc9f6153 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test
@@ -23,7 +23,7 @@ while ($i <= $max) {
# Restart the server
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
index ec48dc03ec8..e7ab37d2658 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
@@ -25,7 +25,7 @@ CREATE TABLE t2 (pk int primary key) ENGINE=ROCKSDB PARTITION BY KEY(pk) PARTITI
# Send shutdown to the connected server and give it 10 seconds to die before
# zapping it
-shutdown_server 10;
+shutdown_server;
# Write file to make mysql-test-run.pl start up the server again
--exec echo "restart" >$_expect_file_name
@@ -42,7 +42,7 @@ shutdown_server 10;
# Now shut down again and rename one of the .frm files
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
# Rename the file
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm.tmp
@@ -70,7 +70,7 @@ shutdown_server 10;
# Now shut down again and rename one the .frm file back and make a copy of it
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
--remove_file $LOG
# Rename the file
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm.tmp $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm
@@ -92,7 +92,7 @@ shutdown_server 10;
# Shut down an clean up
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
--remove_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1_dummy.frm
--exec echo "restart" >$_expect_file_name
--enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_compaction_readahead_size_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_compaction_readahead_size_basic.result
index d971396f9e8..206cfa8188e 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_compaction_readahead_size_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_compaction_readahead_size_basic.result
@@ -7,7 +7,7 @@ INSERT INTO invalid_values VALUES('\'aaa\'');
INSERT INTO invalid_values VALUES('\'bbb\'');
SET @@global.rocksdb_compaction_readahead_size = -1;
Warnings:
-Warning 1292 Truncated incorrect rocksdb_compaction_readahead_siz value: '-1'
+Warning 1292 Truncated incorrect rocksdb_compaction_readahead_... value: '-1'
SELECT @@global.rocksdb_compaction_readahead_size;
@@global.rocksdb_compaction_readahead_size
0
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_force_index_records_in_range_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_force_index_records_in_range_basic.result
index 1a7a21c3a9f..d4768cfde1e 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_force_index_records_in_range_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_force_index_records_in_range_basic.result
@@ -7,7 +7,7 @@ INSERT INTO invalid_values VALUES('\'aaa\'');
INSERT INTO invalid_values VALUES('\'bbb\'');
SET @@session.rocksdb_force_index_records_in_range = -1;
Warnings:
-Warning 1292 Truncated incorrect rocksdb_force_index_records_in_r value: '-1'
+Warning 1292 Truncated incorrect rocksdb_force_index_records_i... value: '-1'
SELECT @@session.rocksdb_force_index_records_in_range;
@@session.rocksdb_force_index_records_in_range
0
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_rate_limiter_bytes_per_sec_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_rate_limiter_bytes_per_sec_basic.result
index 94eb9e34057..9d194ad718c 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_rate_limiter_bytes_per_sec_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_rate_limiter_bytes_per_sec_basic.result
@@ -97,5 +97,5 @@ Warnings:
Warning 1210 RocksDB: rocksdb_rate_limiter_bytes_per_sec cannot be dynamically changed to or from 0. Do a clean shutdown if you want to change it from or to 0.
SET @@global.rocksdb_rate_limiter_bytes_per_sec = -1;
Warnings:
-Warning 1292 Truncated incorrect rocksdb_rate_limiter_bytes_per_s value: '-1'
+Warning 1292 Truncated incorrect rocksdb_rate_limiter_bytes_pe... value: '-1'
Warning 1210 RocksDB: rocksdb_rate_limiter_bytes_per_sec cannot be dynamically changed to or from 0. Do a clean shutdown if you want to change it from or to 0.
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test
index 8277011831a..743f942af9c 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test
@@ -13,7 +13,7 @@ SET @@global.rocksdb_rate_limiter_bytes_per_sec = 10000;
# Send shutdown to the connected server and give it 10 seconds to die before
# zapping it
-shutdown_server 10;
+shutdown_server;
# Attempt to restart the server with the rate limiter on
--exec echo "restart:--rocksdb_rate_limiter_bytes_per_sec=10000" >$_expect_file_name
@@ -53,7 +53,7 @@ SET @@global.rocksdb_rate_limiter_bytes_per_sec = -1;
# Restart the server without the rate limiter
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
--exec echo "restart" >$_expect_file_name
--sleep 5
diff --git a/storage/rocksdb/rdb_sst_info.cc b/storage/rocksdb/rdb_sst_info.cc
index 8b7886667eb..f7e944c2e39 100644
--- a/storage/rocksdb/rdb_sst_info.cc
+++ b/storage/rocksdb/rdb_sst_info.cc
@@ -507,7 +507,7 @@ void Rdb_sst_info::set_error_msg(const std::string &sst_file_name,
void Rdb_sst_info::report_error_msg(const rocksdb::Status &s,
const char *sst_file_name) {
if (s.IsInvalidArgument() &&
- strcmp(s.getState(), "Keys must be added in order") == 0) {
+ strcmp(s.getState(), "Keys must be added in strict ascending order.") == 0) {
my_printf_error(ER_KEYS_OUT_OF_ORDER,
"Rows must be inserted in primary key order "
"during bulk load operation",
diff --git a/storage/rocksdb/rocksdb b/storage/rocksdb/rocksdb
-Subproject e731f4402258554812c46334dc0d9483e6cc769
+Subproject bba5e7bc21093d7cfa765e1280a7c4fdcd28428
diff --git a/storage/rocksdb/ut0counter.h b/storage/rocksdb/ut0counter.h
index cfa474e7a99..3a7ee85d01c 100644
--- a/storage/rocksdb/ut0counter.h
+++ b/storage/rocksdb/ut0counter.h
@@ -23,7 +23,7 @@ Created 2012/04/12 by Sunny Bains
#include <string.h>
/** CPU cache line size */
-#define CACHE_LINE_SIZE 64
+#define UT_CACHE_LINE_SIZE 64
/** Default number of slots to use in ib_counter_t */
#define IB_N_SLOTS 64
@@ -43,7 +43,7 @@ struct generic_indexer_t {
/** @return offset within m_counter */
size_t offset(size_t index) const {
- return(((index % N) + 1) * (CACHE_LINE_SIZE / sizeof(Type)));
+ return(((index % N) + 1) * (UT_CACHE_LINE_SIZE / sizeof(Type)));
}
};
@@ -90,7 +90,7 @@ struct single_indexer_t {
/** @return offset within m_counter */
size_t offset(size_t index) const {
DBUG_ASSERT(N == 1);
- return((CACHE_LINE_SIZE / sizeof(Type)));
+ return((UT_CACHE_LINE_SIZE / sizeof(Type)));
}
/* @return 1 */
@@ -103,7 +103,7 @@ struct single_indexer_t {
/** Class for using fuzzy counters. The counter is not protected by any
mutex and the results are not guaranteed to be 100% accurate but close
enough. Creates an array of counters and separates each element by the
-CACHE_LINE_SIZE bytes */
+UT_CACHE_LINE_SIZE bytes */
template <
typename Type,
int N = IB_N_SLOTS,
@@ -119,7 +119,7 @@ public:
bool validate() {
#ifdef UNIV_DEBUG
- size_t n = (CACHE_LINE_SIZE / sizeof(Type));
+ size_t n = (UT_CACHE_LINE_SIZE / sizeof(Type));
/* Check that we aren't writing outside our defined bounds. */
for (size_t i = 0; i < UT_ARRAY_SIZE(m_counter); i += n) {
@@ -197,7 +197,7 @@ private:
Indexer<Type, N>m_policy;
/** Slot 0 is unused. */
- Type m_counter[(N + 1) * (CACHE_LINE_SIZE / sizeof(Type))];
+ Type m_counter[(N + 1) * (UT_CACHE_LINE_SIZE / sizeof(Type))];
};
#endif /* UT0COUNTER_H */
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index fb453ddc637..5e7b5a1e8ce 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -2258,6 +2258,7 @@ int ha_spider::index_read_map_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -2265,6 +2266,11 @@ int ha_spider::index_read_map_internal(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -2286,11 +2292,15 @@ int ha_spider::index_read_map_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -2325,6 +2335,8 @@ int ha_spider::index_read_map_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -2351,6 +2363,8 @@ int ha_spider::index_read_map_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -2750,6 +2764,7 @@ int ha_spider::index_read_last_map_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -2757,6 +2772,11 @@ int ha_spider::index_read_last_map_internal(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -2775,11 +2795,15 @@ int ha_spider::index_read_last_map_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -2814,6 +2838,8 @@ int ha_spider::index_read_last_map_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -2840,6 +2866,8 @@ int ha_spider::index_read_last_map_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -3216,6 +3244,7 @@ int ha_spider::index_first_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -3224,6 +3253,11 @@ int ha_spider::index_first_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -3242,11 +3276,15 @@ int ha_spider::index_first_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -3281,6 +3319,8 @@ int ha_spider::index_first_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -3307,6 +3347,8 @@ int ha_spider::index_first_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -3600,6 +3642,7 @@ int ha_spider::index_last_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -3608,6 +3651,11 @@ int ha_spider::index_last_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -3626,11 +3674,15 @@ int ha_spider::index_last_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -3665,6 +3717,8 @@ int ha_spider::index_last_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -3691,6 +3745,8 @@ int ha_spider::index_last_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -4044,6 +4100,7 @@ int ha_spider::read_range_first_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -4051,6 +4108,11 @@ int ha_spider::read_range_first_internal(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -4069,11 +4131,15 @@ int ha_spider::read_range_first_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4108,6 +4174,8 @@ int ha_spider::read_range_first_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4134,6 +4202,8 @@ int ha_spider::read_range_first_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -4670,6 +4740,7 @@ int ha_spider::read_multi_range_first_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -4678,6 +4749,11 @@ int ha_spider::read_multi_range_first_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -4702,11 +4778,15 @@ int ha_spider::read_multi_range_first_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4742,6 +4822,8 @@ int ha_spider::read_multi_range_first_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4770,6 +4852,8 @@ int ha_spider::read_multi_range_first_internal(
if (!error_num)
{
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -5463,6 +5547,7 @@ int ha_spider::read_multi_range_first_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -5471,6 +5556,11 @@ int ha_spider::read_multi_range_first_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -5496,11 +5586,15 @@ int ha_spider::read_multi_range_first_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5542,6 +5636,8 @@ int ha_spider::read_multi_range_first_internal(
-1,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -5577,6 +5673,8 @@ int ha_spider::read_multi_range_first_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -5603,6 +5701,8 @@ int ha_spider::read_multi_range_first_internal(
break;
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -6110,6 +6210,7 @@ int ha_spider::read_multi_range_next(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -6118,6 +6219,11 @@ int ha_spider::read_multi_range_next(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -6142,11 +6248,15 @@ int ha_spider::read_multi_range_next(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6182,6 +6292,8 @@ int ha_spider::read_multi_range_next(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -6210,6 +6322,8 @@ int ha_spider::read_multi_range_next(
if (!error_num)
{
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -6907,6 +7021,7 @@ int ha_spider::read_multi_range_next(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -6915,6 +7030,11 @@ int ha_spider::read_multi_range_next(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -6940,11 +7060,15 @@ int ha_spider::read_multi_range_next(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6986,6 +7110,8 @@ int ha_spider::read_multi_range_next(
-1,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7021,6 +7147,8 @@ int ha_spider::read_multi_range_next(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7047,6 +7175,8 @@ int ha_spider::read_multi_range_next(
break;
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -7524,6 +7654,7 @@ int ha_spider::rnd_next_internal(
sql_type = SPIDER_SQL_TYPE_HANDLER;
}
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -7532,6 +7663,11 @@ int ha_spider::rnd_next_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -7541,11 +7677,15 @@ int ha_spider::rnd_next_internal(
}
DBUG_PRINT("info",("spider sql_type=%lu", sql_type));
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7580,6 +7720,8 @@ int ha_spider::rnd_next_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7606,6 +7748,8 @@ int ha_spider::rnd_next_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -8116,6 +8260,7 @@ int ha_spider::ft_read_internal(
uint dbton_id = share->use_sql_dbton_ids[roop_count];
spider_db_handler *dbton_hdl = dbton_handler[dbton_id];
SPIDER_CONN *conn = conns[roop_count];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_SELECT_SQL))
{
@@ -8125,6 +8270,12 @@ int ha_spider::ft_read_internal(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_SELECT_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_SELECT_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -8134,10 +8285,14 @@ int ha_spider::ft_read_internal(
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -8171,6 +8326,8 @@ int ha_spider::ft_read_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -8197,6 +8354,8 @@ int ha_spider::ft_read_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -10455,9 +10614,12 @@ void ha_spider::bulk_req_exec()
if (conn->bulk_access_requests)
{
spider_bg_conn_wait(conn);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
/* currently only used for HS */
@@ -10475,6 +10637,8 @@ void ha_spider::bulk_req_exec()
conn->bulk_access_sended += conn->bulk_access_requests;
*/
conn->bulk_access_requests = 0;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -12217,6 +12381,7 @@ int ha_spider::drop_tmp_tables()
uint dbton_id = share->use_sql_dbton_ids[roop_count];
spider_db_handler *dbton_hdl = dbton_handler[dbton_id];
SPIDER_CONN *conn = conns[roop_count];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_TMP_SQL))
{
@@ -12226,6 +12391,12 @@ int ha_spider::drop_tmp_tables()
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_TMP_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_TMP_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -12235,10 +12406,14 @@ int ha_spider::drop_tmp_tables()
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((tmp_error_num = spider_db_set_names(this, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -12275,6 +12450,8 @@ int ha_spider::drop_tmp_tables()
-1,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
tmp_error_num = spider_db_errorno(conn);
@@ -12300,6 +12477,8 @@ int ha_spider::drop_tmp_tables()
}
error_num = tmp_error_num;
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
diff --git a/storage/spider/mysql-test/spider/r/pushdown_not_like.result b/storage/spider/mysql-test/spider/r/pushdown_not_like.result
new file mode 100644
index 00000000000..cd926962180
--- /dev/null
+++ b/storage/spider/mysql-test/spider/r/pushdown_not_like.result
@@ -0,0 +1,63 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+drop and create databases
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+
+create table select test
+connection master_1;
+DROP TABLE IF EXISTS ta_l;
+CREATE TABLE ta_l (
+a INT,
+b CHAR(1),
+c DATETIME,
+PRIMARY KEY(a)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
+INSERT INTO ta_l (a, b, c) VALUES
+(1, 'a', '2018-11-01 10:21:39'),
+(2, 'b', '2015-06-30 23:59:59'),
+(3, 'c', '2013-11-01 01:01:01');
+
+spider not like bug fix test
+connection master_1;
+select * from ta_l where b not like 'a%';
+a b c
+2 b 2015-06-30 23:59:59
+3 c 2013-11-01 01:01:01
+connection child2_1;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select%';
+argument
+select `a`,`b`,`c` from `auto_test_remote`.`ta_r` where (`b` not like 'a%')
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select%'
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/t/pushdown_not_like.test b/storage/spider/mysql-test/spider/t/pushdown_not_like.test
new file mode 100644
index 00000000000..95e4fa6eea8
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/pushdown_not_like.test
@@ -0,0 +1,138 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source test_init.inc
+--enable_result_log
+--enable_query_log
+
+
+--echo
+--echo drop and create databases
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ DROP DATABASE IF EXISTS auto_test_remote;
+ CREATE DATABASE auto_test_remote;
+ USE auto_test_remote;
+}
+--enable_warnings
+
+
+--echo
+--echo create table select test
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_1_DROP_TABLES;
+ echo CHILD2_1_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_1_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_1_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ TRUNCATE TABLE mysql.general_log;
+ set global log_output = 'TABLE';
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--connection master_1
+--disable_warnings
+DROP TABLE IF EXISTS ta_l;
+--enable_warnings
+--disable_query_log
+echo CREATE TABLE ta_l (
+ a INT,
+ b CHAR(1),
+ c DATETIME,
+ PRIMARY KEY(a)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
+eval CREATE TABLE ta_l (
+ a INT,
+ b CHAR(1),
+ c DATETIME,
+ PRIMARY KEY(a)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
+--enable_query_log
+INSERT INTO ta_l (a, b, c) VALUES
+ (1, 'a', '2018-11-01 10:21:39'),
+ (2, 'b', '2015-06-30 23:59:59'),
+ (3, 'c', '2013-11-01 01:01:01');
+
+--echo
+--echo spider not like bug fix test
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--connection master_1
+select * from ta_l where b not like 'a%';
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select%';
+ }
+}
+
+
+--echo
+--echo deinit
+--disable_warnings
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ DROP DATABASE IF EXISTS auto_test_remote;
+ SET GLOBAL log_output = @old_log_output;
+}
+
+
+--disable_query_log
+--disable_result_log
+--source test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--echo
+--echo end of test
diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc
index c1c2ce07476..30296215952 100644
--- a/storage/spider/spd_conn.cc
+++ b/storage/spider/spd_conn.cc
@@ -2385,6 +2385,7 @@ void *spider_bg_conn_action(
sql_type = SPIDER_SQL_TYPE_SELECT_HS;
}
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -2414,6 +2415,8 @@ void *spider_bg_conn_action(
if (!result_list->bgs_error)
{
conn->need_mon = &spider->need_mons[conn->link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
#ifdef HA_CAN_BULK_ACCESS
@@ -2491,6 +2494,8 @@ void *spider_bg_conn_action(
#ifdef HA_CAN_BULK_ACCESS
}
#endif
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -2501,11 +2506,14 @@ void *spider_bg_conn_action(
}
} else {
spider->connection_ids[conn->link_idx] = conn->connection_id;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_unlock_later = TRUE;
result_list->bgs_error =
spider_db_store_result(spider, conn->link_idx, result_list->table);
if ((result_list->bgs_error_with_message = thd->is_error()))
strmov(result_list->bgs_error_msg, spider_stmt_da_message(thd));
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_unlock_later = FALSE;
}
conn->bg_search = FALSE;
@@ -2569,12 +2577,26 @@ void *spider_bg_conn_action(
{
DBUG_PRINT("info",("spider bg exec sql start"));
spider = (ha_spider*) conn->bg_target;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[conn->link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
*conn->bg_error_num = spider_db_query_with_set_names(
conn->bg_sql_type,
spider,
conn,
conn->link_idx
);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
conn->bg_exec_sql = FALSE;
continue;
}
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index 13ff6c568de..f77603d0d3a 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -208,23 +208,14 @@ int spider_db_ping(
DBUG_PRINT("info", ("spider thd->query_id is %lld",
spider->trx->thd->query_id));
#endif
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
if (conn->server_lost || conn->queued_connect)
{
if ((error_num = spider_db_connect(spider->share, conn,
spider->conn_link_idx[link_idx])))
{
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
conn->server_lost = FALSE;
@@ -238,11 +229,7 @@ int spider_db_ping(
{
DBUG_PRINT("info", ("spider conn=%p SERVER_LOST", conn));
conn->server_lost = TRUE;
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
if((error_num = conn->db_conn->ping()))
@@ -250,20 +237,12 @@ int spider_db_ping(
spider_db_disconnect(conn);
DBUG_PRINT("info", ("spider conn=%p SERVER_LOST", conn));
conn->server_lost = TRUE;
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
}
conn->ping_time = (time_t) time((time_t*) 0);
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(0);
}
@@ -303,6 +282,7 @@ int spider_db_conn_queue_action(
conn->queued_connect = FALSE;
}
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
@@ -551,7 +531,6 @@ int spider_db_before_query(
int *need_mon
) {
int error_num;
- bool tmp_mta_conn_mutex_lock_already;
DBUG_ENTER("spider_db_before_query");
DBUG_ASSERT(need_mon);
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -559,25 +538,18 @@ int spider_db_before_query(
spider_bg_conn_break(conn, NULL);
#endif
conn->in_before_query = TRUE;
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = need_mon;
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if ((error_num = spider_db_conn_queue_action(conn)))
{
conn->in_before_query = FALSE;
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
if (conn->server_lost)
{
conn->in_before_query = FALSE;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(CR_SERVER_GONE_ERROR);
}
DBUG_PRINT("info", ("spider conn[%p]->quick_target=%p",
@@ -604,6 +576,7 @@ int spider_db_before_query(
) {
conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
conn->in_before_query = FALSE;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
}
@@ -619,6 +592,7 @@ int spider_db_before_query(
}
}
conn->in_before_query = FALSE;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(0);
}
@@ -631,6 +605,7 @@ int spider_db_query(
) {
int error_num;
DBUG_ENTER("spider_db_query");
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
@@ -673,6 +648,7 @@ int spider_db_errorno(
int error_num;
DBUG_ENTER("spider_db_errorno");
DBUG_ASSERT(conn->need_mon);
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
@@ -687,6 +663,7 @@ int spider_db_errorno(
}
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -708,6 +685,7 @@ int spider_db_errorno(
}
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -720,6 +698,7 @@ int spider_db_errorno(
conn->error_length = strlen(conn->error_str);
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -745,6 +724,7 @@ int spider_db_errorno(
}
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -766,6 +746,7 @@ int spider_db_errorno(
}
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -782,6 +763,7 @@ int spider_db_errorno(
conn->server_lost = TRUE;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -791,6 +773,7 @@ int spider_db_errorno(
*conn->need_mon = 0;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -813,6 +796,7 @@ int spider_db_errorno(
*conn->need_mon = ER_SPIDER_HS_NUM;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -821,6 +805,7 @@ int spider_db_errorno(
#endif
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -843,33 +828,25 @@ int spider_db_set_names_internal(
int all_link_idx,
int *need_mon
) {
- bool tmp_mta_conn_mutex_lock_already;
DBUG_ENTER("spider_db_set_names_internal");
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
#endif
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = need_mon;
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
if (
!conn->access_charset ||
share->access_charset->cset != conn->access_charset->cset
) {
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if (
spider_db_before_query(conn, need_mon) ||
conn->db_conn->set_character_set(share->access_charset->csname)
) {
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
DBUG_RETURN(spider_db_errorno(conn));
}
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
conn->access_charset = share->access_charset;
}
if (
@@ -884,13 +861,10 @@ int spider_db_set_names_internal(
) {
DBUG_PRINT("info",("spider all_link_idx=%d db=%s", all_link_idx,
share->tgt_dbs[all_link_idx]));
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if (
spider_db_before_query(conn, need_mon) ||
conn->db_conn->select_db(share->tgt_dbs[all_link_idx])
) {
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
DBUG_RETURN(spider_db_errorno(conn));
}
conn->default_database.length(0);
@@ -900,12 +874,6 @@ int spider_db_set_names_internal(
conn->default_database.q_append(share->tgt_dbs[all_link_idx],
share->tgt_dbs_lengths[all_link_idx] + 1);
conn->default_database.length(share->tgt_dbs_lengths[all_link_idx]);
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- }
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
}
@@ -934,19 +902,11 @@ int spider_db_query_with_set_names(
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
DBUG_ENTER("spider_db_query_with_set_names");
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
-*/
- conn->need_mon = &spider->need_mons[link_idx];
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
if (
share->monitoring_kind[link_idx] &&
spider->need_mons[link_idx]
@@ -977,8 +937,6 @@ int spider_db_query_with_set_names(
-1,
&spider->need_mons[link_idx])
) {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
if (
share->monitoring_kind[link_idx] &&
@@ -1002,10 +960,6 @@ int spider_db_query_with_set_names(
}
DBUG_RETURN(error_num);
}
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
}
@@ -1019,15 +973,16 @@ int spider_db_query_for_bulk_update(
SPIDER_SHARE *share = spider->share;
DBUG_ENTER("spider_db_query_for_bulk_update");
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
-*/
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -1063,6 +1018,8 @@ int spider_db_query_for_bulk_update(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -1109,6 +1066,8 @@ int spider_db_query_for_bulk_update(
}
if (error_num > 0 && !conn->db_conn->is_dup_entry_error(error_num))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -1135,6 +1094,8 @@ int spider_db_query_for_bulk_update(
}
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -3644,6 +3605,7 @@ int spider_db_store_result(
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3660,6 +3622,7 @@ int spider_db_store_result(
) {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3691,6 +3654,7 @@ int spider_db_store_result(
) {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3734,6 +3698,7 @@ int spider_db_store_result(
) {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3773,6 +3738,7 @@ int spider_db_store_result(
{
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3801,6 +3767,7 @@ int spider_db_store_result(
#endif
if (!conn->mta_conn_mutex_unlock_later && !call_db_errorno)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3808,6 +3775,7 @@ int spider_db_store_result(
} else {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3851,6 +3819,7 @@ int spider_db_store_result(
result_list->limit_num -= current->prev->record_num;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3874,6 +3843,7 @@ int spider_db_store_result(
} else {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3885,6 +3855,7 @@ int spider_db_store_result(
spider->quick_targets[link_idx] = spider;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -4043,6 +4014,7 @@ int spider_db_store_result(
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -4068,6 +4040,7 @@ int spider_db_store_result(
} else {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -4078,6 +4051,7 @@ int spider_db_store_result(
result_list->hs_has_result = TRUE;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -4163,15 +4137,15 @@ int spider_db_bulk_store_result(
error_num = spider_db_bulk_open_handler(spider, conn, link_idx);
if (!discard_result)
{
- bool tmp_mta_conn_mutex_unlock_later;
- tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_unlock_later = TRUE;
if ((tmp_error_num = spider_db_store_result(spider, link_idx,
spider->get_table())))
{
error_num = tmp_error_num;
}
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
+ conn->mta_conn_mutex_unlock_later = FALSE;
} else {
if (spider->connection_ids[link_idx] == conn->connection_id)
spider_db_discard_result(spider, link_idx, conn);
@@ -4381,10 +4355,14 @@ int spider_db_seek_next(
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4420,6 +4398,8 @@ int spider_db_seek_next(
result_list->quick_mode,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4447,6 +4427,8 @@ int spider_db_seek_next(
DBUG_RETURN(error_num);
}
spider->connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -4487,6 +4469,8 @@ int spider_db_seek_next(
}
} else {
spider->connection_ids[link_idx] = conn->connection_id;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_store_result(spider, link_idx, table)))
{
@@ -4613,6 +4597,7 @@ int spider_db_seek_last(
}
conn = spider->conns[roop_count];
spider_db_handler *dbton_handler = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -4620,6 +4605,11 @@ int spider_db_seek_last(
}
if ((error_num = dbton_handler->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
@@ -4629,10 +4619,14 @@ int spider_db_seek_last(
}
DBUG_PRINT("info",("spider sql_type=%lu", sql_type));
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4667,6 +4661,8 @@ int spider_db_seek_last(
result_list->quick_mode,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4693,6 +4689,8 @@ int spider_db_seek_last(
DBUG_RETURN(error_num);
}
spider->connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -4813,6 +4811,7 @@ int spider_db_seek_last(
}
conn = spider->conns[roop_count];
spider_db_handler *dbton_handler = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -4820,6 +4819,11 @@ int spider_db_seek_last(
}
if ((error_num = dbton_handler->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
@@ -4829,10 +4833,14 @@ int spider_db_seek_last(
}
DBUG_PRINT("info",("spider sql_type=%lu", sql_type));
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4867,6 +4875,8 @@ int spider_db_seek_last(
result_list->quick_mode,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4893,6 +4903,8 @@ int spider_db_seek_last(
DBUG_RETURN(error_num);
}
spider->connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -5561,8 +5573,6 @@ int spider_db_bulk_insert(
#endif
SPIDER_SHARE *share = spider->share;
THD *thd = spider->trx->thd;
- bool mta_conn_mutex_lock_already_backup;
- bool mta_conn_mutex_unlock_later_backup;
DBUG_ENTER("spider_db_bulk_insert");
if (!bulk_end)
@@ -5617,61 +5627,50 @@ int spider_db_bulk_insert(
sql_type = SPIDER_SQL_TYPE_INSERT_SQL;
conn = spider->conns[roop_count2];
dbton_handler = spider->dbton_handler[conn->dbton_id];
- mta_conn_mutex_lock_already_backup =
- conn->mta_conn_mutex_lock_already;
- mta_conn_mutex_unlock_later_backup =
- conn->mta_conn_mutex_unlock_later;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
- if (!mta_conn_mutex_lock_already_backup)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
if ((error_num = dbton_handler->set_sql_for_exec(sql_type,
roop_count2)))
{
+ if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
- if (!mta_conn_mutex_lock_already_backup)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
} else {
sql_type = SPIDER_SQL_TYPE_INSERT_HS;
conn = spider->hs_w_conns[roop_count2];
dbton_handler = spider->dbton_handler[conn->dbton_id];
- mta_conn_mutex_lock_already_backup =
- conn->mta_conn_mutex_lock_already;
- mta_conn_mutex_unlock_later_backup =
- conn->mta_conn_mutex_unlock_later;
- if (!mta_conn_mutex_lock_already_backup)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
#endif
conn->need_mon = &spider->need_mons[roop_count2];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count2)))
{
- conn->mta_conn_mutex_lock_already =
- mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later =
- mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (
share->monitoring_kind[roop_count2] &&
spider->need_mons[roop_count2]
@@ -5709,15 +5708,12 @@ int spider_db_bulk_insert(
{
conn->db_conn->set_dup_key_idx(spider, roop_count2);
}
- conn->mta_conn_mutex_lock_already =
- mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later =
- mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (
error_num != ER_DUP_ENTRY &&
error_num != ER_DUP_KEY &&
@@ -5743,8 +5739,10 @@ int spider_db_bulk_insert(
}
DBUG_RETURN(error_num);
}
- conn->mta_conn_mutex_lock_already = mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later = mta_conn_mutex_unlock_later_backup;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind != SPIDER_CONN_KIND_MYSQL)
{
@@ -5780,11 +5778,8 @@ int spider_db_bulk_insert(
}
}
#endif
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (first_insert_link_idx == -1)
{
first_insert_link_idx = roop_count2;
@@ -5793,14 +5788,12 @@ int spider_db_bulk_insert(
}
conn = first_insert_conn;
- mta_conn_mutex_lock_already_backup = conn->mta_conn_mutex_lock_already;
- mta_conn_mutex_unlock_later_backup = conn->mta_conn_mutex_unlock_later;
- if (!mta_conn_mutex_lock_already_backup)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[first_insert_link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if (spider->sql_kinds & SPIDER_SQL_KIND_SQL)
@@ -5822,15 +5815,12 @@ int spider_db_bulk_insert(
else if ((error_num = dbton_handler->
show_last_insert_id(first_insert_link_idx, last_insert_id)))
{
- conn->mta_conn_mutex_lock_already =
- mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later =
- mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
table->next_number_field->set_notnull();
@@ -5840,25 +5830,21 @@ int spider_db_bulk_insert(
(error_num = table->next_number_field->store(
last_insert_id, TRUE))
) {
- conn->mta_conn_mutex_lock_already =
- mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later =
- mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
}
- conn->mta_conn_mutex_lock_already = mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later = mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
spider->store_last_insert_id = 0;
#ifdef HA_CAN_BULK_ACCESS
}
@@ -5902,8 +5888,11 @@ int spider_db_bulk_bulk_insert(
conn = spider->hs_w_conns[roop_count2];
}
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((tmp_error_num = spider_db_bulk_open_handler(spider, conn,
@@ -5911,6 +5900,8 @@ int spider_db_bulk_bulk_insert(
{
error_num = tmp_error_num;
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -5959,9 +5950,12 @@ int spider_db_bulk_bulk_insert(
}
conn = first_insert_conn;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[first_insert_link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if (table->next_number_field &&
@@ -5988,6 +5982,8 @@ int spider_db_bulk_bulk_insert(
error_num = tmp_error_num;
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6115,6 +6111,7 @@ int spider_db_bulk_update_size_limit(
) {
conn = spider->conns[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
{
@@ -6124,6 +6121,12 @@ int spider_db_bulk_update_size_limit(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -6134,7 +6137,11 @@ int spider_db_bulk_update_size_limit(
}
if ((error_num = spider_db_query_for_bulk_update(
spider, conn, roop_count, &dup_key_found)))
+ {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
+ }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
}
spider->reset_sql_sql(SPIDER_SQL_TYPE_BULK_UPDATE_SQL);
} else {
@@ -6200,6 +6207,7 @@ int spider_db_bulk_update_end(
) {
conn = spider->conns[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
{
@@ -6209,14 +6217,14 @@ int spider_db_bulk_update_end(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
if (error_num == ER_SPIDER_COND_SKIP_NUM)
{
- if (dbton_hdl->need_lock_before_set_sql_for_exec(
- SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
continue;
}
DBUG_RETURN(error_num);
@@ -6229,7 +6237,11 @@ int spider_db_bulk_update_end(
}
if ((error_num = spider_db_query_for_bulk_update(
spider, conn, roop_count, dup_key_found)))
+ {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
goto error_query;
+ }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
}
}
if (error_num != HA_ERR_END_OF_FILE)
@@ -6254,6 +6266,7 @@ int spider_db_bulk_update_end(
) {
conn = spider->conns[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
{
@@ -6263,6 +6276,12 @@ int spider_db_bulk_update_end(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -6273,7 +6292,11 @@ int spider_db_bulk_update_end(
}
if ((error_num = spider_db_query_for_bulk_update(
spider, conn, roop_count, dup_key_found)))
+ {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
goto error_last_query;
+ }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
}
}
}
@@ -6341,6 +6364,7 @@ int spider_db_update(
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
conn->ignore_dup_key = spider->ignore_dup_key;
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_UPDATE_SQL))
{
@@ -6350,6 +6374,12 @@ int spider_db_update(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_UPDATE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_UPDATE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -6359,10 +6389,14 @@ int spider_db_update(
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6397,6 +6431,8 @@ int spider_db_update(
-1,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -6435,6 +6471,8 @@ int spider_db_update(
if ((error_num = dbton_hdl->append_insert_for_recovery(
SPIDER_SQL_TYPE_INSERT_SQL, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6449,6 +6487,8 @@ int spider_db_update(
-1,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -6478,6 +6518,8 @@ int spider_db_update(
DBUG_RETURN(error_num);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6666,6 +6708,7 @@ int spider_db_direct_update(
}
#endif
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -6673,6 +6716,11 @@ int spider_db_direct_update(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -6688,10 +6736,14 @@ int spider_db_direct_update(
} else {
#endif
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6729,6 +6781,8 @@ int spider_db_direct_update(
) &&
(error_num != HA_ERR_FOUND_DUPP_KEY || !spider->ignore_dup_key)
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -6795,6 +6849,8 @@ int spider_db_direct_update(
{
error_num = spider_db_errorno(conn);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6803,11 +6859,13 @@ int spider_db_direct_update(
}
}
#endif
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
#ifdef HA_CAN_BULK_ACCESS
}
#endif
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -6852,8 +6910,11 @@ int spider_db_bulk_direct_update(
conn = spider->hs_w_conns[roop_count];
}
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((tmp_error_num = spider_db_bulk_open_handler(spider, conn,
@@ -6899,6 +6960,8 @@ int spider_db_bulk_direct_update(
{
error_num = spider_db_errorno(conn);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6907,6 +6970,8 @@ int spider_db_bulk_direct_update(
}
}
#endif
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6963,6 +7028,7 @@ int spider_db_delete(
) {
conn = spider->conns[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_DELETE_SQL))
{
@@ -6972,6 +7038,12 @@ int spider_db_delete(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_DELETE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_DELETE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -6980,9 +7052,27 @@ int spider_db_delete(
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_query_with_set_names(
SPIDER_SQL_TYPE_DELETE_SQL, spider, conn, roop_count)))
+ {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
result_list->update_sqls[roop_count].length(0);
}
if ((error_num = spider->reset_sql_sql(SPIDER_SQL_TYPE_DELETE_SQL)))
@@ -7094,6 +7184,7 @@ int spider_db_direct_delete(
}
#endif
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -7101,6 +7192,11 @@ int spider_db_direct_delete(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -7116,10 +7212,14 @@ int spider_db_direct_delete(
} else {
#endif
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7154,6 +7254,8 @@ int spider_db_direct_delete(
-1,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7179,6 +7281,8 @@ int spider_db_direct_delete(
}
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -7271,6 +7375,7 @@ int spider_db_delete_all_rows(
uint dbton_id = share->use_sql_dbton_ids[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[dbton_id];
conn = spider->conns[roop_count];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_DELETE_SQL))
{
@@ -7280,6 +7385,12 @@ int spider_db_delete_all_rows(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_DELETE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_DELETE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -7289,6 +7400,8 @@ int spider_db_delete_all_rows(
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, roop_count, spider->trx->thd,
@@ -7311,6 +7424,8 @@ int spider_db_delete_all_rows(
/* retry */
if ((error_num = spider_db_ping(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7339,6 +7454,8 @@ int spider_db_delete_all_rows(
}
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7373,6 +7490,8 @@ int spider_db_delete_all_rows(
-1,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7399,6 +7518,8 @@ int spider_db_delete_all_rows(
DBUG_RETURN(error_num);
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7426,6 +7547,8 @@ int spider_db_delete_all_rows(
DBUG_RETURN(error_num);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -8807,7 +8930,14 @@ int spider_db_udf_direct_sql(
c_thd->lex->sql_command = SQLCOM_INSERT;
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (
!(error_num = spider_db_udf_direct_sql_set_names(direct_sql, trx, conn)) &&
!(error_num = spider_db_udf_direct_sql_select_db(direct_sql, conn))
@@ -8830,9 +8960,6 @@ int spider_db_udf_direct_sql(
#endif
DBUG_RETURN(error_num);
}
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
}
#endif
spider_conn_set_timeout_from_direct_sql(conn, thd, direct_sql);
@@ -8851,8 +8978,6 @@ int spider_db_udf_direct_sql(
DBUG_PRINT("info",("spider conn=%p", conn));
if (!direct_sql->table_count)
roop_count = -1;
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
do {
if (roop_count == direct_sql->table_count)
{
@@ -9064,12 +9189,14 @@ int spider_db_udf_direct_sql(
if (roop_count >= 0)
roop_count++;
} while (status == 0);
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (need_trx_end && insert_start)
{
if (error_num)
@@ -9099,19 +9226,13 @@ int spider_db_udf_direct_sql_select_db(
SPIDER_CONN *conn
) {
int error_num, need_mon = 0;
- bool tmp_mta_conn_mutex_lock_already;
SPIDER_DB_CONN *db_conn = conn->db_conn;
DBUG_ENTER("spider_db_udf_direct_sql_select_db");
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (direct_sql->access_mode == 0)
{
#endif
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &need_mon;
- }
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
if (
!conn->default_database.length() ||
@@ -9120,8 +9241,6 @@ int spider_db_udf_direct_sql_select_db(
memcmp(direct_sql->tgt_default_db_name, conn->default_database.ptr(),
direct_sql->tgt_default_db_name_length)
) {
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if (
(
spider_db_before_query(conn, &need_mon) ||
@@ -9135,7 +9254,6 @@ int spider_db_udf_direct_sql_select_db(
)
my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
DBUG_RETURN(error_num);
}
conn->default_database.length(0);
@@ -9145,12 +9263,6 @@ int spider_db_udf_direct_sql_select_db(
conn->default_database.q_append(direct_sql->tgt_default_db_name,
direct_sql->tgt_default_db_name_length + 1);
conn->default_database.length(direct_sql->tgt_default_db_name_length);
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- }
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
}
@@ -9164,25 +9276,17 @@ int spider_db_udf_direct_sql_set_names(
SPIDER_CONN *conn
) {
int error_num, need_mon = 0;
- bool tmp_mta_conn_mutex_lock_already;
DBUG_ENTER("spider_db_udf_direct_sql_set_names");
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (direct_sql->access_mode == 0)
{
#endif
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &need_mon;
- }
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
if (
!conn->access_charset ||
trx->udf_access_charset->cset != conn->access_charset->cset
) {
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if (
(
spider_db_before_query(conn, &need_mon) ||
@@ -9197,17 +9301,10 @@ int spider_db_udf_direct_sql_set_names(
my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
}
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
DBUG_RETURN(error_num);
}
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
conn->access_charset = trx->udf_access_charset;
}
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
}
#endif
@@ -9271,13 +9368,18 @@ int spider_db_udf_ping_table(
spider.conn_link_idx = &tmp_conn_link_idx;
spider.db_request_phase = &db_request_phase;
spider.db_request_id = &db_request_id;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_ping(&spider, conn, 0)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9293,6 +9395,8 @@ int spider_db_udf_ping_table(
share->server_names[0]);
DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9336,13 +9440,18 @@ int spider_db_udf_ping_table(
my_error(error_num, MYF(0));
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(&spider, conn, 0)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9360,6 +9469,8 @@ int spider_db_udf_ping_table(
-1,
&need_mon)
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -9368,6 +9479,8 @@ int spider_db_udf_ping_table(
DBUG_PRINT("info",("spider error_num=%d", error_num));
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
spider_db_discard_result(&spider, 0, conn);
@@ -9553,13 +9666,18 @@ int spider_db_udf_ping_table_mon_next(
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_ping(&spider, conn, 0)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9570,6 +9688,8 @@ int spider_db_udf_ping_table_mon_next(
}
if ((error_num = spider_db_set_names(&spider, conn, 0)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9584,6 +9704,8 @@ int spider_db_udf_ping_table_mon_next(
-1,
&need_mon)
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
@@ -9596,13 +9718,25 @@ int spider_db_udf_ping_table_mon_next(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ DBUG_RETURN(error_num);
+ }
+ else if ((error_num = spider_db_errorno(conn)))
+ {
DBUG_RETURN(error_num);
+ }
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9683,8 +9817,22 @@ int spider_db_udf_copy_tables(
spider_conn_clear_queue_at_commit(tmp_conn);
if (!tmp_conn->trx_start)
{
+ pthread_mutex_assert_not_owner(&tmp_conn->mta_conn_mutex);
+ pthread_mutex_lock(&tmp_conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ tmp_conn->need_mon = &tmp_spider->need_mons[0];
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = TRUE;
+ tmp_conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_ping(tmp_spider, tmp_conn, 0))
{
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
tmp_spider->share->server_names[0]);
error_num = ER_CONNECT_TO_FOREIGN_DATA_SOURCE;
@@ -9694,8 +9842,21 @@ int spider_db_udf_copy_tables(
(error_num = spider_db_set_names(tmp_spider, tmp_conn, 0)) ||
(error_num = spider_db_start_transaction(tmp_conn,
tmp_spider->need_mons))
- )
+ ) {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_start_transaction;
+ }
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
}
}
} else {
@@ -9715,8 +9876,22 @@ int spider_db_udf_copy_tables(
{
tmp_spider = &spider[roop_count];
tmp_conn = tmp_spider->conns[0];
+ pthread_mutex_assert_not_owner(&tmp_conn->mta_conn_mutex);
+ pthread_mutex_lock(&tmp_conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ tmp_conn->need_mon = &tmp_spider->need_mons[0];
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = TRUE;
+ tmp_conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_ping(tmp_spider, tmp_conn, 0))
{
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
tmp_spider->share->server_names[0]);
error_num = ER_CONNECT_TO_FOREIGN_DATA_SOURCE;
@@ -9729,11 +9904,23 @@ int spider_db_udf_copy_tables(
(error_num = spider_db_lock_tables(tmp_spider, 0))
)
) {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
tmp_conn->table_lock = 0;
if (error_num == HA_ERR_OUT_OF_MEM)
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error_lock_tables;
}
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
tmp_conn->table_lock = 1;
}
}
@@ -9741,11 +9928,23 @@ int spider_db_udf_copy_tables(
tmp_conn = src_tbl_conn->conn;
spider_conn_set_timeout_from_share(tmp_conn, 0,
copy_tables->trx->thd, src_tbl_conn->share);
+ pthread_mutex_assert_not_owner(&tmp_conn->mta_conn_mutex);
+ pthread_mutex_lock(&tmp_conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ tmp_conn->need_mon = &src_tbl_conn->need_mon;
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = TRUE;
+ tmp_conn->mta_conn_mutex_unlock_later = TRUE;
if (select_ct->exec_query(
tmp_conn,
-1,
&src_tbl_conn->need_mon)
) {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(tmp_conn);
if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM)
my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
@@ -9774,6 +9973,10 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_db_query;
@@ -9789,6 +9992,10 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_db_query;
@@ -9815,6 +10022,10 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_db_query;
@@ -9832,6 +10043,10 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
error_num = ER_OUT_OF_RESOURCES;
@@ -9844,12 +10059,20 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_db_query;
}
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
for (dst_tbl_conn = copy_tables->table_conn[1]; dst_tbl_conn;
@@ -9870,6 +10093,12 @@ int spider_db_udf_copy_tables(
}
if (error_num)
{
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM)
my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
@@ -9877,6 +10106,10 @@ int spider_db_udf_copy_tables(
}
error_num = HA_ERR_END_OF_FILE;
end_of_file = TRUE;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
}
@@ -9919,9 +10152,12 @@ int spider_db_udf_copy_tables(
{
tmp_conn = dst_tbl_conn->conn;
insert_ct = dst_tbl_conn->copy_table;
+ pthread_mutex_assert_not_owner(&tmp_conn->mta_conn_mutex);
pthread_mutex_lock(&tmp_conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
tmp_conn->need_mon = &dst_tbl_conn->need_mon;
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_unlock_later);
tmp_conn->mta_conn_mutex_lock_already = TRUE;
tmp_conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(tmp_conn, 0,
@@ -9931,6 +10167,8 @@ int spider_db_udf_copy_tables(
-1,
&dst_tbl_conn->need_mon)
) {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
tmp_conn->mta_conn_mutex_lock_already = FALSE;
tmp_conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(tmp_conn);
@@ -9939,6 +10177,8 @@ int spider_db_udf_copy_tables(
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
goto error_db_query;
} else {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
tmp_conn->mta_conn_mutex_lock_already = FALSE;
tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
@@ -10079,8 +10319,6 @@ int spider_db_open_handler(
int link_idx
) {
int error_num;
- bool tmp_mta_conn_mutex_lock_already;
- bool tmp_mta_conn_mutex_unlock_later;
SPIDER_SHARE *share = spider->share;
uint *handler_id_ptr =
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -10095,16 +10333,14 @@ int spider_db_open_handler(
;
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
DBUG_ENTER("spider_db_open_handler");
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
- tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later;
conn->mta_conn_mutex_unlock_later = TRUE;
if (!spider->handler_opened(link_idx, conn->conn_kind))
*handler_id_ptr = conn->opened_handlers;
@@ -10153,11 +10389,6 @@ int spider_db_open_handler(
{
my_printf_error(ER_SPIDER_HS_NUM, ER_SPIDER_HS_STR, MYF(0),
conn->db_conn->get_errno(), conn->db_conn->get_error());
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
spider->need_mons[link_idx] = ER_SPIDER_HS_NUM;
error_num = ER_SPIDER_HS_NUM;
goto error;
@@ -10293,23 +10524,21 @@ int spider_db_open_handler(
}
DBUG_PRINT("info",("spider conn=%p", conn));
DBUG_PRINT("info",("spider opened_handlers=%u", conn->opened_handlers));
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
- if (!tmp_mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
error:
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
- if (!tmp_mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
@@ -10359,6 +10588,7 @@ int spider_db_bulk_open_handler(
}
bool tmp_mta_conn_mutex_unlock_later;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later;
conn->mta_conn_mutex_unlock_later = TRUE;
SPIDER_DB_RESULT *result;
@@ -10397,24 +10627,19 @@ int spider_db_close_handler(
uint tgt_conn_kind
) {
int error_num;
- bool tmp_mta_conn_mutex_lock_already;
- bool tmp_mta_conn_mutex_unlock_later;
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
DBUG_ENTER("spider_db_close_handler");
DBUG_PRINT("info",("spider conn=%p", conn));
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider->handler_opened(link_idx, tgt_conn_kind))
{
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- }
- DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
- tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later;
- conn->mta_conn_mutex_unlock_later = TRUE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
@@ -10422,7 +10647,15 @@ int spider_db_close_handler(
dbton_hdl->reset_sql(SPIDER_SQL_TYPE_HANDLER);
if ((error_num = dbton_hdl->append_close_handler_part(
SPIDER_SQL_TYPE_HANDLER, link_idx)))
+ {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
+ }
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
spider->share);
@@ -10448,24 +10681,22 @@ int spider_db_close_handler(
goto error;
conn->opened_handlers--;
DBUG_PRINT("info",("spider opened_handlers=%u", conn->opened_handlers));
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
- if (!tmp_mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
error:
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
- if (!tmp_mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
@@ -10502,3 +10733,4 @@ bool spider_db_conn_is_network_error(
}
DBUG_RETURN(FALSE);
}
+
diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h
index 7db61d44e20..39e2c8650c4 100644
--- a/storage/spider/spd_db_include.h
+++ b/storage/spider/spd_db_include.h
@@ -139,6 +139,8 @@ typedef st_spider_result SPIDER_RESULT;
#define SPIDER_SQL_IN_LEN (sizeof(SPIDER_SQL_IN_STR) - 1)
#define SPIDER_SQL_NOT_IN_STR "not in("
#define SPIDER_SQL_NOT_IN_LEN (sizeof(SPIDER_SQL_NOT_IN_STR) - 1)
+#define SPIDER_SQL_NOT_LIKE_STR "not like"
+#define SPIDER_SQL_NOT_LIKE_LEN (sizeof(SPIDER_SQL_NOT_LIKE_STR) - 1)
#define SPIDER_SQL_AS_CHAR_STR " as char"
#define SPIDER_SQL_AS_CHAR_LEN (sizeof(SPIDER_SQL_AS_CHAR_STR) - 1)
#define SPIDER_SQL_CAST_STR "cast("
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index 6f2960cb868..9ed29d015b3 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -1844,10 +1844,6 @@ void spider_db_mysql::print_warnings(
if (!(db_conn->server_status & SERVER_MORE_RESULTS_EXISTS))
#endif
{
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
-*/
if (
spider_param_dry_access() ||
!mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR,
@@ -1865,18 +1861,10 @@ void spider_db_mysql::print_warnings(
{
if (res)
mysql_free_result(res);
-/*
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
-*/
DBUG_VOID_RETURN;
}
/* no record is ok */
}
-/*
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
-*/
num_fields = mysql_num_fields(res);
if (num_fields != 3)
{
@@ -1895,11 +1883,6 @@ void spider_db_mysql::print_warnings(
}
if (res)
mysql_free_result(res);
- } else {
-/*
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
-*/
}
}
}
@@ -2039,14 +2022,31 @@ int spider_db_mysql::consistent_snapshot(
) {
DBUG_ENTER("spider_db_mysql::consistent_snapshot");
DBUG_PRINT("info",("spider this=%p", this));
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_START_CONSISTENT_SNAPSHOT_STR,
SPIDER_SQL_START_CONSISTENT_SNAPSHOT_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2064,16 +2064,18 @@ int spider_db_mysql::start_transaction(
) {
DBUG_ENTER("spider_db_mysql::start_transaction");
DBUG_PRINT("info",("spider this=%p", this));
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
if (spider_db_query(
conn,
SPIDER_SQL_START_TRANSACTION_STR,
SPIDER_SQL_START_TRANSACTION_LEN,
-1,
need_mon)
- )
+ ) {
DBUG_RETURN(spider_db_errorno(conn));
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(0);
}
@@ -2082,14 +2084,31 @@ int spider_db_mysql::commit(
) {
DBUG_ENTER("spider_db_mysql::commit");
DBUG_PRINT("info",("spider this=%p", this));
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_COMMIT_STR,
SPIDER_SQL_COMMIT_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2102,6 +2121,13 @@ int spider_db_mysql::rollback(
int error_num;
DBUG_ENTER("spider_db_mysql::rollback");
DBUG_PRINT("info",("spider this=%p", this));
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
@@ -2118,12 +2144,18 @@ int spider_db_mysql::rollback(
)
conn->thd->clear_error();
else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
@@ -2160,14 +2192,31 @@ int spider_db_mysql::xa_end(
sql_str.length(0);
sql_str.q_append(SPIDER_SQL_XA_END_STR, SPIDER_SQL_XA_END_LEN);
spider_db_append_xid_str(&sql_str, xid);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2186,14 +2235,31 @@ int spider_db_mysql::xa_prepare(
sql_str.length(0);
sql_str.q_append(SPIDER_SQL_XA_PREPARE_STR, SPIDER_SQL_XA_PREPARE_LEN);
spider_db_append_xid_str(&sql_str, xid);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2212,14 +2278,31 @@ int spider_db_mysql::xa_commit(
sql_str.length(0);
sql_str.q_append(SPIDER_SQL_XA_COMMIT_STR, SPIDER_SQL_XA_COMMIT_LEN);
spider_db_append_xid_str(&sql_str, xid);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2238,14 +2321,31 @@ int spider_db_mysql::xa_rollback(
sql_str.length(0);
sql_str.q_append(SPIDER_SQL_XA_ROLLBACK_STR, SPIDER_SQL_XA_ROLLBACK_LEN);
spider_db_append_xid_str(&sql_str, xid);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2267,50 +2367,118 @@ int spider_db_mysql::set_trx_isolation(
switch (trx_isolation)
{
case ISO_READ_UNCOMMITTED:
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_READ_UNCOMMITTED_STR,
SPIDER_SQL_ISO_READ_UNCOMMITTED_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
case ISO_READ_COMMITTED:
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_READ_COMMITTED_STR,
SPIDER_SQL_ISO_READ_COMMITTED_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
case ISO_REPEATABLE_READ:
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_REPEATABLE_READ_STR,
SPIDER_SQL_ISO_REPEATABLE_READ_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
case ISO_SERIALIZABLE:
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_SERIALIZABLE_STR,
SPIDER_SQL_ISO_SERIALIZABLE_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
@@ -2335,25 +2503,59 @@ int spider_db_mysql::set_autocommit(
DBUG_PRINT("info",("spider this=%p", this));
if (autocommit)
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_AUTOCOMMIT_ON_STR,
SPIDER_SQL_AUTOCOMMIT_ON_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_AUTOCOMMIT_OFF_STR,
SPIDER_SQL_AUTOCOMMIT_OFF_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -2375,25 +2577,59 @@ int spider_db_mysql::set_sql_log_off(
DBUG_PRINT("info",("spider this=%p", this));
if (sql_log_off)
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_SQL_LOG_ON_STR,
SPIDER_SQL_SQL_LOG_ON_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_SQL_LOG_OFF_STR,
SPIDER_SQL_SQL_LOG_OFF_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -2424,14 +2660,31 @@ int spider_db_mysql::set_time_zone(
sql_str.q_append(SPIDER_SQL_TIME_ZONE_STR, SPIDER_SQL_TIME_ZONE_LEN);
sql_str.q_append(tz_str->ptr(), tz_str->length());
sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -3948,13 +4201,27 @@ int spider_db_mysql_util::open_item_func(
case Item_func::LE_FUNC:
case Item_func::GE_FUNC:
case Item_func::GT_FUNC:
- case Item_func::LIKE_FUNC:
if (str)
{
func_name = (char*) item_func->func_name();
func_name_length = strlen(func_name);
}
break;
+ case Item_func::LIKE_FUNC:
+ if (str)
+ {
+ if (((Item_func_like *)item_func)->negated)
+ {
+ func_name = SPIDER_SQL_NOT_LIKE_STR;
+ func_name_length = SPIDER_SQL_NOT_LIKE_LEN;
+ }
+ else
+ {
+ func_name = (char*)item_func->func_name();
+ func_name_length = strlen(func_name);
+ }
+ }
+ break;
default:
THD *thd = spider->trx->thd;
SPIDER_SHARE *share = spider->share;
@@ -4959,6 +5226,14 @@ int spider_mysql_share::discover_table_structure(
) {
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (!conn->disable_reconnect)
{
ha_spider tmp_spider;
@@ -4971,14 +5246,15 @@ int spider_mysql_share::discover_table_structure(
if ((error_num = spider_db_ping(&tmp_spider, conn, 0)))
{
DBUG_PRINT("info",("spider spider_db_ping error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
continue;
}
}
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &need_mon;
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, roop_count, trx->thd,
spider_share);
if (
@@ -4995,6 +5271,8 @@ int spider_mysql_share::discover_table_structure(
)
) {
DBUG_PRINT("info",("spider spider_get_trx error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5014,6 +5292,8 @@ int spider_mysql_share::discover_table_structure(
if (error_num || (error_num = spider_db_errorno(conn)))
{
DBUG_PRINT("info",("spider column store error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5022,6 +5302,8 @@ int spider_mysql_share::discover_table_structure(
}
/* no record */
DBUG_PRINT("info",("spider column no record error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5034,6 +5316,8 @@ int spider_mysql_share::discover_table_structure(
DBUG_PRINT("info",("spider column fetch error"));
res->free_result();
delete res;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5050,6 +5334,8 @@ int spider_mysql_share::discover_table_structure(
if (conn->db_conn->next_result())
{
DBUG_PRINT("info",("spider single result error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5062,6 +5348,8 @@ int spider_mysql_share::discover_table_structure(
if (error_num || (error_num = spider_db_errorno(conn)))
{
DBUG_PRINT("info",("spider index store error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5070,6 +5358,8 @@ int spider_mysql_share::discover_table_structure(
}
/* no record */
DBUG_PRINT("info",("spider index no record error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5082,6 +5372,8 @@ int spider_mysql_share::discover_table_structure(
DBUG_PRINT("info",("spider index fetch error"));
res->free_result();
delete res;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5093,6 +5385,8 @@ int spider_mysql_share::discover_table_structure(
if (conn->db_conn->next_result())
{
DBUG_PRINT("info",("spider dual result error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5105,6 +5399,8 @@ int spider_mysql_share::discover_table_structure(
if (error_num || (error_num = spider_db_errorno(conn)))
{
DBUG_PRINT("info",("spider table store error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5113,6 +5409,8 @@ int spider_mysql_share::discover_table_structure(
}
/* no record */
DBUG_PRINT("info",("spider table no record error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5125,6 +5423,8 @@ int spider_mysql_share::discover_table_structure(
DBUG_PRINT("info",("spider table fetch error"));
res->free_result();
delete res;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5133,6 +5433,8 @@ int spider_mysql_share::discover_table_structure(
}
res->free_result();
delete res;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10333,9 +10635,12 @@ int spider_mysql_handler::show_table_status(
if (sts_mode == 1)
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
conn->disable_connect_retry = TRUE;
@@ -10361,6 +10666,8 @@ int spider_mysql_handler::show_table_status(
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10370,6 +10677,8 @@ int spider_mysql_handler::show_table_status(
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10386,12 +10695,16 @@ int spider_mysql_handler::show_table_status(
&spider->need_mons[link_idx])
) {
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10408,6 +10721,8 @@ int spider_mysql_handler::show_table_status(
if (spider_param_dry_access())
{
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10417,9 +10732,17 @@ int spider_mysql_handler::show_table_status(
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ DBUG_RETURN(error_num);
+ }
+ else if ((error_num = spider_db_errorno(conn)))
DBUG_RETURN(error_num);
else
{
@@ -10432,6 +10755,8 @@ int spider_mysql_handler::show_table_status(
}
}
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10474,9 +10799,12 @@ int spider_mysql_handler::show_table_status(
DBUG_RETURN(error_num);
}
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
conn->disable_connect_retry = TRUE;
@@ -10502,6 +10830,8 @@ int spider_mysql_handler::show_table_status(
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10511,6 +10841,8 @@ int spider_mysql_handler::show_table_status(
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10527,12 +10859,16 @@ int spider_mysql_handler::show_table_status(
&spider->need_mons[link_idx])
) {
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10549,6 +10885,8 @@ int spider_mysql_handler::show_table_status(
if (spider_param_dry_access())
{
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10558,6 +10896,8 @@ int spider_mysql_handler::show_table_status(
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (error_num || (error_num = spider_db_errorno(conn)))
@@ -10566,6 +10906,8 @@ int spider_mysql_handler::show_table_status(
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
conn->disable_connect_retry = FALSE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10650,9 +10992,12 @@ int spider_mysql_handler::show_index(
DBUG_PRINT("info",("spider crd_mode=%d", crd_mode));
if (crd_mode == 1)
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10676,6 +11021,8 @@ int spider_mysql_handler::show_index(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10684,6 +11031,8 @@ int spider_mysql_handler::show_index(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10699,11 +11048,15 @@ int spider_mysql_handler::show_index(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10721,6 +11074,8 @@ int spider_mysql_handler::show_index(
{
if (error_num || (error_num = spider_db_errorno(conn)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10729,6 +11084,8 @@ int spider_mysql_handler::show_index(
}
/* no record is ok */
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10783,9 +11140,12 @@ int spider_mysql_handler::show_index(
DBUG_RETURN(error_num);
}
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10809,6 +11169,8 @@ int spider_mysql_handler::show_index(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10817,6 +11179,8 @@ int spider_mysql_handler::show_index(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10832,11 +11196,15 @@ int spider_mysql_handler::show_index(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10854,6 +11222,8 @@ int spider_mysql_handler::show_index(
{
if (error_num || (error_num = spider_db_errorno(conn)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10862,6 +11232,8 @@ int spider_mysql_handler::show_index(
}
/* no record is ok */
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10928,9 +11300,12 @@ int spider_mysql_handler::show_records(
SPIDER_SHARE *share = spider->share;
uint pos = spider->conn_link_idx[link_idx];
DBUG_ENTER("spider_mysql_handler::show_records");
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10954,6 +11329,8 @@ int spider_mysql_handler::show_records(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10963,6 +11340,8 @@ int spider_mysql_handler::show_records(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10979,12 +11358,16 @@ int spider_mysql_handler::show_records(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_PRINT("info", ("spider error_num=%d 3", error_num));
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11001,18 +11384,29 @@ int spider_mysql_handler::show_records(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
{
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_PRINT("info", ("spider error_num=%d 5", error_num));
DBUG_RETURN(error_num);
+ }
+ else if ((error_num = spider_db_errorno(conn)))
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 6", error_num));
+ DBUG_RETURN(error_num);
} else {
- DBUG_PRINT("info", ("spider error_num=%d 6",
+ DBUG_PRINT("info", ("spider error_num=%d 7",
ER_QUERY_ON_FOREIGN_DATA_SOURCE));
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11062,9 +11456,12 @@ ha_rows spider_mysql_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -11090,6 +11487,8 @@ ha_rows spider_mysql_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11100,6 +11499,8 @@ ha_rows spider_mysql_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11118,6 +11519,8 @@ ha_rows spider_mysql_handler::explain_select(
error_num = spider_db_errorno(conn);
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11127,6 +11530,8 @@ ha_rows spider_mysql_handler::explain_select(
} else {
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11146,6 +11551,8 @@ ha_rows spider_mysql_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11153,6 +11560,8 @@ ha_rows spider_mysql_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
} else {
my_errno = ER_QUERY_ON_FOREIGN_DATA_SOURCE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11160,6 +11569,8 @@ ha_rows spider_mysql_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11192,13 +11603,18 @@ int spider_mysql_handler::lock_tables(
}
if (str->length())
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11214,10 +11630,14 @@ int spider_mysql_handler::lock_tables(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11252,14 +11672,31 @@ int spider_mysql_handler::unlock_tables(
{
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
spider->share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
str->ptr(),
str->length(),
-1,
&spider->need_mons[link_idx])
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -11282,13 +11719,18 @@ int spider_mysql_handler::disable_keys(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11304,11 +11746,15 @@ int spider_mysql_handler::disable_keys(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11331,13 +11777,18 @@ int spider_mysql_handler::enable_keys(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11353,11 +11804,15 @@ int spider_mysql_handler::enable_keys(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11381,13 +11836,18 @@ int spider_mysql_handler::check_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11403,11 +11863,15 @@ int spider_mysql_handler::check_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11431,13 +11895,18 @@ int spider_mysql_handler::repair_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11453,11 +11922,15 @@ int spider_mysql_handler::repair_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11480,13 +11953,18 @@ int spider_mysql_handler::analyze_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11502,11 +11980,15 @@ int spider_mysql_handler::analyze_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11529,13 +12011,18 @@ int spider_mysql_handler::optimize_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11551,11 +12038,15 @@ int spider_mysql_handler::optimize_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11581,6 +12072,14 @@ int spider_mysql_handler::flush_tables(
}
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
str->ptr(),
@@ -11588,9 +12087,17 @@ int spider_mysql_handler::flush_tables(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -11606,6 +12113,14 @@ int spider_mysql_handler::flush_logs(
DBUG_PRINT("info",("spider this=%p", this));
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_FLUSH_LOGS_STR,
@@ -11613,9 +12128,17 @@ int spider_mysql_handler::flush_logs(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc
index 281e3188067..d5d41f4a994 100644
--- a/storage/spider/spd_db_oracle.cc
+++ b/storage/spider/spd_db_oracle.cc
@@ -1780,16 +1780,18 @@ int spider_db_oracle::start_transaction(
}
DBUG_RETURN(set_trx_isolation(conn->trx_isolation, need_mon));
}
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
if (spider_db_query(
conn,
SPIDER_SQL_START_TRANSACTION_STR,
SPIDER_SQL_START_TRANSACTION_LEN,
-1,
need_mon)
- )
+ ) {
DBUG_RETURN(spider_db_errorno(conn));
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(0);
}
@@ -1978,14 +1980,31 @@ int spider_db_oracle::set_trx_isolation(
DBUG_RETURN(exec_query(SPIDER_SQL_ISO_READ_COMMITTED_STR,
SPIDER_SQL_ISO_READ_COMMITTED_LEN, -1));
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_READ_COMMITTED_STR,
SPIDER_SQL_ISO_READ_COMMITTED_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
@@ -1996,14 +2015,31 @@ int spider_db_oracle::set_trx_isolation(
DBUG_RETURN(exec_query(SPIDER_SQL_ISO_SERIALIZABLE_STR,
SPIDER_SQL_ISO_SERIALIZABLE_LEN, -1));
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_SERIALIZABLE_STR,
SPIDER_SQL_ISO_SERIALIZABLE_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
@@ -2033,14 +2069,31 @@ int spider_db_oracle::set_autocommit(
DBUG_RETURN(exec_query(SPIDER_SQL_AUTOCOMMIT_ON_STR,
SPIDER_SQL_AUTOCOMMIT_ON_LEN, -1));
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_AUTOCOMMIT_ON_STR,
SPIDER_SQL_AUTOCOMMIT_ON_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
} else {
@@ -2049,14 +2102,31 @@ int spider_db_oracle::set_autocommit(
DBUG_RETURN(exec_query(SPIDER_SQL_AUTOCOMMIT_OFF_STR,
SPIDER_SQL_AUTOCOMMIT_OFF_LEN, -1));
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_AUTOCOMMIT_OFF_STR,
SPIDER_SQL_AUTOCOMMIT_OFF_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -10449,112 +10519,6 @@ int spider_oracle_handler::show_table_status(
if (sts_mode == 1)
{
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
- spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
- share);
- if (
- (error_num = spider_db_set_names(spider, conn, link_idx)) ||
- (
- spider_db_query(
- conn,
- oracle_share->show_table_status[0 + pos].ptr(),
- oracle_share->show_table_status[0 + pos].length(),
- -1,
- &spider->need_mons[link_idx]) &&
- (error_num = spider_db_errorno(conn))
- )
- ) {
- if (
- error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM &&
- !conn->disable_reconnect
- ) {
-*/
- /* retry */
-/*
- if ((error_num = spider_db_ping(spider, conn, link_idx)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- if ((error_num = spider_db_set_names(spider, conn, link_idx)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
- share);
- if (spider_db_query(
- conn,
- oracle_share->show_table_status[0 + pos].ptr(),
- oracle_share->show_table_status[0 + pos].length(),
- -1,
- &spider->need_mons[link_idx])
- ) {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- DBUG_RETURN(spider_db_errorno(conn));
- }
- } else {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- }
- st_spider_db_request_key request_key;
- request_key.spider_thread_id = spider->trx->spider_thread_id;
- request_key.query_id = spider->trx->thd->query_id;
- request_key.handler = spider;
- request_key.request_id = 1;
- request_key.next = NULL;
- if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
- DBUG_RETURN(error_num);
- else {
- my_printf_error(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM,
- ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0),
- oracle_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(),
- oracle_share->table_names_str[spider->conn_link_idx[
- link_idx]].ptr());
- DBUG_RETURN(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM);
- }
- }
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- error_num = res->fetch_table_status(
- sts_mode,
- share->records,
- share->mean_rec_length,
- share->data_file_length,
- share->max_data_file_length,
- share->index_file_length,
- auto_increment_value,
- share->create_time,
- share->update_time,
- share->check_time
- );
- res->free_result();
- delete res;
- if (error_num)
- DBUG_RETURN(error_num);
-*/
if (!share->records)
share->records = 10000;
share->mean_rec_length = 65535;
@@ -10565,9 +10529,12 @@ int spider_oracle_handler::show_table_status(
share->update_time = (time_t) 0;
share->check_time = (time_t) 0;
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10591,6 +10558,8 @@ int spider_oracle_handler::show_table_status(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10599,6 +10568,8 @@ int spider_oracle_handler::show_table_status(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10614,11 +10585,15 @@ int spider_oracle_handler::show_table_status(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10634,6 +10609,8 @@ int spider_oracle_handler::show_table_status(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (error_num || (error_num = spider_db_errorno(conn)))
@@ -10641,6 +10618,8 @@ int spider_oracle_handler::show_table_status(
else
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10695,105 +10674,6 @@ int spider_oracle_handler::show_index(
DBUG_PRINT("info",("spider crd_mode=%d", crd_mode));
if (crd_mode == 1)
{
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
- spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
- share);
- if (
- (error_num = spider_db_set_names(spider, conn, link_idx)) ||
- (
- spider_db_query(
- conn,
- oracle_share->show_index[0 + pos].ptr(),
- oracle_share->show_index[0 + pos].length(),
- -1,
- &spider->need_mons[link_idx]) &&
- (error_num = spider_db_errorno(conn))
- )
- ) {
- if (
- error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM &&
- !conn->disable_reconnect
- ) {
-*/
- /* retry */
-/*
- if ((error_num = spider_db_ping(spider, conn, link_idx)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- if ((error_num = spider_db_set_names(spider, conn, link_idx)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
- share);
- if (spider_db_query(
- conn,
- oracle_share->show_index[0 + pos].ptr(),
- oracle_share->show_index[0 + pos].length(),
- -1,
- &spider->need_mons[link_idx])
- ) {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- DBUG_RETURN(spider_db_errorno(conn));
- }
- } else {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- }
- st_spider_db_request_key request_key;
- request_key.spider_thread_id = spider->trx->spider_thread_id;
- request_key.query_id = spider->trx->thd->query_id;
- request_key.handler = spider;
- request_key.request_id = 1;
- request_key.next = NULL;
- if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
- {
- if (error_num || (error_num = spider_db_errorno(conn)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
-*/
- /* no record is ok */
-/*
- }
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- if (res)
- {
- error_num = res->fetch_table_cardinality(
- crd_mode,
- table,
- share->cardinality,
- share->cardinality_upd,
- share->bitmap_size
- );
- }
-*/
for (roop_count = 0, tmp_cardinality = share->cardinality;
roop_count < (int) table->s->fields;
roop_count++, tmp_cardinality++)
@@ -10805,19 +10685,13 @@ int spider_oracle_handler::show_index(
*tmp_cardinality = 1;
}
}
-/*
- if (res)
- {
- res->free_result();
- delete res;
- }
- if (error_num)
- DBUG_RETURN(error_num);
-*/
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10841,6 +10715,8 @@ int spider_oracle_handler::show_index(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10849,6 +10725,8 @@ int spider_oracle_handler::show_index(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10864,11 +10742,15 @@ int spider_oracle_handler::show_index(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10886,6 +10768,8 @@ int spider_oracle_handler::show_index(
{
if (error_num || (error_num = spider_db_errorno(conn)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10894,6 +10778,8 @@ int spider_oracle_handler::show_index(
}
/* no record is ok */
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10939,9 +10825,12 @@ int spider_oracle_handler::show_records(
SPIDER_SHARE *share = spider->share;
uint pos = spider->conn_link_idx[link_idx];
DBUG_ENTER("spider_oracle_handler::show_records");
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10965,6 +10854,8 @@ int spider_oracle_handler::show_records(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10974,6 +10865,8 @@ int spider_oracle_handler::show_records(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10990,12 +10883,16 @@ int spider_oracle_handler::show_records(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_PRINT("info", ("spider error_num=%d 3", error_num));
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11012,18 +10909,29 @@ int spider_oracle_handler::show_records(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
{
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_PRINT("info", ("spider error_num=%d 5", error_num));
DBUG_RETURN(error_num);
+ }
+ else if (error_num || (error_num = spider_db_errorno(conn)))
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 6", error_num));
+ DBUG_RETURN(error_num);
} else {
- DBUG_PRINT("info", ("spider error_num=%d 6",
+ DBUG_PRINT("info", ("spider error_num=%d 7",
ER_QUERY_ON_FOREIGN_DATA_SOURCE));
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11056,9 +10964,12 @@ int spider_oracle_handler::show_autoinc(
if (!oracle_share->show_autoinc)
DBUG_RETURN(0);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -11082,6 +10993,8 @@ int spider_oracle_handler::show_autoinc(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11091,6 +11004,8 @@ int spider_oracle_handler::show_autoinc(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11107,12 +11022,16 @@ int spider_oracle_handler::show_autoinc(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_PRINT("info", ("spider error_num=%d 3", error_num));
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11129,18 +11048,29 @@ int spider_oracle_handler::show_autoinc(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
{
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_PRINT("info", ("spider error_num=%d 5", error_num));
DBUG_RETURN(error_num);
+ }
+ else if ((error_num = spider_db_errorno(conn)))
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 6", error_num));
+ DBUG_RETURN(error_num);
} else {
- DBUG_PRINT("info", ("spider error_num=%d 6",
+ DBUG_PRINT("info", ("spider error_num=%d 7",
ER_QUERY_ON_FOREIGN_DATA_SOURCE));
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11250,9 +11180,12 @@ ha_rows spider_oracle_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -11278,6 +11211,8 @@ ha_rows spider_oracle_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11288,6 +11223,8 @@ ha_rows spider_oracle_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11306,6 +11243,8 @@ ha_rows spider_oracle_handler::explain_select(
error_num = spider_db_errorno(conn);
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11315,6 +11254,8 @@ ha_rows spider_oracle_handler::explain_select(
} else {
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11334,6 +11275,8 @@ ha_rows spider_oracle_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11341,6 +11284,8 @@ ha_rows spider_oracle_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
} else {
my_errno = ER_QUERY_ON_FOREIGN_DATA_SOURCE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11348,6 +11293,8 @@ ha_rows spider_oracle_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11381,13 +11328,18 @@ int spider_oracle_handler::lock_tables(
}
if (str->length())
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11403,10 +11355,14 @@ int spider_oracle_handler::lock_tables(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11452,13 +11408,18 @@ int spider_oracle_handler::disable_keys(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11474,11 +11435,15 @@ int spider_oracle_handler::disable_keys(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11501,13 +11466,18 @@ int spider_oracle_handler::enable_keys(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11523,11 +11493,15 @@ int spider_oracle_handler::enable_keys(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11551,13 +11525,18 @@ int spider_oracle_handler::check_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11573,11 +11552,15 @@ int spider_oracle_handler::check_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11601,13 +11584,18 @@ int spider_oracle_handler::repair_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11623,11 +11611,15 @@ int spider_oracle_handler::repair_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11650,13 +11642,18 @@ int spider_oracle_handler::analyze_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11672,11 +11669,15 @@ int spider_oracle_handler::analyze_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11699,13 +11700,18 @@ int spider_oracle_handler::optimize_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11721,11 +11727,15 @@ int spider_oracle_handler::optimize_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11751,6 +11761,14 @@ int spider_oracle_handler::flush_tables(
}
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
str->ptr(),
@@ -11758,9 +11776,17 @@ int spider_oracle_handler::flush_tables(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -11776,6 +11802,14 @@ int spider_oracle_handler::flush_logs(
DBUG_PRINT("info",("spider this=%p", this));
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_FLUSH_LOGS_STR,
@@ -11783,9 +11817,17 @@ int spider_oracle_handler::flush_logs(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h
index a6ce2efe774..a871e186d96 100644
--- a/storage/spider/spd_include.h
+++ b/storage/spider/spd_include.h
@@ -17,6 +17,8 @@
#define SPIDER_HEX_VERSION 0x0302
#if MYSQL_VERSION_ID < 50500
+#define pthread_mutex_assert_owner(A)
+#define pthread_mutex_assert_not_owner(A)
#else
#define my_free(A,B) my_free(A)
#ifdef pthread_mutex_t
@@ -39,6 +41,8 @@
#undef pthread_mutex_destroy
#endif
#define pthread_mutex_destroy mysql_mutex_destroy
+#define pthread_mutex_assert_owner(A) mysql_mutex_assert_owner(A)
+#define pthread_mutex_assert_not_owner(A) mysql_mutex_assert_not_owner(A)
#ifdef pthread_cond_t
#undef pthread_cond_t
#endif
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index 7c591cf691d..39f51fa1b59 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -5815,13 +5815,18 @@ int spider_open_all_tables(
}
conn->error_mode &= spider_param_error_read_mode(thd, 0);
conn->error_mode &= spider_param_error_write_mode(thd, 0);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &mon_val;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_before_query(conn, &mon_val)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5834,6 +5839,8 @@ int spider_open_all_tables(
free_root(&mem_root, MYF(0));
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index f22f7c1d6b5..eaad6488796 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(TOKUDB_VERSION 5.6.41-84.1)
+SET(TOKUDB_VERSION 5.6.49-89.0)
# PerconaFT only supports x86-64 and cmake-2.8.9+
IF(WIN32)
# tokudb never worked there
@@ -136,6 +136,7 @@ IF(DEFINED TOKUDB_NOPATCH_CONFIG)
ADD_DEFINITIONS("-DTOKUDB_NOPATCH_CONFIG=${TOKUDB_NOPATCH_CONFIG}")
ENDIF()
+MY_CHECK_AND_SET_COMPILER_FLAG(-Wno-missing-format-attribute)
MY_CHECK_AND_SET_COMPILER_FLAG(-Wno-missing-field-initializers)
IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/PerconaFT/")
@@ -168,3 +169,5 @@ TARGET_LINK_LIBRARIES(tokudb tokufractaltree_static tokuportability_static
SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin")
+
+ADD_SUBDIRECTORY(man)
diff --git a/storage/tokudb/PerconaFT/DartConfig.cmake b/storage/tokudb/PerconaFT/DartConfig.cmake
deleted file mode 100644
index 9ad189869c6..00000000000
--- a/storage/tokudb/PerconaFT/DartConfig.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-if(BUILD_TESTING)
- if (NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
- # Valgrind on OSX 10.8 generally works but outputs some warning junk
- # that is hard to parse out, so we'll just let it run alone
- set(MEMORYCHECK_COMMAND "${TokuDB_SOURCE_DIR}/scripts/tokuvalgrind")
- endif ()
- set(MEMORYCHECK_COMMAND_OPTIONS "--gen-suppressions=no --soname-synonyms=somalloc=*tokuportability* --quiet --num-callers=20 --leak-check=full --show-reachable=yes --trace-children=yes --trace-children-skip=sh,*/sh,basename,*/basename,dirname,*/dirname,rm,*/rm,cp,*/cp,mv,*/mv,cat,*/cat,diff,*/diff,grep,*/grep,date,*/date,test,*/tokudb_dump,*/tdb-recover --trace-children-skip-by-arg=--only_create,--test,--no-shutdown,novalgrind" CACHE INTERNAL "options for valgrind")
- set(MEMORYCHECK_SUPPRESSIONS_FILE "${CMAKE_CURRENT_BINARY_DIR}/valgrind.suppressions" CACHE INTERNAL "suppressions file for valgrind")
- set(UPDATE_COMMAND "svn")
-endif()
diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake
index 2f04a33558a..88210868eda 100644
--- a/storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake
+++ b/storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake
@@ -134,4 +134,4 @@ static __thread int tlsvar = 0;
int main(void) { return tlsvar; }" HAVE_GNU_TLS)
## set TOKUDB_REVISION
-set(CMAKE_TOKUDB_REVISION 0 CACHE INTEGER "Revision of tokudb.")
+set(CMAKE_TOKUDB_REVISION 0 CACHE STRING "Revision of tokudb.")
diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
index 8f65895cc9c..924e24c8f2e 100644
--- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
+++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
@@ -47,20 +47,18 @@ include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
## adds a compiler flag if the compiler supports it
-macro(set_cflags_if_supported)
+macro(prepend_cflags_if_supported)
foreach(flag ${ARGN})
MY_CHECK_AND_SET_COMPILER_FLAG(${flag})
endforeach(flag)
-endmacro(set_cflags_if_supported)
+endmacro(prepend_cflags_if_supported)
if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
set (OPTIONAL_CFLAGS "${OPTIONAL_CFLAGS} -Wmissing-format-attribute")
endif()
## disable some warnings
-## missing-format-attribute causes warnings in some MySQL include files
-## if the library is built as a part of TokuDB MySQL storage engine
-set_cflags_if_supported(
+prepend_cflags_if_supported(
-Wno-missing-field-initializers
-Wstrict-null-sentinel
-Winit-self
@@ -77,7 +75,6 @@ set_cflags_if_supported(
-fno-exceptions
-Wno-error=nonnull-compare
)
-## set_cflags_if_supported_named("-Weffc++" -Weffcpp)
if (CMAKE_CXX_FLAGS MATCHES -fno-implicit-templates)
# must append this because mysql sets -fno-implicit-templates and we need to override it
@@ -89,24 +86,18 @@ endif()
## Clang has stricter POD checks. So, only enable this warning on our other builds (Linux + GCC)
if (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang)
- set_cflags_if_supported(
+ prepend_cflags_if_supported(
-Wpacked
)
endif ()
option (PROFILING "Allow profiling and debug" ON)
if (PROFILING)
- set_cflags_if_supported(
+ prepend_cflags_if_supported(
-fno-omit-frame-pointer
)
endif ()
-## this hits with optimized builds somewhere in ftleaf_split, we don't
-## know why but we don't think it's a big deal
-set_cflags_if_supported(
- -Wno-error=strict-overflow
- )
-
# new flag sets in MySQL 8.0 seem to explicitly disable this
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
@@ -144,7 +135,7 @@ else ()
endif ()
## set warnings
-set_cflags_if_supported(
+prepend_cflags_if_supported(
-Wextra
-Wbad-function-cast
-Wno-missing-noreturn
@@ -167,12 +158,12 @@ set_cflags_if_supported(
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang)
# Disabling -Wcast-align with clang. TODO: fix casting and re-enable it, someday.
- set_cflags_if_supported(-Wcast-align)
+ prepend_cflags_if_supported(-Wcast-align)
endif ()
-## always want these in debug builds
-set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror ${CMAKE_C_FLAGS_DEBUG}")
-set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Werror ${CMAKE_CXX_FLAGS_DEBUG}")
+## never want these
+set(CMAKE_C_FLAGS "-Wno-error ${CMAKE_C_FLAGS}")
+set(CMAKE_CXX_FLAGS "-Wno-error ${CMAKE_CXX_FLAGS}")
# pick language dialect
set(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}")
diff --git a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
index 5467bef43b4..034d5442742 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
@@ -225,6 +225,9 @@ uint32_t toku_get_checkpoint_period_unlocked (CACHETABLE ct) {
}
void toku_set_cleaner_period (CACHETABLE ct, uint32_t new_period) {
+ if(force_recovery) {
+ return;
+ }
ct->cl.set_period(new_period);
}
@@ -3026,9 +3029,12 @@ int toku_cleaner_thread (void *cleaner_v) {
//
ENSURE_POD(cleaner);
+extern uint force_recovery;
+
int cleaner::init(uint32_t _cleaner_iterations, pair_list* _pl, CACHETABLE _ct) {
// default is no cleaner, for now
m_cleaner_cron_init = false;
+ if (force_recovery) return 0;
int r = toku_minicron_setup(&m_cleaner_cron, 0, toku_cleaner_thread, this);
if (r == 0) {
m_cleaner_cron_init = true;
diff --git a/storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc b/storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc
index 6b6ff1e323f..439e0688e89 100644
--- a/storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc
@@ -73,7 +73,7 @@ cachetable_put_empty_node_with_dep_nodes(
enum cachetable_dirty dependent_dirty_bits[num_dependent_nodes];
for (uint32_t i = 0; i < num_dependent_nodes; i++) {
dependent_pairs[i] = dependent_nodes[i]->ct_pair;
- dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty;
+ dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty();
}
toku_cachetable_put_with_dep_pairs(
@@ -253,7 +253,7 @@ toku_pin_ftnode_for_query(
// written out, it would have to be dirtied. That
// requires a write lock, and a write lock requires you to
// resolve checkpointing.
- if (!node->dirty) {
+ if (!node->dirty()) {
toku_ft_bn_update_max_msn(node, max_msn_in_path, bfe->child_to_read);
}
}
@@ -280,7 +280,7 @@ toku_pin_ftnode_with_dep_nodes(
enum cachetable_dirty dependent_dirty_bits[num_dependent_nodes];
for (uint32_t i = 0; i < num_dependent_nodes; i++) {
dependent_pairs[i] = dependent_nodes[i]->ct_pair;
- dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty;
+ dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty();
}
int r = toku_cachetable_get_and_pin_with_dep_pairs(
@@ -333,7 +333,7 @@ cleanup:
void toku_unpin_ftnode(FT ft, FTNODE node) {
int r = toku_cachetable_unpin(ft->cf,
node->ct_pair,
- static_cast<enum cachetable_dirty>(node->dirty),
+ static_cast<enum cachetable_dirty>(node->dirty()),
make_ftnode_pair_attr(node));
invariant_zero(r);
}
@@ -344,7 +344,7 @@ toku_unpin_ftnode_read_only(FT ft, FTNODE node)
int r = toku_cachetable_unpin(
ft->cf,
node->ct_pair,
- (enum cachetable_dirty) node->dirty,
+ (enum cachetable_dirty) node->dirty(),
make_invalid_pair_attr()
);
assert(r==0);
diff --git a/storage/tokudb/PerconaFT/ft/ft-flusher.cc b/storage/tokudb/PerconaFT/ft/ft-flusher.cc
index 3fd59f388ce..bbb2a170cb9 100644
--- a/storage/tokudb/PerconaFT/ft/ft-flusher.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-flusher.cc
@@ -139,7 +139,7 @@ maybe_destroy_child_blbs(FTNODE node, FTNODE child, FT ft)
// up to date.
if (child->n_children > 1 &&
child->height == 0 &&
- !child->dirty) {
+ !child->dirty()) {
for (int i = 0; i < child->n_children; ++i) {
if (BP_STATE(child, i) == PT_AVAIL &&
node->max_msn_applied_to_node_on_disk.msn < BLB_MAX_MSN_APPLIED(child, i).msn)
@@ -480,7 +480,7 @@ handle_split_of_child(
}
)
- node->dirty = 1;
+ node->set_dirty();
XREALLOC_N(node->n_children+1, node->bp);
// Slide the children over.
@@ -662,8 +662,8 @@ static void ftnode_finalize_split(FTNODE node, FTNODE B, MSN max_msn_applied_to_
// The new node in the split inherits the oldest known reference xid
B->oldest_referenced_xid_known = node->oldest_referenced_xid_known;
- node->dirty = 1;
- B->dirty = 1;
+ node->set_dirty();
+ B->set_dirty();
}
void
@@ -1003,8 +1003,8 @@ flush_this_child(
paranoid_invariant(child->blocknum.b!=0);
// VERIFY_NODE does not work off client thread as of now
//VERIFY_NODE(t, child);
- node->dirty = 1;
- child->dirty = 1;
+ node->set_dirty();
+ child->set_dirty();
BP_WORKDONE(node, childnum) = 0; // this buffer is drained, no work has been done by its contents
NONLEAF_CHILDINFO bnc = BNC(node, childnum);
@@ -1034,8 +1034,8 @@ merge_leaf_nodes(FTNODE a, FTNODE b)
// TODO(leif): this is no longer the way in_memory_stats is
// maintained. verify that it's ok to move this just before the unpin
// and then do that.
- a->dirty = 1;
- b->dirty = 1;
+ a->set_dirty();
+ b->set_dirty();
bn_data* a_last_bd = BLB_DATA(a, a->n_children-1);
// this bool states if the last basement node in a has any items or not
@@ -1167,8 +1167,8 @@ maybe_merge_pinned_nonleaf_nodes(
a->n_children = new_n_children;
b->n_children = 0;
- a->dirty = 1;
- b->dirty = 1;
+ a->set_dirty();
+ b->set_dirty();
*did_merge = true;
*did_rebalance = false;
@@ -1211,7 +1211,7 @@ maybe_merge_pinned_nodes(
toku_ftnode_assert_fully_in_memory(parent);
toku_ftnode_assert_fully_in_memory(a);
toku_ftnode_assert_fully_in_memory(b);
- parent->dirty = 1; // just to make sure
+ parent->set_dirty(); // just to make sure
{
MSN msna = a->max_msn_applied_to_node_on_disk;
MSN msnb = b->max_msn_applied_to_node_on_disk;
@@ -1335,8 +1335,8 @@ ft_merge_child(
}
paranoid_invariant(BP_BLOCKNUM(node, childnuma).b == childa->blocknum.b);
- childa->dirty = 1; // just to make sure
- childb->dirty = 1; // just to make sure
+ childa->set_dirty(); // just to make sure
+ childb->set_dirty(); // just to make sure
} else {
// flow will be inaccurate for a while, oh well. the children
// are leaves in this case so it's not a huge deal (we're
@@ -1345,7 +1345,7 @@ ft_merge_child(
// If we didn't merge the nodes, then we need the correct pivot.
invariant_notnull(splitk.data);
node->pivotkeys.replace_at(&splitk, childnuma);
- node->dirty = 1;
+ node->set_dirty();
}
toku_destroy_dbt(&splitk);
}
@@ -1369,7 +1369,7 @@ ft_merge_child(
call_flusher_thread_callback(ft_flush_aflter_merge);
// unlock the parent
- paranoid_invariant(node->dirty);
+ paranoid_invariant(node->dirty());
toku_unpin_ftnode(ft, node);
}
else {
@@ -1377,7 +1377,7 @@ ft_merge_child(
call_flusher_thread_callback(ft_flush_aflter_rebalance);
// unlock the parent
- paranoid_invariant(node->dirty);
+ paranoid_invariant(node->dirty());
toku_unpin_ftnode(ft, node);
toku_unpin_ftnode(ft, childb);
}
@@ -1439,9 +1439,9 @@ void toku_ft_flush_some_child(FT ft, FTNODE parent, struct flusher_advice *fa)
// only do the following work if there is a flush to perform
if (toku_bnc_n_entries(BNC(parent, childnum)) > 0 || parent->height == 1) {
- if (!parent->dirty) {
+ if (!parent->dirty()) {
dirtied++;
- parent->dirty = 1;
+ parent->set_dirty();
}
// detach buffer
BP_WORKDONE(parent, childnum) = 0; // this buffer is drained, no work has been done by its contents
@@ -1486,9 +1486,9 @@ void toku_ft_flush_some_child(FT ft, FTNODE parent, struct flusher_advice *fa)
// in the buffer to flush, and as a result, flushing is not necessary
// and bnc is NULL
if (bnc != NULL) {
- if (!child->dirty) {
+ if (!child->dirty()) {
dirtied++;
- child->dirty = 1;
+ child->set_dirty();
}
// do the actual flush
toku_bnc_flush_to_child(
@@ -1787,7 +1787,7 @@ static void flush_node_fun(void *fe_v)
// read them back in, or just do the regular partial fetch. If we
// don't, that means fe->node is a parent, so we need to do this anyway.
bring_node_fully_into_memory(fe->node,fe->ft);
- fe->node->dirty = 1;
+ fe->node->set_dirty();
struct flusher_advice fa;
struct flush_status_update_extra fste;
@@ -1893,7 +1893,7 @@ void toku_ft_flush_node_on_background_thread(FT ft, FTNODE parent)
//
// can detach buffer and unpin root here
//
- parent->dirty = 1;
+ parent->set_dirty();
BP_WORKDONE(parent, childnum) = 0; // this buffer is drained, no work has been done by its contents
NONLEAF_CHILDINFO bnc = BNC(parent, childnum);
NONLEAF_CHILDINFO new_bnc = toku_create_empty_nl();
diff --git a/storage/tokudb/PerconaFT/ft/ft-internal.h b/storage/tokudb/PerconaFT/ft/ft-internal.h
index eec591d1744..130d3c302aa 100644
--- a/storage/tokudb/PerconaFT/ft/ft-internal.h
+++ b/storage/tokudb/PerconaFT/ft/ft-internal.h
@@ -76,11 +76,30 @@ enum ft_type {
FT_CHECKPOINT_INPROGRESS
};
+extern "C" {
+extern uint force_recovery;
+}
+
+extern int writing_rollback;
+
// The ft_header is not managed by the cachetable. Instead, it hangs off the cachefile as userdata.
struct ft_header {
enum ft_type type;
- int dirty;
+ int dirty_;
+
+ void set_dirty() {
+ if(force_recovery) assert(writing_rollback);
+ dirty_ = 1;
+ }
+
+ void clear_dirty() {
+ dirty_ = 0;
+ }
+
+ bool dirty() {
+ return dirty_;
+ }
// Free-running counter incremented once per checkpoint (toggling LSB).
// LSB indicates which header location is used on disk so this
diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc
index df0d88a9580..d752f13c9c3 100644
--- a/storage/tokudb/PerconaFT/ft/ft-ops.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc
@@ -656,7 +656,7 @@ void toku_ftnode_clone_callback(void *value_data,
node->layout_version_read_from_disk;
cloned_node->build_id = node->build_id;
cloned_node->height = node->height;
- cloned_node->dirty = node->dirty;
+ cloned_node->dirty_ = node->dirty_;
cloned_node->fullhash = node->fullhash;
cloned_node->n_children = node->n_children;
@@ -672,8 +672,8 @@ void toku_ftnode_clone_callback(void *value_data,
toku_ftnode_clone_partitions(node, cloned_node);
// clear dirty bit
- node->dirty = 0;
- cloned_node->dirty = 0;
+ node->clear_dirty();
+ cloned_node->clear_dirty();
node->layout_version_read_from_disk = FT_LAYOUT_VERSION;
// set new pair attr if necessary
if (node->height == 0) {
@@ -742,7 +742,7 @@ void toku_ftnode_flush_callback(CACHEFILE UU(cachefile),
// persisted, we need undo the logical row count adjustments as
// they may occur again in the future if/when the node is
// re-read from disk for another query or change.
- if (!ftnode->dirty && !write_me) {
+ if (!ftnode->dirty() && !write_me) {
int64_t lrc_delta = 0;
for (int i = 0; i < ftnode->n_children; i++) {
if (BP_STATE(ftnode, i) == PT_AVAIL) {
@@ -847,8 +847,8 @@ int toku_ftnode_fetch_callback(CACHEFILE UU(cachefile),
if (r == 0) {
*sizep = make_ftnode_pair_attr(*node);
(*node)->ct_pair = p;
- *dirtyp = (*node)->dirty; // deserialize could mark the node as dirty
- // (presumably for upgrade)
+ *dirtyp = (*node)->dirty(); // deserialize could mark the node as dirty
+ // (presumably for upgrade)
}
return r;
}
@@ -870,7 +870,7 @@ void toku_ftnode_pe_est_callback(
paranoid_invariant(ftnode_pv != NULL);
long bytes_to_free = 0;
FTNODE node = static_cast<FTNODE>(ftnode_pv);
- if (node->dirty || node->height == 0 ||
+ if (node->dirty() || node->height == 0 ||
node->layout_version_read_from_disk < FT_FIRST_LAYOUT_VERSION_WITH_BASEMENT_NODES) {
*bytes_freed_estimate = 0;
*cost = PE_CHEAP;
@@ -947,7 +947,7 @@ int toku_ftnode_pe_callback(void *ftnode_pv,
void *pointers_to_free[node->n_children * 2];
// Don't partially evict dirty nodes
- if (node->dirty) {
+ if (node->dirty()) {
goto exit;
}
// Don't partially evict nodes whose partitions can't be read back
@@ -1400,7 +1400,7 @@ ft_init_new_root(FT ft, FTNODE oldroot, FTNODE *newrootp)
MSN msna = oldroot->max_msn_applied_to_node_on_disk;
newroot->max_msn_applied_to_node_on_disk = msna;
BP_STATE(newroot,0) = PT_AVAIL;
- newroot->dirty = 1;
+ newroot->set_dirty();
// Set the first child to have the new blocknum,
// and then swap newroot with oldroot. The new root
@@ -1488,7 +1488,7 @@ static void inject_message_in_locked_node(
// mark the node as dirty.
// enforcing invariant here.
//
- paranoid_invariant(node->dirty != 0);
+ paranoid_invariant(node->dirty() != 0);
// update some status variables
if (node->height != 0) {
@@ -1848,7 +1848,7 @@ static void push_something_in_subtree(
}
}
- if (next_loc != NEITHER_EXTREME || child->dirty || toku_bnc_should_promote(ft, bnc)) {
+ if (next_loc != NEITHER_EXTREME || child->dirty() || toku_bnc_should_promote(ft, bnc)) {
push_something_in_subtree(ft, child, -1, msg, flow_deltas, gc_info, depth + 1, next_loc, false);
toku_sync_fetch_and_add(&bnc->flow[0], flow_deltas[0]);
// The recursive call unpinned the child, but
@@ -2803,9 +2803,9 @@ static int ft_create_file(FT_HANDLE UU(ft_handle), const char *fname, int *fdp)
}
// open a file for use by the ft. if the file does not exist, error
-static int ft_open_file(const char *fname, int *fdp) {
+static int ft_open_file(const char *fname, int *fdp, bool rw) {
int fd;
- fd = ft_open_maybe_direct(fname, O_RDWR | O_BINARY, file_mode);
+ fd = ft_open_maybe_direct(fname, (rw ? O_RDWR : O_RDONLY) | O_BINARY, file_mode);
if (fd==-1) {
return get_error_errno();
}
@@ -2956,7 +2956,7 @@ toku_ft_handle_inherit_options(FT_HANDLE t, FT ft) {
// The checkpointed version (checkpoint_lsn) of the dictionary must be no later than max_acceptable_lsn .
// Requires: The multi-operation client lock must be held to prevent a checkpoint from occuring.
static int
-ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only_create, CACHETABLE cachetable, TOKUTXN txn, FILENUM use_filenum, DICTIONARY_ID use_dictionary_id, LSN max_acceptable_lsn) {
+ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only_create, CACHETABLE cachetable, TOKUTXN txn, FILENUM use_filenum, DICTIONARY_ID use_dictionary_id, LSN max_acceptable_lsn, bool open_rw = true) {
int r;
bool txn_created = false;
char *fname_in_cwd = NULL;
@@ -2978,7 +2978,7 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
fname_in_cwd = toku_cachetable_get_fname_in_cwd(cachetable, fname_in_env);
{
int fd = -1;
- r = ft_open_file(fname_in_cwd, &fd);
+ r = ft_open_file(fname_in_cwd, &fd, open_rw);
if (reserved_filenum.fileid == FILENUM_NONE.fileid) {
reserved_filenum = toku_cachetable_reserve_filenum(cachetable);
}
@@ -3124,15 +3124,15 @@ toku_ft_handle_open_recovery(FT_HANDLE t, const char *fname_in_env, int is_creat
// Open an ft in normal use. The FILENUM and dict_id are assigned by the ft_handle_open() function.
// Requires: The multi-operation client lock must be held to prevent a checkpoint from occuring.
int
-toku_ft_handle_open(FT_HANDLE t, const char *fname_in_env, int is_create, int only_create, CACHETABLE cachetable, TOKUTXN txn) {
+toku_ft_handle_open(FT_HANDLE t, const char *fname_in_env, int is_create, int only_create, CACHETABLE cachetable, TOKUTXN txn, bool open_rw) {
int r;
- r = ft_handle_open(t, fname_in_env, is_create, only_create, cachetable, txn, FILENUM_NONE, DICTIONARY_ID_NONE, MAX_LSN);
+ r = ft_handle_open(t, fname_in_env, is_create, only_create, cachetable, txn, FILENUM_NONE, DICTIONARY_ID_NONE, MAX_LSN, open_rw);
return r;
}
// clone an ft handle. the cloned handle has a new dict_id but refers to the same fractal tree
int
-toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn) {
+toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn, bool open_rw) {
FT_HANDLE result_ft_handle;
toku_ft_handle_create(&result_ft_handle);
@@ -3147,7 +3147,7 @@ toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN t
CACHEFILE cf = ft_handle->ft->cf;
CACHETABLE ct = toku_cachefile_get_cachetable(cf);
const char *fname_in_env = toku_cachefile_fname_in_env(cf);
- int r = toku_ft_handle_open(result_ft_handle, fname_in_env, false, false, ct, txn);
+ int r = toku_ft_handle_open(result_ft_handle, fname_in_env, false, false, ct, txn, open_rw);
if (r != 0) {
toku_ft_handle_close(result_ft_handle);
result_ft_handle = NULL;
@@ -3548,7 +3548,7 @@ unlock_ftnode_fun (void *v) {
int r = toku_cachetable_unpin_ct_prelocked_no_flush(
ft_handle->ft->cf,
node->ct_pair,
- (enum cachetable_dirty) node->dirty,
+ (enum cachetable_dirty) node->dirty(),
x->msgs_applied ? make_ftnode_pair_attr(node) : make_invalid_pair_attr()
);
assert_zero(r);
@@ -4970,6 +4970,14 @@ static void toku_pfs_keys_destroy(void) {
}
int toku_ft_layer_init(void) {
+ static bool ft_layer_init_started = false;
+
+ if(ft_layer_init_started) {
+ return 0;
+ }
+
+ ft_layer_init_started = true;
+
int r = 0;
// Portability must be initialized first
@@ -5000,6 +5008,14 @@ exit:
}
void toku_ft_layer_destroy(void) {
+ static bool ft_layer_destroy_started = false;
+
+ if(ft_layer_destroy_started) {
+ return;
+ }
+
+ ft_layer_destroy_started = true;
+
toku_mutex_destroy(&ft_open_close_lock);
toku_ft_serialize_layer_destroy();
toku_checkpoint_destroy();
diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.h b/storage/tokudb/PerconaFT/ft/ft-ops.h
index df8ffe287df..7b6d0634c37 100644
--- a/storage/tokudb/PerconaFT/ft/ft-ops.h
+++ b/storage/tokudb/PerconaFT/ft/ft-ops.h
@@ -125,12 +125,12 @@ typedef int (*ft_update_func)(DB *db, const DBT *key, const DBT *old_val, const
void toku_ft_set_update(FT_HANDLE ft_h, ft_update_func update_fun);
int toku_ft_handle_open(FT_HANDLE, const char *fname_in_env,
- int is_create, int only_create, CACHETABLE ct, TOKUTXN txn) __attribute__ ((warn_unused_result));
+ int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, bool open_rw=true) __attribute__ ((warn_unused_result));
int toku_ft_handle_open_recovery(FT_HANDLE, const char *fname_in_env, int is_create, int only_create, CACHETABLE ct, TOKUTXN txn,
FILENUM use_filenum, LSN max_acceptable_lsn) __attribute__ ((warn_unused_result));
// clone an ft handle. the cloned handle has a new dict_id but refers to the same fractal tree
-int toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn);
+int toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn, bool open_rw=true);
// close an ft handle during normal operation. the underlying ft may or may not close,
// depending if there are still references. an lsn for this close will come from the logger.
diff --git a/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc b/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc
index e31d80772d5..3b5501b66d3 100644
--- a/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc
@@ -98,7 +98,7 @@ int toku_ft_recount_rows(FT_HANDLE ft,
if (rre._cancelled == false) {
// update ft count
toku_unsafe_set(&ft->ft->in_memory_logical_rows, rre._keys);
- ft->ft->h->dirty = 1;
+ ft->ft->h->set_dirty();
ret = 0;
}
diff --git a/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc b/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
index a82d8a80718..ad1dda01760 100644
--- a/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
@@ -259,7 +259,7 @@ int toku_testsetup_insert_to_nonleaf (FT_HANDLE ft_handle, BLOCKNUM blocknum, en
// is directly queueing something in a FIFO instead of
// using ft APIs.
node->max_msn_applied_to_node_on_disk = msn;
- node->dirty = 1;
+ node->set_dirty();
// Also hack max_msn_in_ft
ft_handle->ft->h->max_msn_in_ft = msn;
diff --git a/storage/tokudb/PerconaFT/ft/ft-verify.cc b/storage/tokudb/PerconaFT/ft/ft-verify.cc
index 7e3a64f441e..4f6e07e61f2 100644
--- a/storage/tokudb/PerconaFT/ft/ft-verify.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-verify.cc
@@ -512,7 +512,7 @@ toku_verify_ft_with_progress (FT_HANDLE ft_handle, int (*progress_callback)(void
if (r == 0) {
toku_ft_lock(ft_handle->ft);
ft_handle->ft->h->time_of_last_verification = time(NULL);
- ft_handle->ft->h->dirty = 1;
+ ft_handle->ft->h->set_dirty();
toku_ft_unlock(ft_handle->ft);
}
return r;
diff --git a/storage/tokudb/PerconaFT/ft/ft.cc b/storage/tokudb/PerconaFT/ft/ft.cc
index c7c2ea33c9e..1106abfbfb4 100644
--- a/storage/tokudb/PerconaFT/ft/ft.cc
+++ b/storage/tokudb/PerconaFT/ft/ft.cc
@@ -61,7 +61,7 @@ void toku_reset_root_xid_that_created(FT ft, TXNID new_root_xid_that_created) {
// (see cooperative use of dirty bit in ft_begin_checkpoint())
toku_ft_lock(ft);
ft->h->root_xid_that_created = new_root_xid_that_created;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -147,7 +147,7 @@ static void ft_begin_checkpoint (LSN checkpoint_lsn, void *header_v) {
assert(ft->h->type == FT_CURRENT);
assert(ft->checkpoint_header == NULL);
ft_copy_for_checkpoint_unlocked(ft, checkpoint_lsn);
- ft->h->dirty = 0; // this is only place this bit is cleared (in currentheader)
+ ft->h->clear_dirty(); // this is only place this bit is cleared (in currentheader)
ft->blocktable.note_start_checkpoint_unlocked();
toku_ft_unlock (ft);
}
@@ -186,7 +186,7 @@ static void ft_checkpoint (CACHEFILE cf, int fd, void *header_v) {
FT_HEADER ch = ft->checkpoint_header;
assert(ch);
assert(ch->type == FT_CHECKPOINT_INPROGRESS);
- if (ch->dirty) { // this is only place this bit is tested (in checkpoint_header)
+ if (ch->dirty()) { // this is only place this bit is tested (in checkpoint_header)
TOKULOGGER logger = toku_cachefile_logger(cf);
if (logger) {
toku_logger_fsync_if_lsn_not_fsynced(logger, ch->checkpoint_lsn);
@@ -201,7 +201,7 @@ static void ft_checkpoint (CACHEFILE cf, int fd, void *header_v) {
// write translation and header to disk (or at least to OS internal buffer)
toku_serialize_ft_to(fd, ch, &ft->blocktable, ft->cf);
- ch->dirty = 0; // this is only place this bit is cleared (in checkpoint_header)
+ ch->clear_dirty(); // this is only place this bit is cleared (in checkpoint_header)
// fsync the cachefile
toku_cachefile_fsync(cf);
@@ -255,7 +255,7 @@ static void ft_close(CACHEFILE cachefile, int fd, void *header_v, bool oplsn_val
toku_log_fclose(
logger,
&lsn,
- ft->h->dirty,
+ ft->h->dirty(),
bs,
toku_cachefile_filenum(cachefile)); // flush the log on
// close (if new header
@@ -266,7 +266,7 @@ static void ft_close(CACHEFILE cachefile, int fd, void *header_v, bool oplsn_val
}
}
}
- if (ft->h->dirty) { // this is the only place this bit is tested (in currentheader)
+ if (ft->h->dirty()) { // this is the only place this bit is tested (in currentheader)
bool do_checkpoint = true;
if (logger && logger->rollback_cachefile == cachefile) {
do_checkpoint = false;
@@ -275,7 +275,7 @@ static void ft_close(CACHEFILE cachefile, int fd, void *header_v, bool oplsn_val
ft_begin_checkpoint(lsn, header_v);
ft_checkpoint(cachefile, fd, ft);
ft_end_checkpoint(cachefile, fd, header_v);
- assert(!ft->h->dirty); // dirty bit should be cleared by begin_checkpoint and never set again (because we're closing the dictionary)
+ assert(!ft->h->dirty()); // dirty bit should be cleared by begin_checkpoint and never set again (because we're closing the dictionary)
}
}
}
@@ -371,7 +371,7 @@ ft_header_create(FT_OPTIONS options, BLOCKNUM root_blocknum, TXNID root_xid_that
uint64_t now = (uint64_t) time(NULL);
struct ft_header h = {
.type = FT_CURRENT,
- .dirty = 0,
+ .dirty_ = 0,
.checkpoint_count = 0,
.checkpoint_lsn = ZERO_LSN,
.layout_version = FT_LAYOUT_VERSION,
@@ -522,7 +522,7 @@ toku_ft_note_hot_begin(FT_HANDLE ft_handle) {
toku_ft_lock(ft);
ft->h->time_of_last_optimize_begin = now;
ft->h->count_of_optimize_in_progress++;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -546,7 +546,7 @@ toku_ft_note_hot_complete(FT_HANDLE ft_handle, bool success, MSN msn_at_start_of
if (ft->h->count_of_optimize_in_progress == ft->h->count_of_optimize_in_progress_read_from_disk)
ft->h->count_of_optimize_in_progress = 0;
}
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -959,7 +959,7 @@ void toku_ft_remove_reference(
void toku_ft_set_nodesize(FT ft, unsigned int nodesize) {
toku_ft_lock(ft);
ft->h->nodesize = nodesize;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -972,7 +972,7 @@ void toku_ft_get_nodesize(FT ft, unsigned int *nodesize) {
void toku_ft_set_basementnodesize(FT ft, unsigned int basementnodesize) {
toku_ft_lock(ft);
ft->h->basementnodesize = basementnodesize;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -985,7 +985,7 @@ void toku_ft_get_basementnodesize(FT ft, unsigned int *basementnodesize) {
void toku_ft_set_compression_method(FT ft, enum toku_compression_method method) {
toku_ft_lock(ft);
ft->h->compression_method = method;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -998,7 +998,7 @@ void toku_ft_get_compression_method(FT ft, enum toku_compression_method *methodp
void toku_ft_set_fanout(FT ft, unsigned int fanout) {
toku_ft_lock(ft);
ft->h->fanout = fanout;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
diff --git a/storage/tokudb/PerconaFT/ft/ft.h b/storage/tokudb/PerconaFT/ft/ft.h
index ff0b63b2b12..5c6caead978 100644
--- a/storage/tokudb/PerconaFT/ft/ft.h
+++ b/storage/tokudb/PerconaFT/ft/ft.h
@@ -184,11 +184,11 @@ void tokuft_update_product_name_strings(void);
extern char toku_product_name[TOKU_MAX_PRODUCT_NAME_LENGTH];
struct toku_product_name_strings_struct {
- char db_version[sizeof(toku_product_name) + sizeof("1.2.3 build ") + 256];
- char environmentdictionary[sizeof(toku_product_name) + sizeof(".environment")];
- char fileopsdirectory[sizeof(toku_product_name) + sizeof(".directory")];
- char single_process_lock[sizeof(toku_product_name) + sizeof("___lock_dont_delete_me")];
- char rollback_cachefile[sizeof(toku_product_name) + sizeof(".rollback")];
+ char db_version[sizeof(toku_product_name) + sizeof("1.2.3 build ") + 256 + 1];
+ char environmentdictionary[sizeof(toku_product_name) + sizeof(".environment") + 1];
+ char fileopsdirectory[sizeof(toku_product_name) + sizeof(".directory") + 1];
+ char single_process_lock[sizeof(toku_product_name) + sizeof("___lock_dont_delete_me") + 1];
+ char rollback_cachefile[sizeof(toku_product_name) + sizeof(".rollback") + 1];
};
extern struct toku_product_name_strings_struct toku_product_name_strings;
diff --git a/storage/tokudb/PerconaFT/ft/logger/logger.cc b/storage/tokudb/PerconaFT/ft/logger/logger.cc
index 9516f46df28..3965714e8cb 100644
--- a/storage/tokudb/PerconaFT/ft/logger/logger.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/logger.cc
@@ -50,6 +50,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/status.h"
+int writing_rollback = 0;
+extern "C" {
+ uint force_recovery = 0;
+}
+
static const int log_format_version = TOKU_LOG_VERSION;
toku_instr_key *result_output_condition_lock_mutex_key;
@@ -232,6 +237,7 @@ void toku_logger_initialize_rollback_cache(TOKULOGGER logger, FT ft) {
}
int toku_logger_open_rollback(TOKULOGGER logger, CACHETABLE cachetable, bool create) {
+ writing_rollback++;
assert(logger->is_open);
assert(!logger->rollback_cachefile);
@@ -251,6 +257,7 @@ int toku_logger_open_rollback(TOKULOGGER logger, CACHETABLE cachetable, bool cre
} else {
toku_ft_handle_close(ft_handle);
}
+ writing_rollback--;
return r;
}
@@ -268,20 +275,20 @@ void toku_logger_close_rollback_check_empty(TOKULOGGER logger, bool clean_shutdo
FT CAST_FROM_VOIDP(ft, toku_cachefile_get_userdata(cf));
if (clean_shutdown) {
//Verify it is safe to close it.
- assert(!ft->h->dirty); //Must not be dirty.
+ assert(!ft->h->dirty()); //Must not be dirty.
ft->blocktable.free_unused_blocknums(ft->h->root_blocknum);
// Must have no data blocks (rollback logs or otherwise).
ft->blocktable.verify_no_data_blocks_except_root(ft->h->root_blocknum);
- assert(!ft->h->dirty);
+ assert(!ft->h->dirty());
} else {
- ft->h->dirty = 0;
+ ft->h->clear_dirty();
}
ft_to_close = toku_ft_get_only_existing_ft_handle(ft);
if (clean_shutdown) {
bool is_empty;
is_empty = toku_ft_is_empty_fast(ft_to_close);
assert(is_empty);
- assert(!ft->h->dirty); // it should not have been dirtied by the toku_ft_is_empty test.
+ assert(!ft->h->dirty()); // it should not have been dirtied by the toku_ft_is_empty test.
}
}
diff --git a/storage/tokudb/PerconaFT/ft/node.cc b/storage/tokudb/PerconaFT/ft/node.cc
index 8db2f895033..88f46c7812b 100644
--- a/storage/tokudb/PerconaFT/ft/node.cc
+++ b/storage/tokudb/PerconaFT/ft/node.cc
@@ -78,7 +78,7 @@ void toku_initialize_empty_ftnode(FTNODE n, BLOCKNUM blocknum, int height, int n
}
}
}
- n->dirty = 1; // special case exception, it's okay to mark as dirty because the basements are empty
+ n->set_dirty(); // special case exception, it's okay to mark as dirty because the basements are empty
toku_ft_status_note_ftnode(height, true);
}
@@ -154,7 +154,7 @@ void toku_ftnode_clone_partitions(FTNODE node, FTNODE cloned_node) {
void toku_evict_bn_from_memory(FTNODE node, int childnum, FT ft) {
// free the basement node
- assert(!node->dirty);
+ assert(!node->dirty());
BASEMENTNODE bn = BLB(node, childnum);
toku_ft_decrease_stats(&ft->in_memory_stats, bn->stat64_delta);
toku_ft_adjust_logical_row_count(ft, -BLB_LRD(node, childnum));
@@ -596,7 +596,7 @@ toku_apply_ancestors_messages_to_node (
oldest_referenced_xid_for_simple_gc,
node->oldest_referenced_xid_known,
true);
- if (!node->dirty && child_to_read >= 0) {
+ if (!node->dirty() && child_to_read >= 0) {
paranoid_invariant(BP_STATE(node, child_to_read) == PT_AVAIL);
apply_ancestors_messages_to_bn(
t,
@@ -713,7 +713,7 @@ bool toku_ft_leaf_needs_ancestors_messages(
paranoid_invariant(node->height == 0);
bool needs_ancestors_messages = false;
// child_to_read may be -1 in test cases
- if (!node->dirty && child_to_read >= 0) {
+ if (!node->dirty() && child_to_read >= 0) {
paranoid_invariant(BP_STATE(node, child_to_read) == PT_AVAIL);
needs_ancestors_messages = bn_needs_ancestors_messages(
ft,
@@ -746,7 +746,7 @@ cleanup:
void toku_ft_bn_update_max_msn(FTNODE node, MSN max_msn_applied, int child_to_read) {
invariant(node->height == 0);
- if (!node->dirty && child_to_read >= 0) {
+ if (!node->dirty() && child_to_read >= 0) {
paranoid_invariant(BP_STATE(node, child_to_read) == PT_AVAIL);
BASEMENTNODE bn = BLB(node, child_to_read);
if (max_msn_applied.msn > bn->max_msn_applied.msn) {
@@ -833,7 +833,7 @@ struct rebalance_array_info {
void toku_ftnode_leaf_rebalance(FTNODE node, unsigned int basementnodesize) {
assert(node->height == 0);
- assert(node->dirty);
+ assert(node->dirty());
uint32_t num_orig_basements = node->n_children;
// Count number of leaf entries in this leaf (num_le).
@@ -1142,7 +1142,7 @@ void toku_ft_nonleaf_append_child(FTNODE node, FTNODE child, const DBT *pivotkey
invariant(childnum > 0);
node->pivotkeys.insert_at(pivotkey, childnum - 1);
}
- node->dirty = 1;
+ node->set_dirty();
}
void
@@ -1745,7 +1745,7 @@ static void ft_append_msg_to_child_buffer(const toku::comparator &cmp, FTNODE no
int childnum, const ft_msg &msg, bool is_fresh) {
paranoid_invariant(BP_STATE(node,childnum) == PT_AVAIL);
bnc_insert_msg(BNC(node, childnum), msg, is_fresh, cmp);
- node->dirty = 1;
+ node->set_dirty();
}
// This is only exported for tests.
@@ -2090,7 +2090,7 @@ void toku_ft_leaf_apply_msg(
// be reapplied later), we mark the node as dirty and
// take the opportunity to update node->max_msn_applied_to_node_on_disk.
//
- node->dirty = 1;
+ node->set_dirty();
//
// we cannot blindly update node->max_msn_applied_to_node_on_disk,
diff --git a/storage/tokudb/PerconaFT/ft/node.h b/storage/tokudb/PerconaFT/ft/node.h
index 05c8a44ebed..61093f3ed8d 100644
--- a/storage/tokudb/PerconaFT/ft/node.h
+++ b/storage/tokudb/PerconaFT/ft/node.h
@@ -155,6 +155,12 @@ private:
size_t _total_size;
};
+extern int writing_rollback;
+
+extern "C" {
+extern uint force_recovery;
+}
+
// TODO: class me up
struct ftnode {
// max_msn_applied that will be written to disk
@@ -173,9 +179,22 @@ struct ftnode {
uint32_t build_id;
// height is always >= 0. 0 for leaf, >0 for nonleaf.
int height;
- int dirty;
+ int dirty_;
uint32_t fullhash;
+ void set_dirty() {
+ if(force_recovery) assert(writing_rollback);
+ dirty_ = 1;
+ }
+
+ void clear_dirty() {
+ dirty_ = 0;
+ }
+
+ bool dirty() {
+ return dirty_;
+ }
+
// for internal nodes, if n_children==fanout+1 then the tree needs to be
// rebalanced. for leaf nodes, represents number of basement nodes
int n_children;
diff --git a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
index 811f86c30a7..e3606c11294 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
@@ -196,9 +196,9 @@ static void ft_set_dirty(FT ft, bool for_checkpoint) {
invariant(ft->h->type == FT_CURRENT);
if (for_checkpoint) {
invariant(ft->checkpoint_header->type == FT_CHECKPOINT_INPROGRESS);
- ft->checkpoint_header->dirty = 1;
+ ft->checkpoint_header->set_dirty();
} else {
- ft->h->dirty = 1;
+ ft->h->set_dirty();
}
}
diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc
index 02a9dfd085c..de58fb42a8b 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc
@@ -60,7 +60,7 @@ initialize_ftnode(FTNODE node, BLOCKNUM blocknum)
{
node->fullhash = 0xDEADBEEF; // <CER> Is this 'spoof' ok?
node->blocknum = blocknum;
- node->dirty = 0;
+ node->clear_dirty();
node->bp = NULL;
// <CER> Can we use this initialization as a correctness assert in
// a later function?
diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
index 0d6573972d7..0813855bf55 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
@@ -340,7 +340,7 @@ int deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version)
{
struct ft_header h = {
.type = FT_CURRENT,
- .dirty = 0,
+ .dirty_ = 0,
.checkpoint_count = checkpoint_count,
.checkpoint_lsn = checkpoint_lsn,
.layout_version = FT_LAYOUT_VERSION,
diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc
index f3b31eb31be..e6648b76bf0 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc
@@ -827,7 +827,7 @@ int toku_serialize_ftnode_to(int fd,
node, n_uncompressed_bytes, n_to_write, io_time, for_checkpoint);
toku_free(compressed_buf);
- node->dirty = 0; // See #1957. Must set the node to be clean after
+ node->clear_dirty(); // See #1957. Must set the node to be clean after
// serializing it so that it doesn't get written again on
// the next checkpoint or eviction.
if (node->height == 0) {
@@ -1544,7 +1544,7 @@ static FTNODE alloc_ftnode_for_deserialize(uint32_t fullhash, BLOCKNUM blocknum)
FTNODE XMALLOC(node);
node->fullhash = fullhash;
node->blocknum = blocknum;
- node->dirty = 0;
+ node->clear_dirty();
node->oldest_referenced_xid_known = TXNID_NONE;
node->bp = nullptr;
node->ct_pair = nullptr;
@@ -1951,7 +1951,7 @@ static int deserialize_and_upgrade_internal_node(FTNODE node,
// Assign the highest msn from our upgrade message buffers
node->max_msn_applied_to_node_on_disk = highest_msn;
// Since we assigned MSNs to this node's messages, we need to dirty it.
- node->dirty = 1;
+ node->set_dirty();
// Must compute the checksum now (rather than at the end, while we
// still have the pointer to the buffer).
@@ -2908,9 +2908,9 @@ int toku_serialize_rollback_log_to(int fd,
toku_free(compressed_buf);
if (!is_serialized) {
toku_static_serialized_rollback_log_destroy(&serialized_local);
- log->dirty = 0; // See #1957. Must set the node to be clean after
- // serializing it so that it doesn't get written again
- // on the next checkpoint or eviction.
+ log->dirty = false; // See #1957. Must set the node to be clean after
+ // serializing it so that it doesn't get written again
+ // on the next checkpoint or eviction.
}
return 0;
}
diff --git a/storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h b/storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h
index eb8c953b08c..31ffd7e1617 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h
+++ b/storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h
@@ -193,6 +193,7 @@ namespace MhsRbTree {
BlockPair(OUUInt64 o, OUUInt64 s) : _offset(o), _size(s) {}
BlockPair(const BlockPair &o)
: _offset(o._offset), _size(o._size) {}
+ BlockPair& operator=(const BlockPair&) = default;
int operator<(const BlockPair &rhs) const {
return _offset < rhs._offset;
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc
index c1c4cb4f16e..a13e6d26d15 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc
@@ -195,13 +195,13 @@ static void test_multiple_cachefiles(bool use_same_hash) {
char fname1[strlen(TOKU_TEST_FILENAME) + sizeof("_1")];
strcpy(fname1, TOKU_TEST_FILENAME);
- strncat(fname1, "_1", sizeof("_1"));
+ strcat(fname1, "_1");
char fname2[strlen(TOKU_TEST_FILENAME) + sizeof("_2")];
strcpy(fname2, TOKU_TEST_FILENAME);
- strncat(fname2, "_2", sizeof("_2"));
+ strcat(fname2, "_2");
char fname3[strlen(TOKU_TEST_FILENAME) + sizeof("_3")];
strcpy(fname3, TOKU_TEST_FILENAME);
- strncat(fname3, "_3", sizeof("_3"));
+ strcat(fname3, "_3");
unlink(fname1);
unlink(fname2);
@@ -280,10 +280,10 @@ static void test_evictor(void) {
char fname1[strlen(TOKU_TEST_FILENAME) + sizeof("_1")];
strcpy(fname1, TOKU_TEST_FILENAME);
- strncat(fname1, "_1", sizeof("_1"));
+ strcat(fname1, "_1");
char fname2[strlen(TOKU_TEST_FILENAME) + sizeof("_2")];
strcpy(fname2, TOKU_TEST_FILENAME);
- strncat(fname2, "_2", sizeof("_2"));
+ strcat(fname2, "_2");
unlink(fname1);
unlink(fname2);
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc b/storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc
index 7abd2267a7e..1d6bc2fba7a 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc
@@ -337,7 +337,7 @@ static void test_prefetching(void) {
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 1;
sn.n_children = 3;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
uint64_t key1 = 100;
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc b/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
index 00ff8cf204b..1a708b8e3cc 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
@@ -133,7 +133,7 @@ static void test1(int fd, FT ft_h, FTNODE *dn) {
for (int i = 0; i < (*dn)->n_children; i++) {
invariant(BP_STATE(*dn, i) == PT_AVAIL);
}
- (*dn)->dirty = 1;
+ (*dn)->set_dirty();
toku_ftnode_pe_callback(*dn, attr, ft_h, def_pe_finalize_impl, nullptr);
toku_ftnode_pe_callback(*dn, attr, ft_h, def_pe_finalize_impl, nullptr);
toku_ftnode_pe_callback(*dn, attr, ft_h, def_pe_finalize_impl, nullptr);
@@ -246,7 +246,7 @@ static void test_serialize_nonleaf(void) {
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 1;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(2, sn.bp);
DBT pivotkey;
@@ -384,7 +384,7 @@ static void test_serialize_leaf(void) {
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkey;
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc b/storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc
index d50488ae197..bd5df7862cd 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc
@@ -95,7 +95,7 @@ static void test_serialize_leaf(int valsize,
sn->layout_version_original = FT_LAYOUT_VERSION;
sn->height = 0;
sn->n_children = 8;
- sn->dirty = 1;
+ sn->set_dirty();
sn->oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn->n_children, sn->bp);
sn->pivotkeys.create_empty();
@@ -173,7 +173,7 @@ static void test_serialize_leaf(int valsize,
for (int i = 0; i < ser_runs; i++) {
gettimeofday(&t[0], NULL);
ndd = NULL;
- sn->dirty = 1;
+ sn->set_dirty();
r = toku_serialize_ftnode_to(
fd, make_blocknum(20), sn, &ndd, true, ft->ft, false);
invariant(r == 0);
@@ -265,7 +265,7 @@ static void test_serialize_nonleaf(int valsize,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 1;
sn.n_children = 8;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
sn.pivotkeys.create_empty();
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc b/storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc
index 0cddaf19651..4fca8efad35 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc
@@ -238,7 +238,7 @@ static void test_serialize_leaf_check_msn(enum ftnode_verify_type bft,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkey;
@@ -381,7 +381,7 @@ static void test_serialize_leaf_with_large_pivots(enum ftnode_verify_type bft,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = nrows;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
@@ -538,7 +538,7 @@ static void test_serialize_leaf_with_many_rows(enum ftnode_verify_type bft,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 1;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
XMALLOC_N(sn.n_children, sn.bp);
@@ -693,7 +693,7 @@ static void test_serialize_leaf_with_large_rows(enum ftnode_verify_type bft,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 1;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
@@ -845,7 +845,7 @@ static void test_serialize_leaf_with_empty_basement_nodes(
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 7;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkeys[6];
@@ -989,7 +989,7 @@ static void test_serialize_leaf_with_multiple_empty_basement_nodes(
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 4;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkeys[3];
@@ -1100,7 +1100,7 @@ static void test_serialize_nonleaf(enum ftnode_verify_type bft, bool do_clone) {
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 1;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(2, sn.bp);
DBT pivotkey;
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc b/storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc
index a23a3a60879..c668b9410c9 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc
@@ -57,7 +57,7 @@ static void test_header (void) {
assert(r==0);
// now insert some info into the header
FT ft = t->ft;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
// cast away const because we actually want to fiddle with the header
// in this test
*((int *) &ft->h->layout_version_original) = 13;
diff --git a/storage/tokudb/PerconaFT/ft/tests/make-tree.cc b/storage/tokudb/PerconaFT/ft/tests/make-tree.cc
index 761d672539b..fe950b60972 100644
--- a/storage/tokudb/PerconaFT/ft/tests/make-tree.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/make-tree.cc
@@ -88,7 +88,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
leafnode->max_msn_applied_to_node_on_disk = msn;
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/mempool-115.cc b/storage/tokudb/PerconaFT/ft/tests/mempool-115.cc
index e3a3bfa28dc..bf9a1aa1484 100644
--- a/storage/tokudb/PerconaFT/ft/tests/mempool-115.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/mempool-115.cc
@@ -102,7 +102,7 @@ public:
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkey;
diff --git a/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc b/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc
index c37dcd089f8..6d13eabfd93 100644
--- a/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc
@@ -161,7 +161,7 @@ append_leaf(FT_HANDLE ft, FTNODE leafnode, void *key, uint32_t keylen, void *val
}
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc b/storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc
index 8ac1cd62c50..02dc63fca7e 100644
--- a/storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc
@@ -49,9 +49,9 @@ static void test_5123(void) {
test_setup(TOKU_TEST_FILENAME, &logger, &ct);
int r;
- TXNID_PAIR one = {.parent_id64 = (TXNID)1, TXNID_NONE};
- TXNID_PAIR two = {.parent_id64 = (TXNID)2, TXNID_NONE};
- TXNID_PAIR three = {.parent_id64 = (TXNID)3, TXNID_NONE};
+ TXNID_PAIR one = { (TXNID)1, TXNID_NONE};
+ TXNID_PAIR two = { (TXNID)2, TXNID_NONE};
+ TXNID_PAIR three = { (TXNID)3, TXNID_NONE};
toku_log_xbegin(logger, NULL, false, one, TXNID_PAIR_NONE);
toku_log_xbegin(logger, NULL, false, three, TXNID_PAIR_NONE);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
index 06a26614885..5c73d281b98 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
@@ -245,7 +245,7 @@ doit (bool after_child_pin) {
true
);
assert(node->height == 1);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
if (after_child_pin) {
assert(toku_bnc_nbytesinbuf(BNC(node, 0)) == 0);
@@ -265,7 +265,7 @@ doit (bool after_child_pin) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
if (after_child_pin) {
assert(BLB_NBYTESINDATA(node,0) > 0);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
index 1029dfef320..cab370274cb 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
@@ -270,7 +270,7 @@ doit (int state) {
true
);
assert(node->height == 1);
- assert(!node->dirty);
+ assert(!node->dirty());
BLOCKNUM left_child, right_child;
// cases where we expect the checkpoint to contain the merge
if (state == ft_flush_aflter_merge || state == flt_flush_before_unpin_remove) {
@@ -301,7 +301,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 1);
toku_unpin_ftnode(c_ft->ft, node);
@@ -318,7 +318,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 1);
toku_unpin_ftnode(c_ft->ft, node);
@@ -336,7 +336,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 2);
toku_unpin_ftnode(c_ft->ft, node);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
index 208ebe3ca31..87f66512642 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
@@ -284,7 +284,7 @@ doit (int state) {
true
);
assert(node->height == 1);
- assert(!node->dirty);
+ assert(!node->dirty());
BLOCKNUM left_child, right_child;
assert(node->n_children == 2);
@@ -304,7 +304,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 2);
toku_unpin_ftnode(c_ft->ft, node);
@@ -319,7 +319,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 2);
toku_unpin_ftnode(c_ft->ft, node);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
index 2b29de409b1..d5f7fe50f46 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
@@ -260,7 +260,7 @@ doit (bool after_split) {
true
);
assert(node->height == 1);
- assert(!node->dirty);
+ assert(!node->dirty());
BLOCKNUM left_child, right_child;
if (after_split) {
assert(node->n_children == 2);
@@ -287,7 +287,7 @@ doit (bool after_split) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 1);
toku_unpin_ftnode(c_ft->ft, node);
@@ -302,7 +302,7 @@ doit (bool after_split) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 1);
toku_unpin_ftnode(c_ft->ft, node);
@@ -318,7 +318,7 @@ doit (bool after_split) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 2);
toku_unpin_ftnode(c_ft->ft, node);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc b/storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc
index 460134ec353..e1937538471 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc
@@ -199,7 +199,7 @@ doit (void) {
&node,
true
);
- assert(node->dirty);
+ assert(node->dirty());
assert(node->n_children == 2);
assert(BP_STATE(node,0) == PT_AVAIL);
assert(BP_STATE(node,1) == PT_AVAIL);
@@ -229,7 +229,7 @@ doit (void) {
&node,
true
);
- assert(node->dirty);
+ assert(node->dirty());
assert(node->n_children == 2);
assert(BP_STATE(node,0) == PT_AVAIL);
assert(BP_STATE(node,1) == PT_AVAIL);
@@ -250,7 +250,7 @@ doit (void) {
&node,
true
);
- assert(node->dirty);
+ assert(node->dirty());
// we expect that this flushes its buffer, that
// a merge is not done, and that the lookup
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc b/storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc
index 89d7130e5f7..f9d4d1646b8 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc
@@ -203,7 +203,7 @@ doit (bool keep_other_bn_in_memory) {
&node,
true
);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 2);
// a hack to get the basement nodes evicted
for (int i = 0; i < 20; i++) {
@@ -249,7 +249,7 @@ doit (bool keep_other_bn_in_memory) {
&node,
true
);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 2);
assert(BP_STATE(node,0) == PT_AVAIL);
if (keep_other_bn_in_memory) {
@@ -273,7 +273,7 @@ doit (bool keep_other_bn_in_memory) {
&node,
true
);
- assert(!node->dirty);
+ assert(!node->dirty());
// we expect that this flushes its buffer, that
// a merge is not done, and that the lookup
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc b/storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc
index 83dfd0244f4..29d07483f99 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc
@@ -194,7 +194,7 @@ doit (void) {
toku_pin_node_with_min_bfe(&node, node_internal, t);
toku_ftnode_assert_fully_in_memory(node);
assert(node->n_children == 2);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(toku_bnc_n_entries(node->bp[0].ptr.u.nonleaf) > 0);
assert(toku_bnc_n_entries(node->bp[1].ptr.u.nonleaf) > 0);
@@ -216,7 +216,7 @@ doit (void) {
toku_pin_node_with_min_bfe(&node, node_internal, t);
toku_ftnode_assert_fully_in_memory(node);
- assert(node->dirty);
+ assert(node->dirty());
assert(node->n_children == 2);
// child 0 should have empty buffer because it flushed
// child 1 should still have message in buffer
@@ -226,14 +226,14 @@ doit (void) {
r = toku_checkpoint(cp, NULL, NULL, NULL, NULL, NULL, CLIENT_CHECKPOINT);
assert_zero(r);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(!node->dirty);
+ assert(!node->dirty());
curr_child_to_flush = 1;
num_flushes_called = 0;
toku_ft_flush_some_child(t->ft, node, &fa);
assert(num_flushes_called == 1);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(node->dirty);
+ assert(node->dirty());
toku_ftnode_assert_fully_in_memory(node);
assert(node->n_children == 2);
// both buffers should be empty now
@@ -244,14 +244,14 @@ doit (void) {
r = toku_checkpoint(cp, NULL, NULL, NULL, NULL, NULL, CLIENT_CHECKPOINT);
assert_zero(r);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(!node->dirty);
+ assert(!node->dirty());
curr_child_to_flush = 0;
num_flushes_called = 0;
toku_ft_flush_some_child(t->ft, node, &fa);
assert(num_flushes_called == 1);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(node->dirty); // nothing was flushed, but since we were trying to flush to a leaf, both become dirty
+ assert(node->dirty()); // nothing was flushed, but since we were trying to flush to a leaf, both become dirty
toku_ftnode_assert_fully_in_memory(node);
assert(node->n_children == 2);
// both buffers should be empty now
@@ -280,17 +280,17 @@ doit (void) {
assert(num_flushes_called == 2);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(node->dirty);
+ assert(node->dirty());
toku_unpin_ftnode(t->ft, node);
toku_pin_node_with_min_bfe(&node, node_leaf[0], t);
- assert(node->dirty);
+ assert(node->dirty());
toku_unpin_ftnode(t->ft, node);
toku_pin_node_with_min_bfe(&node, node_leaf[1], t);
if (i == 0) {
- assert(!node->dirty);
+ assert(!node->dirty());
}
else {
- assert(node->dirty);
+ assert(node->dirty());
}
toku_unpin_ftnode(t->ft, node);
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test3884.cc b/storage/tokudb/PerconaFT/ft/tests/test3884.cc
index cfb76424668..5de55b0daff 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test3884.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test3884.cc
@@ -105,7 +105,7 @@ setup_ftnode_header(struct ftnode *node)
node->layout_version = FT_LAYOUT_VERSION;
node->layout_version_original = FT_LAYOUT_VERSION;
node->height = 0;
- node->dirty = 1;
+ node->set_dirty();
node->oldest_referenced_xid_known = TXNID_NONE;
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc b/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc
index b10885c2e62..1ba5f1c2503 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc
@@ -93,7 +93,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
// leafnode->max_msn_applied_to_node = msn;
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc
index c1d08ce41a6..42415a07765 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc
@@ -77,7 +77,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc b/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc
index 22a29c0ff69..e31b13c4f4d 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc
@@ -78,7 +78,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc
index 80189dd9804..009eda63999 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc
@@ -77,7 +77,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc b/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc
index a84aac1f063..5c639d8d28a 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc
@@ -78,7 +78,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc
index ca413f52567..d55ec7a736f 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc
@@ -80,7 +80,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc
index 6efa06913c2..ff231001c77 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc
@@ -77,7 +77,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/txn/rollback.cc b/storage/tokudb/PerconaFT/ft/txn/rollback.cc
index 0c793842f3c..105f980dc0d 100644
--- a/storage/tokudb/PerconaFT/ft/txn/rollback.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/rollback.cc
@@ -43,6 +43,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ft/logger/log-internal.h"
#include "ft/txn/rollback-ct-callbacks.h"
+extern int writing_rollback;
+
static void rollback_unpin_remove_callback(CACHEKEY* cachekey, bool for_checkpoint, void* extra) {
FT CAST_FROM_VOIDP(ft, extra);
ft->blocktable.free_blocknum(cachekey, ft, for_checkpoint);
@@ -155,6 +157,7 @@ static void rollback_log_create (
ROLLBACK_LOG_NODE *result
)
{
+ writing_rollback++;
ROLLBACK_LOG_NODE XMALLOC(log);
rollback_empty_log_init(log);
@@ -169,6 +172,7 @@ static void rollback_log_create (
get_write_callbacks_for_rollback_log(ft),
toku_rollback_node_save_ct_pair);
txn->roll_info.current_rollback = log->blocknum;
+ writing_rollback --;
}
void toku_rollback_log_unpin(TOKUTXN txn, ROLLBACK_LOG_NODE log) {
diff --git a/storage/tokudb/PerconaFT/ft/txn/txn.cc b/storage/tokudb/PerconaFT/ft/txn/txn.cc
index 7327cbd9d24..7152833d88d 100644
--- a/storage/tokudb/PerconaFT/ft/txn/txn.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/txn.cc
@@ -723,7 +723,11 @@ time_t toku_txn_get_start_time(struct tokutxn *txn) {
return txn->start_time;
}
+extern uint force_recovery;
int toku_txn_reads_txnid(TXNID txnid, TOKUTXN txn, bool is_provisional UU()) {
+ if(force_recovery) {
+ return TOKUDB_ACCEPT;
+ }
int r = 0;
TXNID oldest_live_in_snapshot = toku_get_oldest_in_live_root_txn_list(txn);
if (oldest_live_in_snapshot == TXNID_NONE && txnid < txn->snapshot_txnid64) {
diff --git a/storage/tokudb/PerconaFT/ftcxx/cursor.hpp b/storage/tokudb/PerconaFT/ftcxx/cursor.hpp
index 9ecc4d173c6..bde5dbf2c19 100644
--- a/storage/tokudb/PerconaFT/ftcxx/cursor.hpp
+++ b/storage/tokudb/PerconaFT/ftcxx/cursor.hpp
@@ -398,8 +398,8 @@ namespace ftcxx {
{}
bool operator()(const DBT *key, const DBT *val) {
- _key = std::move(Slice(*key).owned());
- _val = std::move(Slice(*val).owned());
+ _key = Slice(*key).owned();
+ _val = Slice(*val).owned();
// Don't bulk fetch.
return false;
diff --git a/storage/tokudb/PerconaFT/locktree/lock_request.cc b/storage/tokudb/PerconaFT/locktree/lock_request.cc
index 0a95dc417d6..cc6fcafcd5d 100644
--- a/storage/tokudb/PerconaFT/locktree/lock_request.cc
+++ b/storage/tokudb/PerconaFT/locktree/lock_request.cc
@@ -93,6 +93,10 @@ void lock_request::destroy(void) {
toku_cond_destroy(&m_wait_cond);
}
+void lock_request::clearmem(char c) {
+ memset(this, c, sizeof(* this));
+}
+
// set the lock request parameters. this API allows a lock request to be reused.
void lock_request::set(locktree *lt, TXNID txnid, const DBT *left_key, const DBT *right_key, lock_request::type lock_type, bool big_txn, void *extra) {
invariant(m_state != state::PENDING);
diff --git a/storage/tokudb/PerconaFT/locktree/lock_request.h b/storage/tokudb/PerconaFT/locktree/lock_request.h
index 8b22241e276..e16e77ed6f4 100644
--- a/storage/tokudb/PerconaFT/locktree/lock_request.h
+++ b/storage/tokudb/PerconaFT/locktree/lock_request.h
@@ -89,6 +89,7 @@ public:
// effect: Destroys a lock request.
void destroy(void);
+ void clearmem(char c);
// effect: Resets the lock request parameters, allowing it to be reused.
// requires: Lock request was already created at some point
diff --git a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc
index 5c28701c49e..83436a651e1 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc
@@ -83,7 +83,7 @@ namespace toku {
}
request.destroy();
- memset(&request, 0xab, sizeof request);
+ request.clearmem(0xab);
toku_pthread_yield();
if ((i % 10) == 0)
diff --git a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc
index 8458bae6b8c..6748ae30ee1 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc
@@ -96,7 +96,7 @@ namespace toku {
}
request.destroy();
- memset(&request, 0xab, sizeof request);
+ request.clearmem(0xab);
toku_pthread_yield();
if ((i % 10) == 0)
diff --git a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc
index 4b6dadd440f..cd3dc7b37ef 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc
@@ -98,7 +98,7 @@ namespace toku {
}
request.destroy();
- memset(&request, 0xab, sizeof request);
+ request.clearmem(0xab);
toku_pthread_yield();
if ((i % 10) == 0)
diff --git a/storage/tokudb/PerconaFT/portability/portability.cc b/storage/tokudb/PerconaFT/portability/portability.cc
index 81115a516aa..556a34fb861 100644
--- a/storage/tokudb/PerconaFT/portability/portability.cc
+++ b/storage/tokudb/PerconaFT/portability/portability.cc
@@ -60,7 +60,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#if defined(HAVE_SYS_SYSCALL_H)
# include <sys/syscall.h>
#endif
-#if defined(HAVE_SYS_SYSCTL_H)
+#if defined(HAVE_SYS_SYSCTL_H) && !defined(_SC_PHYS_PAGES)
# include <sys/sysctl.h>
#endif
#if defined(HAVE_PTHREAD_H)
diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
index 786a6ef0546..0f287429542 100644
--- a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
+++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
@@ -359,7 +359,16 @@ void toku_instr_rwlock_wrlock_wait_end(
void toku_instr_rwlock_unlock(toku_pthread_rwlock_t &rwlock) {
if (rwlock.psi_rwlock)
+
+// Due to change introduced in e4148f2a22922687f7652c4e3d21a22da07c9e78
+// PSI rwlock version and interface changed
+// PSI_CURRENT_RWLOCK_VERSION is not defined in MySQL 5.6 and is defined
+// as 1 in 5.7 and < 8.0.17
+#if defined(PSI_CURRENT_RWLOCK_VERSION) && (PSI_CURRENT_RWLOCK_VERSION == 2)
+ PSI_RWLOCK_CALL(unlock_rwlock)(rwlock.psi_rwlock, PSI_RWLOCK_UNLOCK);
+#else
PSI_RWLOCK_CALL(unlock_rwlock)(rwlock.psi_rwlock);
+#endif
}
#endif // TOKU_MYSQL_WITH_PFS
diff --git a/storage/tokudb/PerconaFT/scripts/tokuvalgrind b/storage/tokudb/PerconaFT/scripts/tokuvalgrind
deleted file mode 120000
index 74517aa2975..00000000000
--- a/storage/tokudb/PerconaFT/scripts/tokuvalgrind
+++ /dev/null
@@ -1 +0,0 @@
-tokugrind \ No newline at end of file
diff --git a/storage/tokudb/PerconaFT/src/tests/test.h b/storage/tokudb/PerconaFT/src/tests/test.h
index ff464f55890..c5214961afd 100644
--- a/storage/tokudb/PerconaFT/src/tests/test.h
+++ b/storage/tokudb/PerconaFT/src/tests/test.h
@@ -428,14 +428,14 @@ static int env_del_multiple_test_no_array(
/* Some macros for evaluating blocks or functions within the scope of a
* transaction. */
#define IN_TXN_COMMIT(env, parent, txn, flags, expr) ({ \
- DB_TXN *(txn); \
+ DB_TXN *txn; \
{ int chk_r = (env)->txn_begin((env), (parent), &(txn), (flags)); CKERR(chk_r); } \
(expr); \
{ int chk_r = (txn)->commit((txn), 0); CKERR(chk_r); } \
})
#define IN_TXN_ABORT(env, parent, txn, flags, expr) ({ \
- DB_TXN *(txn); \
+ DB_TXN *txn; \
{ int chk_r = (env)->txn_begin((env), (parent), &(txn), (flags)); CKERR(chk_r); } \
(expr); \
{ int chk_r = (txn)->abort(txn); CKERR(chk_r); } \
diff --git a/storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc b/storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc
index ecd88f3c5fe..55b2943e67f 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc
@@ -68,7 +68,7 @@ seqinsert (int n, float p) {
int v = i;
DBT key, val;
r = db->put(db, 0, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); assert(r == 0);
- if (random() <= RAND_MAX * p) {
+ if (random() <= static_cast<float>(RAND_MAX) * p) {
k = htonl(i-1);
v = i-1;
r = db->put(db, 0, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); assert(r == 0);
diff --git a/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h b/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
index e232f327d10..1d8833adcba 100644
--- a/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
+++ b/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
@@ -432,17 +432,17 @@ tsv_print_perf_totals(const struct cli_args *cli_args, uint64_t *counters[], con
}
const struct perf_formatter perf_formatters[] = {
- [HUMAN] = {
+ { /* HUMAN */
.header = human_print_perf_header,
.iteration = human_print_perf_iteration,
.totals = human_print_perf_totals
},
- [CSV] = {
+ { /* CSV */
.header = csv_print_perf_header,
.iteration = csv_print_perf_iteration,
.totals = csv_print_perf_totals
},
- [TSV] = {
+ { /* TSV */
.header = tsv_print_perf_header,
.iteration = tsv_print_perf_iteration,
.totals = tsv_print_perf_totals
diff --git a/storage/tokudb/PerconaFT/src/ydb.cc b/storage/tokudb/PerconaFT/src/ydb.cc
index 58d39c50c23..1378c05b4c4 100644
--- a/storage/tokudb/PerconaFT/src/ydb.cc
+++ b/storage/tokudb/PerconaFT/src/ydb.cc
@@ -40,6 +40,9 @@ extern const char *toku_patent_string;
const char *toku_copyright_string = "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.";
#include <my_global.h>
+
+extern int writing_rollback;
+
#include <db.h>
#include <errno.h>
#include <string.h>
@@ -88,6 +91,8 @@ const char *toku_copyright_string = "Copyright (c) 2006, 2015, Percona and/or it
int toku_close_trace_file (void) { return 0; }
#endif
+extern uint force_recovery;
+
// Set when env is panicked, never cleared.
static int env_is_panicked = 0;
@@ -224,6 +229,9 @@ env_fs_redzone(DB_ENV *env, uint64_t total) {
// Check the available space in the file systems used by tokuft and erect barriers when available space gets low.
static int
env_fs_poller(void *arg) {
+ if(force_recovery == 6) {
+ return 0;
+ }
DB_ENV *env = (DB_ENV *) arg;
int r;
@@ -308,6 +316,9 @@ env_fs_init(DB_ENV *env) {
// Initialize the minicron that polls file system space
static int
env_fs_init_minicron(DB_ENV *env) {
+ if(force_recovery == 6) {
+ return 0;
+ }
int r = toku_minicron_setup(&env->i->fs_poller, env->i->fs_poll_time*1000, env_fs_poller, env);
if (r == 0)
env->i->fs_poller_is_init = true;
@@ -710,7 +721,7 @@ static int validate_env(DB_ENV *env,
}
// Test for fileops directory
- if (r == 0) {
+ if (r == 0 && force_recovery != 6) {
path = toku_construct_full_name(
2, env->i->dir, toku_product_name_strings.fileopsdirectory);
assert(path);
@@ -753,7 +764,7 @@ static int validate_env(DB_ENV *env,
}
// Test for recovery log
- if ((r == 0) && (env->i->open_flags & DB_INIT_LOG)) {
+ if ((r == 0) && (env->i->open_flags & DB_INIT_LOG) && force_recovery != 6) {
// if using transactions, test for existence of log
r = ydb_recover_log_exists(env); // return 0 or ENOENT
if (expect_newenv && (r != ENOENT))
@@ -814,6 +825,27 @@ unlock_single_process(DB_ENV *env) {
// (The set of necessary files is defined in the function validate_env() above.)
static int
env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
+
+ if(force_recovery == 6) {
+ {
+ const int len = strlen(toku_product_name_strings.rollback_cachefile);
+ toku_product_name_strings.rollback_cachefile[len] = '2';
+ toku_product_name_strings.rollback_cachefile[len+1] = 0;
+ }
+
+ {
+ const int len = strlen(toku_product_name_strings.single_process_lock);
+ toku_product_name_strings.single_process_lock[len] = '2';
+ toku_product_name_strings.single_process_lock[len+1] = 0;
+ }
+
+ {
+ const int len = strlen(toku_product_name_strings.environmentdictionary);
+ toku_product_name_strings.environmentdictionary[len] = '2';
+ toku_product_name_strings.environmentdictionary[len+1] = 0;
+ }
+ }
+
HANDLE_PANICKED_ENV(env);
int r;
bool newenv; // true iff creating a new environment
@@ -904,7 +936,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
bool need_rollback_cachefile;
need_rollback_cachefile = false;
- if (flags & (DB_INIT_TXN | DB_INIT_LOG)) {
+ if (flags & (DB_INIT_TXN | DB_INIT_LOG) && force_recovery != 6) {
need_rollback_cachefile = true;
}
@@ -917,7 +949,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
r = ydb_maybe_upgrade_env(env, &last_lsn_of_clean_shutdown_read_from_log, &upgrade_in_progress);
if (r!=0) goto cleanup;
- if (upgrade_in_progress) {
+ if (upgrade_in_progress || force_recovery == 6) {
// Delete old rollback file. There was a clean shutdown, so it has nothing useful,
// and there is no value in upgrading it. It is simpler to just create a new one.
char* rollback_filename = toku_construct_full_name(2, env->i->dir, toku_product_name_strings.rollback_cachefile);
@@ -935,9 +967,13 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
unused_flags &= ~DB_INIT_TXN & ~DB_INIT_LOG;
+ if(force_recovery == 6) {
+ flags |= DB_INIT_LOG | DB_INIT_TXN;
+ }
+
// do recovery only if there exists a log and recovery is requested
// otherwise, a log is created when the logger is opened later
- if (!newenv) {
+ if (!newenv && force_recovery == 0) {
if (flags & DB_INIT_LOG) {
// the log does exist
if (flags & DB_RECOVER) {
@@ -1006,7 +1042,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
assert (using_txns);
toku_logger_set_cachetable(env->i->logger, env->i->cachetable);
if (!toku_logger_rollback_is_open(env->i->logger)) {
- bool create_new_rollback_file = newenv | upgrade_in_progress;
+ bool create_new_rollback_file = newenv | upgrade_in_progress | (force_recovery == 6);
r = toku_logger_open_rollback(env->i->logger, env->i->cachetable, create_new_rollback_file);
if (r != 0) {
r = toku_ydb_do_error(env, r, "Cant open rollback\n");
@@ -1025,6 +1061,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
assert_zero(r);
r = toku_db_use_builtin_key_cmp(env->i->persistent_environment);
assert_zero(r);
+ writing_rollback++;
r = toku_db_open_iname(env->i->persistent_environment, txn, toku_product_name_strings.environmentdictionary, DB_CREATE, mode);
if (r != 0) {
r = toku_ydb_do_error(env, r, "Cant open persistent env\n");
@@ -1057,6 +1094,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
assert_zero(r);
}
capture_persistent_env_contents(env, txn);
+ writing_rollback--;
}
{
r = toku_db_create(&env->i->directory, env, 0);
@@ -1075,8 +1113,10 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
txn = NULL;
}
cp = toku_cachetable_get_checkpointer(env->i->cachetable);
- r = toku_checkpoint(cp, env->i->logger, NULL, NULL, NULL, NULL, STARTUP_CHECKPOINT);
- assert_zero(r);
+ if (!force_recovery) {
+ r = toku_checkpoint(cp, env->i->logger, NULL, NULL, NULL, NULL, STARTUP_CHECKPOINT);
+ }
+ writing_rollback--;
env_fs_poller(env); // get the file system state at startup
r = env_fs_init_minicron(env);
if (r != 0) {
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.cc b/storage/tokudb/PerconaFT/src/ydb_db.cc
index 6b4452325f4..5707415b72d 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_db.cc
@@ -324,6 +324,7 @@ toku_db_open(DB * db, DB_TXN * txn, const char *fname, const char *dbname, DBTYP
// DB_THREAD is implicitly supported and DB_BLACKHOLE is supported at the ft-layer
unused_flags &= ~DB_THREAD;
unused_flags &= ~DB_BLACKHOLE;
+ unused_flags &= ~DB_RDONLY;
// check for unknown or conflicting flags
if (unused_flags) return EINVAL; // unknown flags
@@ -405,7 +406,7 @@ int toku_db_lt_on_create_callback(toku::locktree *lt, void *extra) {
FT_HANDLE ft_handle = info->ft_handle;
FT_HANDLE cloned_ft_handle;
- r = toku_ft_handle_clone(&cloned_ft_handle, ft_handle, ttxn);
+ r = toku_ft_handle_clone(&cloned_ft_handle, ft_handle, ttxn, info->open_rw);
if (r == 0) {
assert(lt->get_userdata() == NULL);
lt->set_userdata(cloned_ft_handle);
@@ -466,6 +467,7 @@ int toku_db_open_iname(DB * db, DB_TXN * txn, const char *iname_in_env, uint32_t
flags&=~DB_READ_COMMITTED;
flags&=~DB_SERIALIZABLE;
flags&=~DB_IS_HOT_INDEX;
+ flags&=~DB_RDONLY;
// unknown or conflicting flags are bad
int unknown_flags = flags & ~DB_THREAD;
unknown_flags &= ~DB_BLACKHOLE;
@@ -480,11 +482,12 @@ int toku_db_open_iname(DB * db, DB_TXN * txn, const char *iname_in_env, uint32_t
db->i->open_flags = flags;
db->i->open_mode = mode;
+ bool open_rw = mode & (S_IWUSR | S_IWOTH | S_IWGRP);
FT_HANDLE ft_handle = db->i->ft_handle;
int r = toku_ft_handle_open(ft_handle, iname_in_env,
is_db_create, is_db_excl,
db->dbenv->i->cachetable,
- txn ? db_txn_struct_i(txn)->tokutxn : nullptr);
+ txn ? db_txn_struct_i(txn)->tokutxn : nullptr, open_rw);
if (r != 0) {
goto out;
}
@@ -506,6 +509,7 @@ int toku_db_open_iname(DB * db, DB_TXN * txn, const char *iname_in_env, uint32_t
struct lt_on_create_callback_extra on_create_extra = {
.txn = txn,
.ft_handle = db->i->ft_handle,
+ .open_rw = false
};
db->i->lt = db->dbenv->i->ltm.get_lt(db->i->dict_id,
toku_ft_get_comparator(db->i->ft_handle),
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.h b/storage/tokudb/PerconaFT/src/ydb_db.h
index ab8fcd2a401..c260e9d0fbe 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.h
+++ b/storage/tokudb/PerconaFT/src/ydb_db.h
@@ -67,6 +67,7 @@ void ydb_db_layer_get_status(YDB_DB_LAYER_STATUS statp);
struct lt_on_create_callback_extra {
DB_TXN *txn;
FT_HANDLE ft_handle;
+ bool open_rw;
};
int toku_db_lt_on_create_callback(toku::locktree *lt, void *extra);
void toku_db_lt_on_destroy_callback(toku::locktree *lt);
diff --git a/storage/tokudb/PerconaFT/tools/tokuftdump.cc b/storage/tokudb/PerconaFT/tools/tokuftdump.cc
index 2838ae5182e..44edb15162a 100644
--- a/storage/tokudb/PerconaFT/tools/tokuftdump.cc
+++ b/storage/tokudb/PerconaFT/tools/tokuftdump.cc
@@ -181,7 +181,7 @@ static void dump_header(FT ft) {
printf(" time_of_creation= %" PRIu64 " %s\n", ft->h->time_of_creation, timestr);
format_time(ft->h->time_of_last_modification, timestr);
printf(" time_of_last_modification=%" PRIu64 " %s\n", ft->h->time_of_last_modification, timestr);
- printf(" dirty=%d\n", ft->h->dirty);
+ printf(" dirty=%d\n", ft->h->dirty());
printf(" checkpoint_count=%" PRId64 "\n", ft->h->checkpoint_count);
printf(" checkpoint_lsn=%" PRId64 "\n", ft->h->checkpoint_lsn.lsn);
printf(" nodesize=%u\n", ft->h->nodesize);
diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc
index ff81fbfe4a7..39bc286a617 100644
--- a/storage/tokudb/ha_tokudb.cc
+++ b/storage/tokudb/ha_tokudb.cc
@@ -1333,7 +1333,7 @@ int ha_tokudb::open_main_dictionary(
NULL,
DB_BTREE,
open_flags,
- 0);
+ S_IWUSR);
if (error) {
goto exit;
}
@@ -1396,7 +1396,7 @@ int ha_tokudb::open_secondary_dictionary(
}
- error = (*ptr)->open(*ptr, txn, newname, NULL, DB_BTREE, open_flags, 0);
+ error = (*ptr)->open(*ptr, txn, newname, NULL, DB_BTREE, open_flags, S_IWUSR);
if (error) {
my_errno = error;
goto cleanup;
diff --git a/storage/tokudb/man/CMakeLists.txt b/storage/tokudb/man/CMakeLists.txt
new file mode 100644
index 00000000000..192d8117119
--- /dev/null
+++ b/storage/tokudb/man/CMakeLists.txt
@@ -0,0 +1,2 @@
+SET(MAN1_TOKUDB tokuftdump.1 tokuft_logprint.1)
+INSTALL(FILES ${MAN1_TOKUDB} DESTINATION ${INSTALL_MANDIR}/man1 COMPONENT tokudb-engine)
diff --git a/storage/tokudb/man/tokuft_logprint.1 b/storage/tokudb/man/tokuft_logprint.1
new file mode 100644
index 00000000000..d6f69e0aeeb
--- /dev/null
+++ b/storage/tokudb/man/tokuft_logprint.1
@@ -0,0 +1,16 @@
+'\" t
+.\"
+.TH "\FBTOKUFT_LOGPRINT\FR" "1" "29 March 2019" "MariaDB 10\&.2" "MariaDB Database System"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH NAME
+tokuft_logprint \- Dump the log from stdin to stdout
+.SH DESCRIPTION
+Use: Dump the log from stdin to stdout\. Use \fBtokuft_logprint \-\-help\fR for details on usage\.
+.PP
+For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
diff --git a/storage/tokudb/man/tokuftdump.1 b/storage/tokudb/man/tokuftdump.1
new file mode 100644
index 00000000000..79129a1a2e1
--- /dev/null
+++ b/storage/tokudb/man/tokuftdump.1
@@ -0,0 +1,237 @@
+'\" t
+.\"
+.TH "\FBTOKUFTDUMP\FR" "1" "3 April 2017" "MariaDB 10\&.2" "MariaDB Database System"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.\" tokuftdump
+.\" upgrading MySQL
+.SH "NAME"
+tokuftdump \- look into the fractal tree file
+.SH "SYNOPSIS"
+.HP \w'\fBtokuftdump\ [\fR\fB\fIoptions\fR\fR\fB]\fR\ 'u
+\fBtokuftdump [\fR\fB\fIoptions\fR\fR\fB]\fR
+.SH "DESCRIPTION"
+.PP
+\fBtokuftdump\fR
+Investigates and diagnoses the fractal tree\&.
+.PP
+\fBtokuftdump\fR
+supports the following options for processing option files\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: interactive option
+.\" interactive option: tokuftdump
+\fB\-\-interactive\fR
+.sp
+Interactive\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: support option
+.\" support option: tokuftdump
+\fB\-\-support \fI/path/to/fractal-tree/file\fR
+.sp
+An interactive way to see what messages and/or switch between FTs\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: json option
+.\" json option: tokuftdump
+\fB\-\-json \fI/path/to/fractal-tree/file [output_json_file]\fR
+.sp
+If the output json file is left empty, FT\&.json will be created automatically\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: nodata option
+.\" nodata option: tokuftdump
+\fB\-\-nodata\fR
+.sp
+Nodata\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: dumpdata option
+.\" dumpdata option: tokuftdump
+\fB\-\-dumpdata = \fR\fB\fI0|1\fR\fR
+.sp
+Dumpdata\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: header option
+.\" header option: tokuftdump
+\fB\-\-header\fR
+.sp
+Header\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: rootnode option
+.\" rootnode option: tokuftdump
+\fB\-\-rootnode\fR
+.sp
+Rootnode\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: node option
+.\" node option: tokuftdump
+\fB\-\-node \fIN\fR
+.sp
+Node\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: fragmentation option
+.\" fragmentation option: tokuftdump
+\fB\-\-fragmentation\fR
+.sp
+Fragmentation\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: garbage option
+.\" garbage option: tokuftdump
+\fB\-\-garbage\fR
+.sp
+Garbage\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: tsv option
+.\" tsv option: tokuftdump
+\fB\-\-tsv\fR
+.sp
+TSV\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: translation-table option
+.\" translation-table option: tokuftdump
+\fB\-\-translation\-table\fR
+.sp
+Translation table\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" tokuftdump: summary option
+.\" summary option: tokuftdump
+\fB\-\-summary\fR
+.sp
+Provide summary info\&.
+.RE
+.SH "COPYRIGHT"
+.br
+.PP
+Copyright 2016 MariaDB Foundation
+.PP
+This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
+.PP
+This documentation is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+.PP
+You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/.
+.sp
+.SH "SEE ALSO"
+For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
+.SH AUTHOR
+MariaDB Foundation (http://www.mariadb.org/).
diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt b/storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt
index b351df53683..127c28fabfd 100644
--- a/storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt
+++ b/storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt
@@ -1,5 +1 @@
--log-warnings=0 --slave-transaction-retries=0
-
-
-
-
diff --git a/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
index ad920deeda4..17229fa5956 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
@@ -1533,11 +1533,8 @@ select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
1.01500000 * 1.01500000 * 0.99500000)
0.81298807395367312459230693948000000000
create table t1 as select 5.05 / 0.014;
-Warnings:
-Note 1265 Data truncated for column '5.05 / 0.014' at row 1
show warnings;
Level Code Message
-Note 1265 Data truncated for column '5.05 / 0.014' at row 1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -1652,8 +1649,6 @@ my_col
0.12345678912345678912345678912345678912
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
-Warnings:
-Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
my_col decimal(65,4) YES NULL
diff --git a/storage/tokudb/mysql-test/tokudb/r/type_ranges.result b/storage/tokudb/mysql-test/tokudb/r/type_ranges.result
index 1c9cd769a14..0b1054263ac 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_ranges.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_ranges.result
@@ -92,8 +92,6 @@ DROP INDEX test ON t1;
insert into t1 values (10, 1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,NULL,2,2,'two','two,one');
insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303101010','','','','3',3,3);
-Warnings:
-Warning 1265 Data truncated for column 'string' at row 1
insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1);
Warnings:
Warning 1264 Out of range value for column 'utiny' at row 1
@@ -131,7 +129,7 @@ select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,ut
auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col
10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1
11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2
-12 0.33333333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
+12 0.3333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
13 -1 -1 -1 -1 -1 -1 -1.0 -1.0000 0 00000 0 0 0 0 1997-08-07 08:07:06 1997-04-03 09:08:07 -1 -1 -1 -1
14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 0 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295
15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295
@@ -183,7 +181,7 @@ Warning 1265 Data truncated for column 'new_field' at row 7
select * from t2;
auto string mediumblob_col new_field
1 2 2 ne
-2 0.33333333 ne
+2 0.3333 ne
3 -1 -1 ne
4 -429496729 -4294967295 ne
5 4294967295 4294967295 ne
diff --git a/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result
index b18f970d2ce..14b6052a7d3 100644
--- a/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result
@@ -1115,5 +1115,13 @@ SELECT * FROM t1;
a
0
DROP TABLE t1;
+#
+# MDEV-19622 Assertion failures in
+# ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table
+#
+CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a);
+INSERT INTO t1 VALUES (1,1),(2,2);
+UPDATE t1 SET pk = 0;
+DROP TABLE t1;
##############################################################################
SET GLOBAL tokudb_prelock_empty = @tokudb_prelock_empty_saved;
diff --git a/storage/tokudb/mysql-test/tokudb_parts/r/partition_syntax_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_syntax_tokudb.result
index c84b4601332..e7bb6c7d70f 100644
--- a/storage/tokudb/mysql-test/tokudb_parts/r/partition_syntax_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb_parts/r/partition_syntax_tokudb.result
@@ -770,7 +770,7 @@ f_char2 CHAR(20),
f_charbig VARCHAR(1000) )
PARTITION BY RANGE(f_int1) SUBPARTITION BY HASH(f_int1) (PARTITION part1 VALUES LESS THAN (10), PARTITION part2 VALUES LESS THAN (20)
(SUBPARTITION subpart21 , SUBPARTITION subpart22 ), PARTITION part3 VALUES LESS THAN (2147483646)) ;
-ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near 'SUBPARTITION subpart21 , SUBPARTITION subpart22 ), PARTITION part3 VALUES LESS T' at line 7
+ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near 'SUBPARTITION subpart21 , SUBPARTITION subpart22 ), PARTITION part3 VALUES LES...' at line 7
CREATE TABLE t1 ( f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
f_char1 CHAR(20),
@@ -779,7 +779,7 @@ f_charbig VARCHAR(1000) )
PARTITION BY RANGE(f_int1) SUBPARTITION BY HASH(f_int1) (PARTITION part1 VALUES LESS THAN (10), PARTITION part2 VALUES LESS THAN (20)
(SUBPARTITION subpart21 , SUBPARTITION subpart22 ), PARTITION part3 VALUES LESS THAN (2147483646)
(SUBPARTITION subpart31 , SUBPARTITION subpart32 )) ;
-ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near 'SUBPARTITION subpart21 , SUBPARTITION subpart22 ), PARTITION part3 VALUES LESS T' at line 7
+ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near 'SUBPARTITION subpart21 , SUBPARTITION subpart22 ), PARTITION part3 VALUES LES...' at line 7
CREATE TABLE t1 ( f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
f_char1 CHAR(20),
@@ -797,7 +797,7 @@ PARTITION BY RANGE(f_int1) SUBPARTITION BY HASH(f_int1) (PARTITION part1 VALUES
(SUBPARTITION subpart11 , SUBPARTITION subpart12 ), PARTITION part2 VALUES LESS THAN (20), PARTITION part3 VALUES LESS THAN (2147483646)
(SUBPARTITION subpart31 , SUBPARTITION subpart32 )) ;
ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near ' PARTITION part3 VALUES LESS THAN (2147483646)
-(SUBPARTITION subpart31 , SUBPART' at line 7
+(SUBPARTITION subpart31 , SUBP...' at line 7
CREATE TABLE t1 ( f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
f_char1 CHAR(20),
@@ -987,7 +987,7 @@ SUBPARTITIONS -1
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-1
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (214' at line 9
+PARTITION part2 VALUES LESS THAN (...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1032,7 +1032,7 @@ SUBPARTITIONS 2.0
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '2.0
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (21' at line 9
+PARTITION part2 VALUES LESS THAN ...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1055,7 +1055,7 @@ SUBPARTITIONS -2.0
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-2.0
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (2' at line 9
+PARTITION part2 VALUES LESS THAN...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1078,7 +1078,7 @@ SUBPARTITIONS 0.0
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '0.0
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (21' at line 9
+PARTITION part2 VALUES LESS THAN ...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1101,7 +1101,7 @@ SUBPARTITIONS 1.6
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '1.6
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (21' at line 9
+PARTITION part2 VALUES LESS THAN ...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1123,7 +1123,7 @@ SUBPARTITIONS 999999999999999999999999999999.999999999999999999999999999999
(PARTITION part1 VALUES LESS THAN (10),
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '999999999999999999999999999999.999999999999999999999999999999
-(PARTITION part1 V' at line 9
+(PARTITION part...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1146,7 +1146,7 @@ SUBPARTITIONS 0.000000000000000000000000000001
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '0.000000000000000000000000000001
(PARTITION part1 VALUES LESS THAN (10),
-PARTITI' at line 9
+PART...' at line 9
# 4.2.3 partition/subpartition numbers FLOAT notation
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
@@ -1170,7 +1170,7 @@ SUBPARTITIONS 2.0E+0
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '2.0E+0
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN ' at line 9
+PARTITION part2 VALUES LESS TH...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1193,7 +1193,7 @@ SUBPARTITIONS 0.2E+1
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '0.2E+1
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN ' at line 9
+PARTITION part2 VALUES LESS TH...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1216,7 +1216,7 @@ SUBPARTITIONS -2.0E+0
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-2.0E+0
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN' at line 9
+PARTITION part2 VALUES LESS T...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1239,7 +1239,7 @@ SUBPARTITIONS 0.16E+1
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '0.16E+1
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN' at line 9
+PARTITION part2 VALUES LESS T...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1262,7 +1262,7 @@ SUBPARTITIONS 0.0E+300
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '0.0E+300
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THA' at line 9
+PARTITION part2 VALUES LESS ...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1285,7 +1285,7 @@ SUBPARTITIONS 1E+300
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '1E+300
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN ' at line 9
+PARTITION part2 VALUES LESS TH...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1308,7 +1308,7 @@ SUBPARTITIONS 1E-300
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: Only integers allowed as number here near '1E-300
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN ' at line 9
+PARTITION part2 VALUES LESS TH...' at line 9
# 4.2.4 partition/subpartition numbers STRING notation
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
@@ -1332,7 +1332,7 @@ SUBPARTITIONS '2'
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''2'
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (21' at line 9
+PARTITION part2 VALUES LESS THAN ...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1355,7 +1355,7 @@ SUBPARTITIONS '2.0'
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''2.0'
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (' at line 9
+PARTITION part2 VALUES LESS THA...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1378,7 +1378,7 @@ SUBPARTITIONS '0.2E+1'
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''0.2E+1'
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THA' at line 9
+PARTITION part2 VALUES LESS ...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1401,7 +1401,7 @@ SUBPARTITIONS '2A'
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''2A'
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (2' at line 9
+PARTITION part2 VALUES LESS THAN...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1424,7 +1424,7 @@ SUBPARTITIONS 'A2'
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''A2'
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (2' at line 9
+PARTITION part2 VALUES LESS THAN...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1447,7 +1447,7 @@ SUBPARTITIONS ''
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '''
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (214' at line 9
+PARTITION part2 VALUES LESS THAN (...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1470,7 +1470,7 @@ SUBPARTITIONS 'GARBAGE'
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''GARBAGE'
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS TH' at line 9
+PARTITION part2 VALUES LESS...' at line 9
# 4.2.5 partition/subpartition numbers other notations
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
@@ -1494,7 +1494,7 @@ SUBPARTITIONS 2A
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '2A
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (214' at line 9
+PARTITION part2 VALUES LESS THAN (...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1517,7 +1517,7 @@ SUBPARTITIONS A2
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'A2
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (214' at line 9
+PARTITION part2 VALUES LESS THAN (...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1540,7 +1540,7 @@ SUBPARTITIONS GARBAGE
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GARBAGE
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN' at line 9
+PARTITION part2 VALUES LESS T...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1563,7 +1563,7 @@ SUBPARTITIONS "2"
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"2"
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (21' at line 9
+PARTITION part2 VALUES LESS THAN ...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1586,7 +1586,7 @@ SUBPARTITIONS "2A"
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"2A"
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (2' at line 9
+PARTITION part2 VALUES LESS THAN...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1609,7 +1609,7 @@ SUBPARTITIONS "A2"
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"A2"
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THAN (2' at line 9
+PARTITION part2 VALUES LESS THAN...' at line 9
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1632,7 +1632,7 @@ SUBPARTITIONS "GARBAGE"
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"GARBAGE"
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS TH' at line 9
+PARTITION part2 VALUES LESS...' at line 9
# 4.2.6 (negative) partition/subpartition numbers per @variables
SET @aux = 5;
CREATE TABLE t1 (
@@ -1657,7 +1657,7 @@ SUBPARTITIONS @aux = 5
PARTITION part2 VALUES LESS THAN (2147483646));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '@aux = 5
(PARTITION part1 VALUES LESS THAN (10),
-PARTITION part2 VALUES LESS THA' at line 9
+PARTITION part2 VALUES LESS ...' at line 9
#------------------------------------------------------------------------
# 4.3 Mixups of assigned partition/subpartition numbers and names
#------------------------------------------------------------------------
@@ -1750,7 +1750,7 @@ PARTITION part2 VALUES LESS THAN (2147483646)
);
ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near '),
PARTITION part2 VALUES LESS THAN (2147483646)
-(SUBPARTITION subpart21, SUBPAR' at line 11
+(SUBPARTITION subpart21, SUB...' at line 11
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1769,7 +1769,7 @@ PARTITION part3 VALUES LESS THAN (2147483646)
);
ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near '),
PARTITION part3 VALUES LESS THAN (2147483646)
-(SUBPARTITION subpart31, SUBPAR' at line 13
+(SUBPARTITION subpart31, SUB...' at line 13
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1812,7 +1812,7 @@ PARTITION part2 VALUES LESS THAN (2147483646)
);
ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near '),
PARTITION part2 VALUES LESS THAN (2147483646)
-(SUBPARTITION subpart21, SUBPAR' at line 11
+(SUBPARTITION subpart21, SUB...' at line 11
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1831,7 +1831,7 @@ PARTITION part3 VALUES LESS THAN (2147483646)
);
ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near '),
PARTITION part2 VALUES LESS THAN (2000)
-(SUBPARTITION subpart21 ' at line 11
+(SUBPARTITION subpart21 ...' at line 11
CREATE TABLE t1 (
f_int1 INTEGER DEFAULT 0,
f_int2 INTEGER DEFAULT 0,
@@ -1848,7 +1848,7 @@ PARTITION part2 VALUES LESS THAN (2147483646)
);
ERROR 42000: Wrong number of subpartitions defined, mismatch with previous setting near '),
PARTITION part2 VALUES LESS THAN (2147483646)
-(SUBPARTITION subpart21, SUBPAR' at line 11
+(SUBPARTITION subpart21, SUB...' at line 11
#========================================================================
# 5. Checks of logical partition/subpartition name
diff --git a/storage/tokudb/tokudb_status.h b/storage/tokudb/tokudb_status.h
index 5cca54e52c9..07772bdc92a 100644
--- a/storage/tokudb/tokudb_status.h
+++ b/storage/tokudb/tokudb_status.h
@@ -201,7 +201,7 @@ int create(
name,
NULL,
DB_BTREE, DB_CREATE | DB_EXCL,
- 0);
+ S_IWUSR);
}
if (error == 0) {
*status_db_ptr = status_db;
@@ -230,7 +230,7 @@ int open(
NULL,
DB_BTREE,
DB_THREAD,
- 0);
+ S_IWUSR);
}
if (error == 0) {
uint32_t pagesize = 0;
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index 07ee23fae5c..bed5946541c 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -99,11 +99,6 @@ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-class-memaccess")
IF(NOT MSVC)
- CHECK_FUNCTION_EXISTS(posix_memalign HAVE_POSIX_MEMALIGN)
- IF(HAVE_POSIX_MEMALIGN)
- ADD_DEFINITIONS(-DHAVE_POSIX_MEMALIGN)
- ENDIF()
-
# either define HAVE_IB_GCC_ATOMIC_BUILTINS or not
# workaround for old gcc on x86, gcc atomic ops only work under -march=i686
IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" AND CMAKE_COMPILER_IS_GNUCC AND
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index 5235fe434a9..7d97881f552 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -3,7 +3,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1542,17 +1542,23 @@ fail_err:
}
ulint max_size = page_get_max_insert_size_after_reorganize(page, 1);
+ if (max_size < rec_size) {
+ goto fail;
+ }
+
+ const ulint n_recs = page_get_n_recs(page);
+ if (UNIV_UNLIKELY(n_recs >= 8189)) {
+ ut_ad(srv_page_size == 65536);
+ goto fail;
+ }
if (page_has_garbage(page)) {
- if ((max_size < rec_size
- || max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT)
- && page_get_n_recs(page) > 1
+ if (max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT
+ && n_recs > 1
&& page_get_max_insert_size(page, 1) < rec_size) {
goto fail;
}
- } else if (max_size < rec_size) {
- goto fail;
}
/* If there have been many consecutive inserts to the
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index 93ad1b12b00..1a4c7e802c4 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -92,17 +92,14 @@ buf_mark_space_corrupt(
/* prototypes for new functions added to ha_innodb.cc */
trx_t* innobase_get_trx();
-inline void* aligned_malloc(size_t size, size_t align) {
+static void* aligned_malloc(size_t size, size_t align) {
void *result;
#ifdef _MSC_VER
result = _aligned_malloc(size, align);
-#elif defined (HAVE_POSIX_MEMALIGN)
+#else
if(posix_memalign(&result, align, size)) {
- result = 0;
+ result = NULL;
}
-#else
- /* Use unaligned malloc as fallback */
- result = malloc(size);
#endif
return result;
}
@@ -4942,9 +4939,8 @@ buf_page_io_complete(buf_page_t* bpage)
err = buf_page_check_corrupt(bpage, space);
}
-database_corrupted:
-
if (err != DB_SUCCESS) {
+database_corrupted:
/* Not a real corruption if it was triggered by
error injection */
DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
@@ -4959,6 +4955,11 @@ database_corrupted:
goto page_not_corrupt;
);
+ if (uncompressed && bpage->zip.data) {
+ memset(reinterpret_cast<buf_block_t*>(bpage)
+ ->frame, 0, srv_page_size);
+ }
+
if (err == DB_PAGE_CORRUPTED) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Database page corruption on disk"
diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc
index 8851dd292da..a405c3edf5e 100644
--- a/storage/xtradb/buf/buf0dblwr.cc
+++ b/storage/xtradb/buf/buf0dblwr.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -554,12 +554,18 @@ buf_dblwr_process()
continue;
}
- if (!fil_check_adress_in_tablespace(space_id, page_no)) {
+ if (!space()->size) {
+ fil_space_get_size(space_id);
+ }
+
+ if (UNIV_UNLIKELY(space()->size <= page_no)) {
ib_logf(IB_LOG_LEVEL_WARN,
- "A copy of page " ULINTPF ":" ULINTPF
+ "A copy of page " ULINTPF
" in the doublewrite buffer slot " ULINTPF
- " is not within space bounds",
- space_id, page_no, page_no_dblwr);
+ " is beyond the end of the tablespace "
+ " %s (" ULINTPF " pages)",
+ page_no, page_no_dblwr,
+ space()->name, space()->size);
continue;
}
@@ -963,6 +969,7 @@ try_again:
ib_int64_t sig_count = os_event_reset(buf_dblwr->b_event);
mutex_exit(&buf_dblwr->mutex);
+ os_aio_simulated_wake_handler_threads();
os_event_wait_low(buf_dblwr->b_event, sig_count);
goto try_again;
}
@@ -1112,6 +1119,7 @@ try_again:
checkpoint. */
ib_int64_t sig_count = os_event_reset(buf_dblwr->b_event);
mutex_exit(&buf_dblwr->mutex);
+ os_aio_simulated_wake_handler_threads();
os_event_wait_low(buf_dblwr->b_event, sig_count);
goto try_again;
diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc
index 349e7d45ab8..20dec30d106 100644
--- a/storage/xtradb/buf/buf0dump.cc
+++ b/storage/xtradb/buf/buf0dump.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -176,7 +176,7 @@ get_buf_dump_dir()
/* The dump file should be created in the default data directory if
innodb_data_home_dir is set as an empty string. */
- if (strcmp(srv_data_home, "") == 0) {
+ if (!*srv_data_home) {
dump_dir = fil_path_to_mysql_datadir;
} else {
dump_dir = srv_data_home;
@@ -208,9 +208,11 @@ buf_dump(
ulint i;
int ret;
+ mysql_mutex_lock(&LOCK_global_system_variables);
ut_snprintf(full_filename, sizeof(full_filename),
"%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR,
srv_buf_dump_filename);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
ut_snprintf(tmp_filename, sizeof(tmp_filename),
format_name, full_filename);
@@ -514,9 +516,11 @@ buf_load()
/* Ignore any leftovers from before */
buf_load_abort_flag = FALSE;
+ mysql_mutex_lock(&LOCK_global_system_variables);
ut_snprintf(full_filename, sizeof(full_filename),
"%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR,
srv_buf_dump_filename);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
buf_load_status(STATUS_NOTICE,
"Loading buffer pool(s) from %s", full_filename);
diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc
index 9c427395231..2a656d748b1 100644
--- a/storage/xtradb/buf/buf0flu.cc
+++ b/storage/xtradb/buf/buf0flu.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Copyright (c) 2013, 2014, Fusion-io
This program is free software; you can redistribute it and/or modify it under
@@ -1297,8 +1297,11 @@ buf_flush_try_neighbors(
/* fprintf(stderr, "Flush area: low %lu high %lu\n", low, high); */
- if (high > fil_space_get_size(space)) {
- high = fil_space_get_size(space);
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ high = s->max_page_number_for_io(high);
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
}
ulint count = 0;
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index 13bf5e79f2d..9a577bc3010 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1049,7 +1049,7 @@ buf_LRU_check_size_of_non_data_objects(
+ UT_LIST_GET_LEN(buf_pool->LRU))
< buf_pool->curr_size / 3) {
- if (!buf_lru_switched_on_innodb_mon) {
+ if (!buf_lru_switched_on_innodb_mon && srv_monitor_event) {
/* Over 67 % of the buffer pool is occupied by lock
heaps or the adaptive hash index. This may be a memory
diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc
index 1ef9162cab9..a962b94c0c2 100644
--- a/storage/xtradb/buf/buf0rea.cc
+++ b/storage/xtradb/buf/buf0rea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -344,19 +344,22 @@ buf_read_ahead_random(
return(0);
}
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ /* Remember the tablespace version along with the
+ tablespace size: if DISCARD + IMPORT changes the
+ actual .ibd file meanwhile, we do not try to read
+ outside the bounds of the tablespace! */
+ tablespace_version = s->tablespace_version;
- tablespace_version = fil_space_get_version(space);
-
- low = (offset / buf_read_ahead_random_area)
- * buf_read_ahead_random_area;
- high = (offset / buf_read_ahead_random_area + 1)
- * buf_read_ahead_random_area;
- if (high > fil_space_get_size(space)) {
+ low = (offset / buf_read_ahead_random_area)
+ * buf_read_ahead_random_area;
+ high = (offset / buf_read_ahead_random_area + 1)
+ * buf_read_ahead_random_area;
+ high = s->max_page_number_for_io(high);
- high = fil_space_get_size(space);
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
}
if (buf_pool->n_pend_reads
@@ -495,22 +498,16 @@ buf_read_page(
ulint offset,
trx_t* trx)
{
- ib_int64_t tablespace_version;
- ulint count;
dberr_t err = DB_SUCCESS;
- tablespace_version = fil_space_get_version(space_id);
-
FilSpace space(space_id, true);
if (space()) {
-
- /* We do the i/o in the synchronous aio mode to save thread
- switches: hence TRUE */
- count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space_id,
- zip_size, FALSE,
- tablespace_version, offset, trx);
-
+ ulint count = buf_read_page_low(&err, /*sync=*/true,
+ BUF_READ_ANY_PAGE,
+ space_id, zip_size, FALSE,
+ space()->tablespace_version,
+ offset, trx);
srv_stats.buf_pool_reads.add(count);
}
@@ -683,13 +680,23 @@ buf_read_ahead_linear(
return(0);
}
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
+ uint32_t space_high_limit = 0;
- tablespace_version = fil_space_get_version(space);
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ /* Remember the tablespace version along with the
+ tablespace size: if DISCARD + IMPORT changes the
+ actual .ibd file meanwhile, we do not try to read
+ outside the bounds of the tablespace! */
+ tablespace_version = s->tablespace_version;
+
+ space_high_limit = s->max_page_number_for_io(ULINT_UNDEFINED);
+
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
+ }
- if (high > fil_space_get_size(space)) {
+ if (high > space_high_limit) {
/* The area is not whole, return */
return(0);
@@ -825,7 +832,7 @@ buf_read_ahead_linear(
return(0);
}
- if (high > fil_space_get_size(space)) {
+ if (high > space_high_limit) {
/* The area is not whole, return */
return(0);
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index 2bea154749f..6d0500589b1 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -604,7 +604,10 @@ dict_table_close(
mutex_exit(&dict_sys->mutex);
- if (drop_aborted) {
+ /* dict_table_try_drop_aborted() can generate undo logs.
+ So it should be avoided after shutdown of background
+ threads */
+ if (drop_aborted && srv_undo_sources) {
dict_table_try_drop_aborted(NULL, table_id, 0);
}
}
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index f4bbc5c8f06..82480b13827 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/dict/dict0mem.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -416,15 +416,14 @@ dict_mem_table_col_rename_low(
}
}
- dict_index_t* new_index = dict_foreign_find_index(
+ /* New index can be null if XtraDB already dropped
+ the foreign index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->foreign_index = dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL);
- /* There must be an equivalent index in this case. */
- ut_ad(new_index != NULL);
-
- foreign->foreign_index = new_index;
} else {
@@ -447,7 +446,41 @@ dict_mem_table_col_rename_low(
foreign = *it;
- ut_ad(foreign->referenced_index != NULL);
+ if (!foreign->referenced_index) {
+ /* Referenced index could have been dropped
+ when foreign_key_checks is disabled. In that case,
+ rename the corresponding referenced_col_names and
+ find the equivalent referenced index also */
+ for (unsigned f = 0; f < foreign->n_fields; f++) {
+
+ const char*& rc =
+ foreign->referenced_col_names[f];
+
+ if (strcmp(rc, from)) {
+ continue;
+ }
+
+ if (to_len <= strlen(rc)) {
+ memcpy(const_cast<char*>(rc), to,
+ to_len + 1);
+ } else {
+ rc = static_cast<char*>(
+ mem_heap_dup(
+ foreign->heap,
+ to, to_len + 1));
+ }
+ }
+
+ /* New index can be null if InnoDB already dropped
+ the referenced index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->referenced_index = dict_foreign_find_index(
+ foreign->referenced_table, NULL,
+ foreign->referenced_col_names,
+ foreign->n_fields, NULL, true, false,
+ NULL, NULL, NULL);
+ return;
+ }
for (unsigned f = 0; f < foreign->n_fields; f++) {
/* foreign->referenced_col_names[] need to be
@@ -820,3 +853,22 @@ operator<< (std::ostream& out, const dict_foreign_set& fk_set)
return(out);
}
+/** Check whether fulltext index gets affected by foreign
+key constraint. */
+bool dict_foreign_t::affects_fulltext() const
+{
+ if (foreign_table == referenced_table || !foreign_table->fts)
+ return false;
+
+ for (ulint i = 0; i < n_fields; i++)
+ {
+ if (dict_table_is_fts_column(
+ foreign_table->fts->indexes,
+ dict_index_get_nth_col_no(foreign_index, i))
+ != ULINT_UNDEFINED)
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index 874c6b4dd2e..b38b8778f5b 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -44,15 +44,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
#include "ha_prototypes.h" // IB_LOG_
#include <my_crypt.h>
-/** Mutex for keys */
-static ib_mutex_t fil_crypt_key_mutex;
-
static bool fil_crypt_threads_inited = false;
-#ifdef UNIV_PFS_MUTEX
-static mysql_pfs_key_t fil_crypt_key_mutex_key;
-#endif
-
/** Is encryption enabled/disabled */
UNIV_INTERN ulong srv_encrypt_tables = 0;
@@ -133,9 +126,6 @@ UNIV_INTERN
void
fil_space_crypt_init()
{
- mutex_create(fil_crypt_key_mutex_key,
- &fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK);
-
fil_crypt_throttle_sleep_event = os_event_create();
mutex_create(fil_crypt_stat_mutex_key,
@@ -152,7 +142,6 @@ fil_space_crypt_cleanup()
{
os_event_free(fil_crypt_throttle_sleep_event);
fil_crypt_throttle_sleep_event = NULL;
- mutex_free(&fil_crypt_key_mutex);
mutex_free(&crypt_stat_mutex);
}
@@ -706,47 +695,8 @@ fil_space_encrypt(
fil_space_crypt_t* crypt_data = space->crypt_data;
ut_ad(space->n_pending_ios > 0);
ulint zip_size = fsp_flags_get_zip_size(space->flags);
- byte* tmp = fil_encrypt_buf(crypt_data, space->id, offset, lsn, src_frame, zip_size, dst_frame);
-
-#ifdef UNIV_DEBUG
- if (tmp) {
- /* Verify that encrypted buffer is not corrupted */
- dberr_t err = DB_SUCCESS;
- byte* src = src_frame;
- bool page_compressed_encrypted = (mach_read_from_2(tmp+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
- byte uncomp_mem[UNIV_PAGE_SIZE_MAX];
- byte tmp_mem[UNIV_PAGE_SIZE_MAX];
- ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
-
- if (page_compressed_encrypted) {
- memcpy(uncomp_mem, src, srv_page_size);
- ulint unzipped1 = fil_page_decompress(
- tmp_mem, uncomp_mem);
- ut_ad(unzipped1);
- if (unzipped1 != srv_page_size) {
- src = uncomp_mem;
- }
- }
-
- ut_ad(!buf_page_is_corrupted(true, src, zip_size, space));
- ut_ad(fil_space_decrypt(crypt_data, tmp_mem, size, tmp, &err));
- ut_ad(err == DB_SUCCESS);
-
- /* Need to decompress the page if it was also compressed */
- if (page_compressed_encrypted) {
- byte buf[UNIV_PAGE_SIZE_MAX];
- memcpy(buf, tmp_mem, srv_page_size);
- ulint unzipped2 = fil_page_decompress(tmp_mem, buf);
- ut_ad(unzipped2);
- }
-
- memcpy(tmp_mem + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
- src + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 8);
- ut_ad(!memcmp(src, tmp_mem, size));
- }
-#endif /* UNIV_DEBUG */
-
- return tmp;
+ return fil_encrypt_buf(crypt_data, space->id, offset, lsn,
+ src_frame, zip_size, dst_frame);
}
/******************************************************************
@@ -1490,6 +1440,109 @@ fil_crypt_return_iops(
fil_crypt_update_total_stat(state);
}
+/** Remove space from key rotation list if there are no pending operations. */
+static void fil_space_remove_from_keyrotation(fil_space_t *space)
+{
+ ut_ad(mutex_own(&fil_system->mutex));
+
+ if (space->n_pending_ops == 0 && space->is_in_rotation_list)
+ {
+ space->is_in_rotation_list= false;
+ ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
+ UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
+ }
+}
+
+/** Return the next tablespace from key rotation list.
+@param space previous tablespace (NULL to start from the beginning)
+@return pointer to the next tablespace (with n_pending_ops incremented)
+@retval NULL if this was the last */
+static fil_space_t *fil_space_keyrotate_next(fil_space_t *space)
+{
+ ut_ad(mutex_own(&fil_system->mutex));
+
+ if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0)
+ {
+ if (space)
+ {
+ space->n_pending_ops--;
+ fil_space_remove_from_keyrotation(space);
+ }
+
+ return NULL;
+ }
+
+ if (!space)
+ {
+ space= UT_LIST_GET_FIRST(fil_system->rotation_list);
+ /* We can trust that space is not NULL because we
+ checked list length above */
+ }
+ else
+ {
+ space->n_pending_ops--;
+ fil_space_t *old = space;
+ space= UT_LIST_GET_NEXT(rotation_list, space);
+ fil_space_remove_from_keyrotation(old);
+ }
+
+ /* Skip spaces that are being created by fil_ibd_create(),
+ or dropped. Note that rotation_list contains only
+ space->purpose == FIL_TABLESPACE. */
+ while (space && (!UT_LIST_GET_LEN(space->chain) || space->is_stopping()))
+ {
+ fil_space_t *old = space;
+ space= UT_LIST_GET_NEXT(rotation_list, space);
+ fil_space_remove_from_keyrotation(old);
+ }
+
+ if (space)
+ space->n_pending_ops++;
+
+ return space;
+}
+
+/** Return the next tablespace.
+@param space previous tablespace (NULL to start from the beginning)
+@return pointer to the next tablespace (with n_pending_ops incremented)
+@retval NULL if this was the last */
+static fil_space_t *fil_space_next(fil_space_t *space)
+{
+ mutex_enter(&fil_system->mutex);
+ ut_ad(!space || space->n_pending_ops);
+
+ if (!srv_fil_crypt_rotate_key_age)
+ space= fil_space_keyrotate_next(space);
+ else if (!space)
+ {
+ space= UT_LIST_GET_FIRST(fil_system->space_list);
+ /* We can trust that space is not NULL because at least the
+ system tablespace is always present and loaded first. */
+ space->n_pending_ops++;
+ }
+ else
+ {
+ ut_ad(space->n_pending_ops > 0);
+ /* Move on to the next fil_space_t */
+ space->n_pending_ops--;
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ /* Skip abnormal tablespaces or those that are being created by
+ fil_ibd_create(), or being dropped. */
+ while (space &&
+ (UT_LIST_GET_LEN(space->chain) == 0 ||
+ space->is_stopping() || space->purpose != FIL_TABLESPACE))
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ if (space)
+ space->n_pending_ops++;
+ }
+
+ mutex_exit(&fil_system->mutex);
+
+ return space;
+}
+
/***********************************************************************
Search for a space needing rotation
@param[in,out] key_state Key state
@@ -1524,14 +1577,7 @@ fil_crypt_find_space_to_rotate(
state->space = NULL;
}
- /* If key rotation is enabled (default) we iterate all tablespaces.
- If key rotation is not enabled we iterate only the tablespaces
- added to keyrotation list. */
- if (srv_fil_crypt_rotate_key_age) {
- state->space = fil_space_next(state->space);
- } else {
- state->space = fil_space_keyrotate_next(state->space);
- }
+ state->space = fil_space_next(state->space);
while (!state->should_shutdown() && state->space) {
fil_crypt_read_crypt_data(state->space);
@@ -1544,14 +1590,15 @@ fil_crypt_find_space_to_rotate(
return true;
}
- if (srv_fil_crypt_rotate_key_age) {
- state->space = fil_space_next(state->space);
- } else {
- state->space = fil_space_keyrotate_next(state->space);
- }
+ state->space = fil_space_next(state->space);
+ }
+
+ if (state->space) {
+ fil_space_release(state->space);
+ state->space = NULL;
}
- /* if we didn't find any space return iops */
+ /* no work to do; release our allocation of I/O capacity */
fil_crypt_return_iops(state);
return false;
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 4a982df3fda..be11b1089a9 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -684,7 +684,7 @@ fil_node_open_file(
#ifdef UNIV_HOTBACKUP
add_size:
#endif /* UNIV_HOTBACKUP */
- space->size += node->size;
+ space->committed_size = space->size += node->size;
}
ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(space->flags);
@@ -1158,6 +1158,9 @@ retry:
ut_a(success);
/* InnoDB data files cannot shrink. */
ut_a(space->size >= size);
+ if (size > space->committed_size) {
+ space->committed_size = size;
+ }
/* There could be multiple concurrent I/O requests for
this tablespace (multiple threads trying to extend
@@ -1815,25 +1818,6 @@ fil_space_get_zip_size(
return(flags);
}
-/*******************************************************************//**
-Checks if the pair space, page_no refers to an existing page in a tablespace
-file space. The tablespace must be cached in the memory cache.
-@return TRUE if the address is meaningful */
-UNIV_INTERN
-ibool
-fil_check_adress_in_tablespace(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint page_no)/*!< in: page number */
-{
- if (fil_space_get_size(id) > page_no) {
-
- return(TRUE);
- }
-
- return(FALSE);
-}
-
/****************************************************************//**
Initializes the tablespace memory cache. */
UNIV_INTERN
@@ -6879,137 +6863,3 @@ fil_space_release(fil_space_t* space)
space->n_pending_ops--;
mutex_exit(&fil_system->mutex);
}
-
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_next(fil_space_t* prev_space)
-{
- fil_space_t* space=prev_space;
-
- mutex_enter(&fil_system->mutex);
-
- if (prev_space == NULL) {
- space = UT_LIST_GET_FIRST(fil_system->space_list);
-
- /* We can trust that space is not NULL because at least the
- system tablespace is always present and loaded first. */
- space->n_pending_ops++;
- } else {
- ut_ad(space->n_pending_ops > 0);
-
- /* Move on to the next fil_space_t */
- space->n_pending_ops--;
- space = UT_LIST_GET_NEXT(space_list, space);
-
- /* Skip spaces that are being created by
- fil_ibd_create(), or dropped, or !tablespace. */
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping()
- || space->purpose != FIL_TABLESPACE)) {
- space = UT_LIST_GET_NEXT(space_list, space);
- }
-
- if (space != NULL) {
- space->n_pending_ops++;
- }
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(space);
-}
-
-/**
-Remove space from key rotation list if there are no more
-pending operations.
-@param[in] space Tablespace */
-static
-void
-fil_space_remove_from_keyrotation(
- fil_space_t* space)
-{
- ut_ad(mutex_own(&fil_system->mutex));
- ut_ad(space);
-
- if (space->n_pending_ops == 0 && space->is_in_rotation_list) {
- space->is_in_rotation_list = false;
- ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
- UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
- }
-}
-
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_keyrotate_next(
- fil_space_t* prev_space)
-{
- fil_space_t* space = prev_space;
- fil_space_t* old = NULL;
-
- mutex_enter(&fil_system->mutex);
-
- if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) {
- if (space) {
- ut_ad(space->n_pending_ops > 0);
- space->n_pending_ops--;
- fil_space_remove_from_keyrotation(space);
- }
- mutex_exit(&fil_system->mutex);
- return(NULL);
- }
-
- if (prev_space == NULL) {
- space = UT_LIST_GET_FIRST(fil_system->rotation_list);
-
- /* We can trust that space is not NULL because we
- checked list length above */
- } else {
- ut_ad(space->n_pending_ops > 0);
-
- /* Move on to the next fil_space_t */
- space->n_pending_ops--;
-
- old = space;
- space = UT_LIST_GET_NEXT(rotation_list, space);
-
- fil_space_remove_from_keyrotation(old);
- }
-
- /* Skip spaces that are being created by fil_ibd_create(),
- or dropped. Note that rotation_list contains only
- space->purpose == FIL_TABLESPACE. */
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping())) {
-
- old = space;
- space = UT_LIST_GET_NEXT(rotation_list, space);
- fil_space_remove_from_keyrotation(old);
- }
-
- if (space != NULL) {
- space->n_pending_ops++;
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(space);
-}
diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc
index edc1fa913e7..656d1d46a6a 100644
--- a/storage/xtradb/fil/fil0pagecompress.cc
+++ b/storage/xtradb/fil/fil0pagecompress.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2018, MariaDB Corporation.
+Copyright (C) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -243,24 +243,12 @@ success:
/* Set up the actual payload lenght */
mach_write_to_2(out_buf+FIL_PAGE_DATA, write_size);
-#ifdef UNIV_DEBUG
- /* Verify */
ut_ad(fil_page_is_compressed(out_buf) || fil_page_is_compressed_encrypted(out_buf));
ut_ad(mach_read_from_4(out_buf+FIL_PAGE_SPACE_OR_CHKSUM) == BUF_NO_CHECKSUM_MAGIC);
ut_ad(mach_read_from_2(out_buf+FIL_PAGE_DATA) == write_size);
ut_ad(mach_read_from_8(out_buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) == (ulint)comp_method ||
mach_read_from_2(out_buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE) == (ulint)comp_method);
- /* Verify that page can be decompressed */
- {
- page_t tmp_buf[UNIV_PAGE_SIZE_MAX];
- page_t page[UNIV_PAGE_SIZE_MAX];
- memcpy(page, out_buf, srv_page_size);
- ut_ad(fil_page_decompress(tmp_buf, page));
- ut_ad(!buf_page_is_corrupted(false, page, 0, NULL));
- }
-#endif /* UNIV_DEBUG */
-
write_size+=header_len;
if (block_size <= 0) {
diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc
index 5604a1b48c5..e9d26a5932b 100644
--- a/storage/xtradb/fsp/fsp0fsp.cc
+++ b/storage/xtradb/fsp/fsp0fsp.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -450,7 +450,7 @@ xdes_get_descriptor_with_space_hdr(
page_t* descr_page;
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET);
/* Read free limit and space size */
@@ -534,7 +534,7 @@ xdes_lst_get_descriptor(
ut_ad(mtr);
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
descr = fut_get_ptr(space, zip_size, lst_node, RW_X_LATCH, mtr)
- XDES_FLST_NODE;
@@ -690,7 +690,7 @@ fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
ut_ad(mtr);
- mtr_x_lock(fil_space_get_latch(space_id, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space_id, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
block = buf_page_create(space_id, 0, zip_size, mtr);
@@ -817,7 +817,7 @@ fsp_header_inc_size(
ut_ad(mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
header = fsp_get_space_header(space,
fsp_flags_get_zip_size(flags),
@@ -846,7 +846,7 @@ fsp_header_get_tablespace_size(void)
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(0, NULL), &mtr);
header = fsp_get_space_header(0, 0, &mtr);
@@ -1073,7 +1073,6 @@ fsp_fill_free_list(
ulint frag_n_used;
ulint actual_increase;
ulint i;
- mtr_t ibuf_mtr;
ut_ad(page_offset(header) == FSP_HEADER_OFFSET);
@@ -1141,26 +1140,17 @@ fsp_fill_free_list(
MLOG_2BYTES, mtr);
}
- /* Initialize the ibuf bitmap page in a separate
- mini-transaction because it is low in the latching
- order, and we must be able to release its latch
- before returning from the fsp routine */
-
- mtr_start(&ibuf_mtr);
-
block = buf_page_create(space,
- i + FSP_IBUF_BITMAP_OFFSET,
- zip_size, &ibuf_mtr);
+ i + FSP_IBUF_BITMAP_OFFSET,
+ zip_size, mtr);
buf_page_get(space, zip_size,
i + FSP_IBUF_BITMAP_OFFSET,
- RW_X_LATCH, &ibuf_mtr);
+ RW_X_LATCH, mtr);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
- fsp_init_file_page(block, &ibuf_mtr);
+ fsp_init_file_page(block, mtr);
- ibuf_bitmap_page_init(block, &ibuf_mtr);
-
- mtr_commit(&ibuf_mtr);
+ ibuf_bitmap_page_init(block, mtr);
}
descr = xdes_get_descriptor_with_space_hdr(header, space, i,
@@ -2047,7 +2037,7 @@ fseg_create_general(
header = byte_offset + buf_block_get_frame(block);
}
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
if (!has_done_reservation) {
success = fsp_reserve_free_extents(&n_reserved, space, 2,
@@ -2194,7 +2184,7 @@ fseg_n_reserved_pages(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -2617,7 +2607,7 @@ fseg_alloc_free_page_general(
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(seg_header, space, zip_size, mtr);
@@ -2734,7 +2724,7 @@ fsp_reserve_free_extents(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
space_header = fsp_get_space_header(space, zip_size, mtr);
try_again:
@@ -2873,7 +2863,7 @@ fsp_get_available_space_in_free_extents(
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
mutex_exit(&dict_sys->mutex);
@@ -3169,7 +3159,7 @@ fseg_free_page(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
seg_inode = fseg_inode_get(seg_header, space, zip_size, mtr);
@@ -3203,7 +3193,7 @@ fseg_page_is_free(
zip_size = dict_tf_get_zip_size(flags);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode = fseg_inode_get(seg_header, space, zip_size, &mtr);
@@ -3328,7 +3318,7 @@ fseg_free_step(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
@@ -3415,7 +3405,7 @@ fseg_free_step_not_header(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3541,7 +3531,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3564,7 +3554,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3590,7 +3580,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3628,7 +3618,7 @@ fseg_validate(
space = page_get_space_id(page_align(header));
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3704,7 +3694,7 @@ fseg_print(
space = page_get_space_id(page_align(header));
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3753,10 +3743,10 @@ fsp_validate(
/* Start first a mini-transaction mtr2 to lock out all other threads
from the fsp system */
mtr_start(&mtr2);
- mtr_x_lock(latch, &mtr2);
+ mtr_x_space_lock(latch, &mtr2);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3783,7 +3773,7 @@ fsp_validate(
/* Validate FSP_FREE list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FREE, &mtr);
@@ -3792,7 +3782,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3807,7 +3797,7 @@ fsp_validate(
/* Validate FSP_FREE_FRAG list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FREE_FRAG, &mtr);
@@ -3816,7 +3806,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3834,7 +3824,7 @@ fsp_validate(
/* Validate FSP_FULL_FRAG list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FULL_FRAG, &mtr);
@@ -3843,7 +3833,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3858,7 +3848,7 @@ fsp_validate(
/* Validate segments */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3873,7 +3863,7 @@ fsp_validate(
n = 0;
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -3902,7 +3892,7 @@ fsp_validate(
}
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3918,7 +3908,7 @@ fsp_validate(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -4002,11 +3992,11 @@ fsp_print(
mtr_start(&mtr2);
- mtr_x_lock(latch, &mtr2);
+ mtr_x_space_lock(latch, &mtr2);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4038,7 +4028,7 @@ fsp_print(
/* Print segments */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4053,7 +4043,7 @@ fsp_print(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -4075,7 +4065,7 @@ fsp_print(
}
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4090,7 +4080,7 @@ fsp_print(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -4147,7 +4137,8 @@ fsp_page_is_free_func(
ut_ad(mtr);
- mtr_x_lock_func(fil_space_get_latch(space, &flags), file, line, mtr);
+ mtr_x_space_lock_func(fil_space_get_latch(space, &flags), file, line,
+ mtr);
ulint zip_size = fsp_flags_get_zip_size(flags);
xdes_t* descr = xdes_get_descriptor(space, zip_size, page_no, mtr);
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 6dbe5e0e2a0..2a1341c4cf0 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -443,9 +443,9 @@ fts_read_stopword(
/******************************************************************//**
Load user defined stopword from designated user table
-@return TRUE if load operation is successful */
+@return whether the operation is successful */
static
-ibool
+bool
fts_load_user_stopword(
/*===================*/
fts_t* fts, /*!< in: FTS struct */
@@ -453,27 +453,26 @@ fts_load_user_stopword(
name */
fts_stopword_t* stopword_info) /*!< in: Stopword info */
{
- pars_info_t* info;
- que_t* graph;
- dberr_t error = DB_SUCCESS;
- ibool ret = TRUE;
- trx_t* trx;
- ibool has_lock = fts->dict_locked;
-
- trx = trx_allocate_for_background();
- trx->op_info = "Load user stopword table into FTS cache";
-
- if (!has_lock) {
+ if (!fts->dict_locked) {
mutex_enter(&dict_sys->mutex);
}
- /* Validate the user table existence and in the right
- format */
+ /* Validate the user table existence in the right format */
+ bool ret= false;
stopword_info->charset = fts_valid_stopword_table(stopword_table_name);
if (!stopword_info->charset) {
- ret = FALSE;
- goto cleanup;
- } else if (!stopword_info->cached_stopword) {
+cleanup:
+ if (!fts->dict_locked) {
+ mutex_exit(&dict_sys->mutex);
+ }
+
+ return ret;
+ }
+
+ trx_t* trx = trx_allocate_for_background();
+ trx->op_info = "Load user stopword table into FTS cache";
+
+ if (!stopword_info->cached_stopword) {
/* Create the stopword RB tree with the stopword column
charset. All comparison will use this charset */
stopword_info->cached_stopword = rbt_create_arg_cmp(
@@ -482,14 +481,14 @@ fts_load_user_stopword(
}
- info = pars_info_create();
+ pars_info_t* info = pars_info_create();
pars_info_bind_id(info, TRUE, "table_stopword", stopword_table_name);
pars_info_bind_function(info, "my_func", fts_read_stopword,
stopword_info);
- graph = fts_parse_sql_no_dict_lock(
+ que_t* graph = fts_parse_sql_no_dict_lock(
NULL,
info,
"DECLARE FUNCTION my_func;\n"
@@ -508,14 +507,13 @@ fts_load_user_stopword(
"CLOSE c;");
for (;;) {
- error = fts_eval_sql(trx, graph);
+ dberr_t error = fts_eval_sql(trx, graph);
if (error == DB_SUCCESS) {
fts_sql_commit(trx);
stopword_info->status = STOPWORD_USER_TABLE;
break;
} else {
-
fts_sql_rollback(trx);
ut_print_timestamp(stderr);
@@ -537,14 +535,9 @@ fts_load_user_stopword(
}
que_graph_free(graph);
-
-cleanup:
- if (!has_lock) {
- mutex_exit(&dict_sys->mutex);
- }
-
trx_free_for_background(trx);
- return(ret);
+ ret = true;
+ goto cleanup;
}
/******************************************************************//**
@@ -1134,14 +1127,14 @@ fts_cache_clear(
index_cache->doc_stats = NULL;
}
- mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
- cache->sync_heap->arg = NULL;
-
cache->total_size = 0;
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
cache->deleted_doc_ids = NULL;
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
+
+ mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
+ cache->sync_heap->arg = NULL;
}
/*********************************************************************//**
@@ -3495,8 +3488,8 @@ fts_add_doc_by_id(
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
- fts_load_stopword(table, NULL, NULL,
- NULL, TRUE, TRUE);
+ fts_load_stopword(table, NULL,
+ NULL, true, true);
}
fts_cache_add_doc(
@@ -7244,21 +7237,19 @@ This function loads the stopword into the FTS cache. It also
records/fetches stopword configuration to/from FTS configure
table, depending on whether we are creating or reloading the
FTS.
-@return TRUE if load operation is successful */
+@return true if load operation is successful */
UNIV_INTERN
-ibool
+bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transactions */
- const char* global_stopword_table, /*!< in: Global stopword table
- name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
- ibool stopword_is_on, /*!< in: Whether stopword
+ bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
- ibool reload) /*!< in: Whether it is
+ bool reload) /*!< in: Whether it is
for reloading FTS table */
{
fts_table_t fts_table;
@@ -7274,9 +7265,8 @@ fts_load_stopword(
cache = table->fts->cache;
- if (!reload && !(cache->stopword_info.status
- & STOPWORD_NOT_INIT)) {
- return(TRUE);
+ if (!reload && !(cache->stopword_info.status & STOPWORD_NOT_INIT)) {
+ return true;
}
if (!trx) {
@@ -7321,12 +7311,11 @@ fts_load_stopword(
goto cleanup;
}
- if (strlen((char*) str.f_str) > 0) {
+ if (*str.f_str) {
stopword_to_use = (const char*) str.f_str;
}
} else {
- stopword_to_use = (session_stopword_table)
- ? session_stopword_table : global_stopword_table;
+ stopword_to_use = session_stopword_table;
}
if (stopword_to_use
@@ -7363,7 +7352,7 @@ cleanup:
sizeof(fts_tokenizer_word_t), fts_utf8_string_cmp);
}
- return(error == DB_SUCCESS);
+ return error == DB_SUCCESS;
}
/**********************************************************************//**
@@ -7569,7 +7558,7 @@ fts_init_index(
} else {
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
- fts_load_stopword(table, NULL, NULL, NULL, TRUE, TRUE);
+ fts_load_stopword(table, NULL, NULL, true, true);
}
for (ulint i = 0; i < ib_vector_size(cache->get_docs); ++i) {
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index 8fce8efac2b..0c51e702907 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -146,6 +146,8 @@ struct fts_query_t {
fts_word_freq_t */
bool multi_exist; /*!< multiple FTS_EXIST oper */
+ byte visiting_sub_exp; /*!< count of nested
+ fts_ast_visit_sub_exp() */
};
/** For phrase matching, first we collect the documents and the positions
@@ -2856,6 +2858,8 @@ fts_query_get_token(
return(new_ptr);
}
+static dberr_t fts_ast_visit_sub_exp(fts_ast_node_t*, fts_ast_callback, void*);
+
/*****************************************************************//**
Visit every node of the AST. */
static
@@ -2945,7 +2949,7 @@ Process (nested) sub-expression, create a new result set to store the
sub-expression result by processing nodes under current sub-expression
list. Merge the sub-expression result with that of parent expression list.
@return DB_SUCCESS if all well */
-UNIV_INTERN
+static
dberr_t
fts_ast_visit_sub_exp(
/*==================*/
@@ -2965,6 +2969,14 @@ fts_ast_visit_sub_exp(
ut_a(node->type == FTS_AST_SUBEXP_LIST);
+ /* To avoid stack overflow, we limit the mutual recursion
+ depth between fts_ast_visit(), fts_query_visitor() and
+ fts_ast_visit_sub_exp(). */
+ if (query->visiting_sub_exp++ > 31) {
+ query->error = DB_OUT_OF_MEMORY;
+ DBUG_RETURN(query->error);
+ }
+
cur_oper = query->oper;
/* Save current result set */
@@ -2987,6 +2999,7 @@ fts_ast_visit_sub_exp(
/* Reinstate parent node state */
query->multi_exist = multi_exist;
query->oper = cur_oper;
+ query->visiting_sub_exp--;
/* Merge the sub-expression result with the parent result set. */
subexpr_doc_ids = query->doc_ids;
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 770f3dc2440..08aae20f3d3 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1,11 +1,10 @@
/*****************************************************************************
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1939,8 +1938,7 @@ innobase_srv_conc_enter_innodb(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
if (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1978,8 +1976,7 @@ innobase_srv_conc_exit_innodb(
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
#endif /* UNIV_SYNC_DEBUG */
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
/* This is to avoid making an unnecessary function call. */
@@ -2922,6 +2919,9 @@ innobase_trx_init(
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
+#ifdef WITH_WSREP
+ trx->wsrep = wsrep_on(thd);
+#endif
/* Transaction on start caches the fake_changes state and uses it for
complete transaction lifetime.
@@ -4645,20 +4645,9 @@ innobase_commit_low(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
- THD* thd = (THD*)trx->mysql_thd;
const char* tmp = 0;
- if (thd && wsrep_on(thd)) {
-#ifdef WSREP_PROC_INFO
- char info[64];
- info[sizeof(info) - 1] = '\0';
- snprintf(info, sizeof(info) - 1,
- "innobase_commit_low():trx_commit_for_mysql(%lld)",
- (long long) wsrep_thd_trx_seqno(thd));
- tmp = thd_proc_info(thd, info);
-
-#else
- tmp = thd_proc_info(thd, "innobase_commit_low()");
-#endif /* WSREP_PROC_INFO */
+ if (trx->is_wsrep()) {
+ tmp = thd_proc_info(trx->mysql_thd, "innobase_commit_low()");
}
#endif /* WITH_WSREP */
if (trx_is_started(trx)) {
@@ -4666,7 +4655,7 @@ innobase_commit_low(
trx_commit_for_mysql(trx);
}
#ifdef WITH_WSREP
- if (thd && wsrep_on(thd)) { thd_proc_info(thd, tmp); }
+ if (trx->is_wsrep()) { thd_proc_info(trx->mysql_thd, tmp); }
#endif /* WITH_WSREP */
}
@@ -8676,19 +8665,19 @@ ha_innobase::write_row(
sql_command = thd_sql_command(user_thd);
- if ((sql_command == SQLCOM_ALTER_TABLE
- || sql_command == SQLCOM_OPTIMIZE
- || sql_command == SQLCOM_CREATE_INDEX
+ if (num_write_row >= 10000
+ && (sql_command == SQLCOM_ALTER_TABLE
+ || sql_command == SQLCOM_OPTIMIZE
+ || sql_command == SQLCOM_CREATE_INDEX
#ifdef WITH_WSREP
- || (wsrep_on(user_thd) && wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
- !thd_test_options(
- user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ || (sql_command == SQLCOM_LOAD &&
+ trx->is_wsrep() && wsrep_load_data_splitting &&
+ !thd_test_options(
+ user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
#endif /* WITH_WSREP */
- || sql_command == SQLCOM_DROP_INDEX)
- && num_write_row >= 10000) {
+ || sql_command == SQLCOM_DROP_INDEX)) {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) && sql_command == SQLCOM_LOAD) {
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep()) {
WSREP_DEBUG("forced trx split for LOAD: %s",
wsrep_thd_query(user_thd));
}
@@ -8727,9 +8716,8 @@ no_commit:
;
} else if (src_table == prebuilt->table) {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) &&
- wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep() &&
+ wsrep_load_data_splitting &&
!thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
@@ -8759,9 +8747,8 @@ no_commit:
prebuilt->sql_stat_start = TRUE;
} else {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) &&
- wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep() &&
+ wsrep_load_data_splitting &&
!thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
@@ -8906,21 +8893,19 @@ no_commit:
prebuilt->autoinc_offset,
prebuilt->autoinc_increment);
- if (wsrep_on(current_thd) &&
+ if (trx->is_wsrep() &&
auto_inc_inserted &&
wsrep_drupal_282555_workaround &&
- wsrep_thd_retry_counter(current_thd) == 0 &&
- !thd_test_options(current_thd,
+ wsrep_thd_retry_counter(user_thd) == 0 &&
+ !thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT |
OPTION_BEGIN)) {
WSREP_DEBUG(
"retrying insert: %s",
- (*wsrep_thd_query(current_thd)) ?
- wsrep_thd_query(current_thd) :
- (char *)"void");
+ wsrep_thd_query(user_thd));
error= DB_SUCCESS;
wsrep_thd_set_conflict_state(
- current_thd, MUST_ABORT);
+ user_thd, MUST_ABORT);
innobase_srv_conc_exit_innodb(prebuilt->trx);
/* jump straight to func exit over
* later wsrep hooks */
@@ -8989,18 +8974,16 @@ report_error:
user_thd);
#ifdef WITH_WSREP
- if (!error_result
- && wsrep_on(user_thd)
- && wsrep_thd_exec_mode(user_thd) == LOCAL_STATE
+ if (!error_result && trx->is_wsrep()
+ && wsrep_thd_exec_mode(user_thd) == LOCAL_STATE
&& !wsrep_consistency_check(user_thd)
&& !wsrep_thd_ignore_table(user_thd)) {
if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record, NULL)) {
DBUG_PRINT("wsrep", ("row key failed"));
error_result = HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ goto func_exit;
}
}
-wsrep_error:
#endif /* WITH_WSREP */
if (error_result == HA_FTS_INVALID_DOCID) {
@@ -9508,9 +9491,8 @@ func_exit:
innobase_active_small();
#ifdef WITH_WSREP
- if (error == DB_SUCCESS &&
+ if (error == DB_SUCCESS && trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == LOCAL_STATE &&
- wsrep_on(user_thd) &&
!wsrep_thd_ignore_table(user_thd))
{
DBUG_PRINT("wsrep", ("update row key"));
@@ -9519,11 +9501,9 @@ func_exit:
new_row)) {
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED");
DBUG_PRINT("wsrep", ("row key failed"));
- err = HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
-wsrep_error:
#endif /* WITH_WSREP */
DBUG_RETURN(err);
@@ -9570,25 +9550,20 @@ ha_innobase::delete_row(
/* Tell the InnoDB server that there might be work for
utility threads: */
-
innobase_active_small();
#ifdef WITH_WSREP
- if (error == DB_SUCCESS &&
+ if (error == DB_SUCCESS && trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == LOCAL_STATE &&
- wsrep_on(user_thd) &&
!wsrep_thd_ignore_table(user_thd))
{
if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record,
- NULL)) {
+ NULL)) {
DBUG_PRINT("wsrep", ("delete fail"));
- error = (dberr_t) HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
-wsrep_error:
#endif /* WITH_WSREP */
-
DBUG_RETURN(convert_error_code_to_mysql(
error, prebuilt->table->flags, user_thd));
}
@@ -10844,8 +10819,7 @@ wsrep_append_foreign_key(
int cache_key_len;
bool const copy = true;
- if (!wsrep_on(trx->mysql_thd) ||
- wsrep_thd_exec_mode(thd) != LOCAL_STATE)
+ if (!trx->is_wsrep() || wsrep_thd_exec_mode(thd) != LOCAL_STATE)
return DB_SUCCESS;
if (!thd || !foreign ||
@@ -12000,10 +11974,17 @@ innobase_fts_load_stopword(
trx_t* trx, /*!< in: transaction */
THD* thd) /*!< in: current thread */
{
- return(fts_load_stopword(table, trx,
- innobase_server_stopword_table,
- THDVAR(thd, ft_user_stopword_table),
- THDVAR(thd, ft_enable_stopword), FALSE));
+ const char *stopword_table= THDVAR(thd, ft_user_stopword_table);
+ if (!stopword_table)
+ {
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ if (innobase_server_stopword_table)
+ stopword_table= thd_strdup(thd, innobase_server_stopword_table);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ }
+
+ return fts_load_stopword(table, trx, stopword_table,
+ THDVAR(thd, ft_enable_stopword), false);
}
/*****************************************************************//**
@@ -15468,12 +15449,11 @@ ha_innobase::external_lock(
THD* thd, /*!< in: handle to the user thread */
int lock_type) /*!< in: lock type */
{
- trx_t* trx;
-
DBUG_ENTER("ha_innobase::external_lock");
DBUG_PRINT("enter",("lock_type: %d", lock_type));
update_thd(thd);
+ trx_t* trx = prebuilt->trx;
/* Statement based binlogging does not work in isolation level
READ UNCOMMITTED and READ COMMITTED since the necessary
@@ -15487,22 +15467,19 @@ ha_innobase::external_lock(
&& thd_binlog_format(thd) == BINLOG_FORMAT_STMT
&& thd_binlog_filter_ok(thd)
&& thd_sqlcom_can_generate_row_events(thd)) {
- bool skip = 0;
+ bool skip = false;
+#ifdef WITH_WSREP
+ skip = trx->is_wsrep()
+ && wsrep_thd_exec_mode(thd) != LOCAL_STATE;
+#endif /* WITH_WSREP */
/* used by test case */
DBUG_EXECUTE_IF("no_innodb_binlog_errors", skip = true;);
if (!skip) {
-#ifdef WITH_WSREP
- if (!wsrep_on(thd) || wsrep_thd_exec_mode(thd) == LOCAL_STATE)
- {
-#endif /* WITH_WSREP */
- my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
- " InnoDB is limited to row-logging when "
- "transaction isolation level is "
- "READ COMMITTED or READ UNCOMMITTED.");
- DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE);
-#ifdef WITH_WSREP
- }
-#endif /* WITH_WSREP */
+ my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
+ " InnoDB is limited to row-logging when "
+ "transaction isolation level is "
+ "READ COMMITTED or READ UNCOMMITTED.");
+ DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE);
}
}
@@ -15533,8 +15510,6 @@ ha_innobase::external_lock(
}
- trx = prebuilt->trx;
-
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
@@ -17716,7 +17691,6 @@ innodb_stopword_table_validate(
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
trx_t* trx;
- int ret = 1;
ut_a(save != NULL);
ut_a(value != NULL);
@@ -17729,14 +17703,22 @@ innodb_stopword_table_validate(
/* Validate the stopword table's (if supplied) existence and
of the right format */
- if (!stopword_table_name
- || fts_valid_stopword_table(stopword_table_name)) {
- *static_cast<const char**>(save) = stopword_table_name;
- ret = 0;
- }
+ int ret = stopword_table_name && !fts_valid_stopword_table(
+ stopword_table_name);
row_mysql_unlock_data_dictionary(trx);
+ if (!ret) {
+ if (stopword_table_name == buff) {
+ ut_ad(static_cast<size_t>(len) < sizeof buff);
+ stopword_table_name = thd_strmake(thd,
+ stopword_table_name,
+ len);
+ }
+
+ *static_cast<const char**>(save) = stopword_table_name;
+ }
+
return(ret);
}
@@ -17744,9 +17726,10 @@ innodb_stopword_table_validate(
static char* innodb_ft_aux_table;
/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table.
+@param[in,out] thd connection
@param[out] save new value of innodb_ft_aux_table
@param[in] value user-specified value */
-static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
+static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*,
void* save, st_mysql_value* value)
{
char buf[STRING_BUFFER_USUAL_SIZE];
@@ -17760,6 +17743,15 @@ static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
dict_table_close(table, FALSE, FALSE);
if (id) {
innodb_ft_aux_table_id = id;
+ if (table_name == buf) {
+ ut_ad(static_cast<size_t>(len)
+ < sizeof buf);
+ table_name = thd_strmake(thd,
+ table_name,
+ len);
+ }
+
+
*static_cast<const char**>(save) = table_name;
return 0;
}
@@ -18458,52 +18450,43 @@ exit:
return;
}
-#ifdef __WIN__
-/*************************************************************//**
-Validate if passed-in "value" is a valid value for
-innodb_buffer_pool_filename. On Windows, file names with colon (:)
-are not allowed.
-
+/** Validate SET GLOBAL innodb_buffer_pool_filename.
+On Windows, file names with colon (:) are not allowed.
+@param thd connection
+@param save &srv_buf_dump_filename
+@param value new value to be validated
@return 0 for valid name */
-static
-int
-innodb_srv_buf_dump_filename_validate(
-/*==================================*/
- THD* thd, /*!< in: thread handle */
- struct st_mysql_sys_var* var, /*!< in: pointer to system
- variable */
- void* save, /*!< out: immediate result
- for update function */
- struct st_mysql_value* value) /*!< in: incoming string */
+static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*,
+ void *save,
+ st_mysql_value *value)
{
- const char* buf_name;
- char buff[OS_FILE_MAX_PATH];
- int len= sizeof(buff);
-
- ut_a(save != NULL);
- ut_a(value != NULL);
-
- buf_name = value->val_str(value, buff, &len);
-
- if (buf_name) {
- if (is_filename_allowed(buf_name, len, FALSE)){
- *static_cast<const char**>(save) = buf_name;
- return(0);
- } else {
- push_warning_printf(thd,
- Sql_condition::WARN_LEVEL_WARN,
- ER_WRONG_ARGUMENTS,
- "InnoDB: innodb_buffer_pool_filename "
- "cannot have colon (:) in the file name.");
+ char buff[OS_FILE_MAX_PATH];
+ int len= sizeof buff;
- }
- }
+ if (const char *buf_name= value->val_str(value, buff, &len))
+ {
+#ifdef __WIN__
+ if (!is_filename_allowed(buf_name, len, FALSE))
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "InnoDB: innodb_buffer_pool_filename "
+ "cannot have colon (:) in the file name.");
+ return 1;
+ }
+#endif /* __WIN__ */
+ if (buf_name == buff)
+ {
+ ut_ad(static_cast<size_t>(len) < sizeof buff);
+ buf_name= thd_strmake(thd, buf_name, len);
+ }
+
+ *static_cast<const char**>(save)= buf_name;
+ return 0;
+ }
- return(1);
+ return 1;
}
-#else /* __WIN__ */
-# define innodb_srv_buf_dump_filename_validate NULL
-#endif /* __WIN__ */
#ifdef UNIV_DEBUG
static char* srv_buffer_pool_evict;
@@ -19392,11 +19375,14 @@ static
void
innodb_status_output_update(THD*,st_mysql_sys_var*,void*var,const void*save)
{
- *static_cast<my_bool*>(var) = *static_cast<const my_bool*>(save);
- mysql_mutex_unlock(&LOCK_global_system_variables);
- /* Wakeup server monitor thread. */
- os_event_set(srv_monitor_event);
- mysql_mutex_lock(&LOCK_global_system_variables);
+ *static_cast<my_bool*>(var)= *static_cast<const my_bool*>(save);
+ if (srv_monitor_event)
+ {
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ /* Wakeup server monitor thread. */
+ os_event_set(srv_monitor_event);
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ }
}
/** Update the system variable innodb_encryption_threads.
@@ -21006,7 +20992,7 @@ static MYSQL_SYSVAR_UINT(data_file_size_debug,
srv_sys_space_size_debug,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"InnoDB system tablespace size to be set in recovery.",
- NULL, NULL, 0, 0, UINT_MAX32, 0);
+ NULL, NULL, 0, 0, 256U << 20, 0);
static MYSQL_SYSVAR_ULONG(fil_make_page_dirty_debug,
srv_fil_make_page_dirty_debug, PLUGIN_VAR_OPCMDARG,
@@ -21082,7 +21068,7 @@ static TYPELIB page_compression_algorithms_typelib=
};
static MYSQL_SYSVAR_ENUM(compression_algorithm, innodb_compression_algorithm,
PLUGIN_VAR_OPCMDARG,
- "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2",
+ "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, bzip2, or snappy",
innodb_compression_algorithm_validate, NULL,
/* We use here the largest number of supported compression method to
enable all those methods that are available. Availability of compression
@@ -21133,7 +21119,7 @@ static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,
"scrubbing",
NULL,
innodb_encryption_threads_update,
- srv_n_fil_crypt_threads, 0, UINT_MAX32, 0);
+ 0, 0, 255, 0);
static MYSQL_SYSVAR_UINT(encryption_rotate_key_age,
srv_fil_crypt_rotate_key_age,
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 2ce30488d8c..41cd0ab37c6 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -3388,6 +3388,12 @@ err_exit:
trx_free_for_mysql(ctx->trx);
trx_commit_for_mysql(ctx->prebuilt->trx);
+ for (uint i = 0; i < ctx->num_to_add_fk; i++) {
+ if (ctx->add_fk[i]) {
+ dict_foreign_free(ctx->add_fk[i]);
+ }
+ }
+
delete ctx;
ha_alter_info->handler_ctx = NULL;
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 8eb53502da8..9813e993411 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -2553,7 +2553,7 @@ i_s_metrics_fill(
time_diff = 0;
}
- /* Unless MONITOR__NO_AVERAGE is marked, we will need
+ /* Unless MONITOR_NO_AVERAGE is set, we must
to calculate the average value. If this is a monitor set
owner marked by MONITOR_SET_OWNER, divide
the value by another counter (number of calls) designated
@@ -2561,8 +2561,9 @@ i_s_metrics_fill(
Otherwise average the counter value by the time between the
time that the counter is enabled and time it is disabled
or time it is sampled. */
- if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
- && (monitor_info->monitor_type & MONITOR_SET_OWNER)
+ if ((monitor_info->monitor_type
+ & (MONITOR_NO_AVERAGE | MONITOR_SET_OWNER))
+ == MONITOR_SET_OWNER
&& monitor_info->monitor_related_id) {
mon_type_t value_start
= MONITOR_VALUE_SINCE_START(
@@ -2578,18 +2579,18 @@ i_s_metrics_fill(
fields[METRIC_AVG_VALUE_START]->set_null();
}
- if (MONITOR_VALUE(monitor_info->monitor_related_id)) {
- OK(fields[METRIC_AVG_VALUE_RESET]->store(
- MONITOR_VALUE(count)
- / MONITOR_VALUE(
- monitor_info->monitor_related_id),
- FALSE));
+ if (mon_type_t related_value =
+ MONITOR_VALUE(monitor_info->monitor_related_id)) {
+ OK(fields[METRIC_AVG_VALUE_RESET]
+ ->store(MONITOR_VALUE(count)
+ / related_value, false));
+ fields[METRIC_AVG_VALUE_RESET]->set_notnull();
} else {
fields[METRIC_AVG_VALUE_RESET]->set_null();
}
- } else if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
- && !(monitor_info->monitor_type
- & MONITOR_DISPLAY_CURRENT)) {
+ } else if (!(monitor_info->monitor_type
+ & (MONITOR_NO_AVERAGE
+ | MONITOR_DISPLAY_CURRENT))) {
if (time_diff) {
OK(fields[METRIC_AVG_VALUE_START]->store(
(double) MONITOR_VALUE_SINCE_START(
@@ -3367,6 +3368,8 @@ no_fts:
conv_str.f_len = sizeof word;
conv_str.f_str = word;
+ rw_lock_s_lock(&cache->lock);
+
for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) {
fts_index_cache_t* index_cache;
@@ -3377,6 +3380,7 @@ no_fts:
index_cache, thd, &conv_str, tables));
}
+ rw_lock_s_unlock(&cache->lock);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc
index 264d1677afa..6f11daa7363 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.cc
+++ b/storage/xtradb/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -63,6 +63,7 @@ UNIV_INTERN my_bool srv_ibuf_disable_background_merge;
#include "que0que.h"
#include "srv0start.h" /* srv_shutdown_state */
#include "ha_prototypes.h"
+#include "ut0crc32.h"
#include "rem0cmp.h"
/* STRUCTURE OF AN INSERT BUFFER RECORD
@@ -587,7 +588,7 @@ ibuf_init_at_db_start(void)
mutex_enter(&ibuf_mutex);
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, NULL), &mtr);
header_page = ibuf_header_page_get(&mtr);
@@ -2138,7 +2139,7 @@ ibuf_add_free_page(void)
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
header_page = ibuf_header_page_get(&mtr);
@@ -2222,7 +2223,7 @@ ibuf_remove_free_page(void)
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
header_page = ibuf_header_page_get(&mtr);
@@ -2925,42 +2926,28 @@ ibuf_contract_after_insert(
} while (size > 0 && sum_sizes < entry_size);
}
-/*********************************************************************//**
-Determine if an insert buffer record has been encountered already.
-@return TRUE if a new record, FALSE if possible duplicate */
-static
-ibool
-ibuf_get_volume_buffered_hash(
-/*==========================*/
- const rec_t* rec, /*!< in: ibuf record in post-4.1 format */
- const byte* types, /*!< in: fields */
- const byte* data, /*!< in: start of user record data */
- ulint comp, /*!< in: 0=ROW_FORMAT=REDUNDANT,
- nonzero=ROW_FORMAT=COMPACT */
- ulint* hash, /*!< in/out: hash array */
- ulint size) /*!< in: number of elements in hash array */
+/** Determine if a change buffer record has been encountered already.
+@param rec change buffer record in the MySQL 5.5 format
+@param hash hash table of encountered records
+@param size number of elements in hash
+@retval true if a distinct record
+@retval false if this may be duplicating an earlier record */
+static bool ibuf_get_volume_buffered_hash(const rec_t *rec, ulint *hash,
+ ulint size)
{
- ulint len;
- ulint fold;
- ulint bitmask;
-
- len = ibuf_rec_get_size(
- rec, types,
- rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER, comp);
- fold = ut_fold_binary(data, len);
-
- hash += (fold / (CHAR_BIT * sizeof *hash)) % size;
- bitmask = static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
-
- if (*hash & bitmask) {
-
- return(FALSE);
- }
-
- /* We have not seen this record yet. Insert it. */
- *hash |= bitmask;
-
- return(TRUE);
+ ut_ad(rec_get_n_fields_old(rec) > IBUF_REC_FIELD_USER);
+ const ulint start= rec_get_field_start_offs(rec, IBUF_REC_FIELD_USER);
+ const ulint len= rec_get_data_size_old(rec) - start;
+ const uint32_t fold= ut_crc32(rec + start, len);
+ hash+= (fold / (CHAR_BIT * sizeof *hash)) % size;
+ ulint bitmask= static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
+
+ if (*hash & bitmask)
+ return false;
+
+ /* We have not seen this record yet. Remember it. */
+ *hash|= bitmask;
+ return true;
}
#ifdef UNIV_DEBUG
@@ -3052,11 +3039,7 @@ ibuf_get_volume_buffered_count_func(
case IBUF_OP_DELETE_MARK:
/* There must be a record to delete-mark.
See if this record has been already buffered. */
- if (n_recs && ibuf_get_volume_buffered_hash(
- rec, types + IBUF_REC_INFO_SIZE,
- types + len,
- types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT,
- hash, size)) {
+ if (n_recs && ibuf_get_volume_buffered_hash(rec, hash, size)) {
(*n_recs)++;
}
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index e8a82f2e3e4..39fceeef384 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -1528,7 +1528,7 @@ buf_page_encrypt_before_write(
NOTE! The definition appears here only for other modules of this
directory (buf) to see it. Do not use from outside! */
-typedef struct {
+struct buf_tmp_buffer_t {
private:
int32 reserved; /*!< true if this slot is reserved
*/
@@ -1558,7 +1558,7 @@ public:
return !my_atomic_fas32_explicit(&reserved, true,
MY_MEMORY_ORDER_RELAXED);
}
-} buf_tmp_buffer_t;
+};
/** The common buffer control block structure
for compressed and uncompressed frames */
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 7256f7f119b..d8df624b5f2 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -1026,16 +1026,18 @@ dict_table_x_lock_indexes(
/*======================*/
dict_table_t* table) /*!< in: table */
{
- dict_index_t* index;
-
ut_ad(mutex_own(&dict_sys->mutex));
+ dict_index_t* clust_index = dict_table_get_first_index(table);
+
/* Loop through each index of the table and lock them */
- for (index = dict_table_get_first_index(table);
+ for (dict_index_t* index = dict_table_get_next_index(clust_index);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
}
+
+ rw_lock_x_lock(dict_index_get_lock(clust_index));
}
/*********************************************************************//**
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index 1dcc3ebdd0c..f39c89d8e4b 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -864,6 +864,10 @@ struct dict_foreign_t{
does not generate new indexes
implicitly */
dict_index_t* referenced_index;/*!< referenced index */
+
+ /** Check whether the fulltext index gets affected by
+ foreign key constraint */
+ bool affects_fulltext() const;
};
std::ostream&
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index a4274f4d8a6..78878fa75fc 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -300,6 +300,8 @@ struct fil_space_t {
/*!< recovered tablespace size in pages;
0 if no size change was read from the redo log,
or if the size change was implemented */
+ /** the committed size of the tablespace in pages */
+ ulint committed_size;
ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
see fsp0fsp.h,
fsp_flags_is_valid(),
@@ -364,6 +366,15 @@ struct fil_space_t {
{
return stop_new_ops;
}
+
+ /** Clamp a page number for batched I/O, such as read-ahead.
+ @param offset page number limit
+ @return offset clamped to the tablespace size */
+ ulint max_page_number_for_io(ulint offset) const
+ {
+ const ulint limit= committed_size;
+ return limit > offset ? offset : limit;
+ }
};
/** Value of fil_space_t::magic_n */
@@ -574,16 +585,6 @@ ulint
fil_space_get_zip_size(
/*===================*/
ulint id); /*!< in: space id */
-/*******************************************************************//**
-Checks if the pair space, page_no refers to an existing page in a tablespace
-file space. The tablespace must be cached in the memory cache.
-@return TRUE if the address is meaningful */
-UNIV_INTERN
-ibool
-fil_check_adress_in_tablespace(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint page_no);/*!< in: page number */
/****************************************************************//**
Initializes the tablespace memory cache. */
UNIV_INTERN
@@ -704,34 +705,6 @@ UNIV_INTERN
void
fil_space_release_for_io(fil_space_t* space);
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last */
-UNIV_INTERN
-fil_space_t*
-fil_space_next(
- fil_space_t* prev_space)
- MY_ATTRIBUTE((warn_unused_result));
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_keyrotate_next(
- fil_space_t* prev_space)
- MY_ATTRIBUTE((warn_unused_result));
-
/** Wrapper with reference-counting for a fil_space_t. */
class FilSpace
{
diff --git a/storage/xtradb/include/fts0ast.h b/storage/xtradb/include/fts0ast.h
index b7d467e0082..b7870cbc7bc 100644
--- a/storage/xtradb/include/fts0ast.h
+++ b/storage/xtradb/include/fts0ast.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -204,19 +204,6 @@ fts_ast_visit(
operator, currently we only
ignore FTS_IGNORE operator */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*****************************************************************//**
-Process (nested) sub-expression, create a new result set to store the
-sub-expression result by processing nodes under current sub-expression
-list. Merge the sub-expression result with that of parent expression list.
-@return DB_SUCCESS if all went well */
-UNIV_INTERN
-dberr_t
-fts_ast_visit_sub_exp(
-/*==================*/
- fts_ast_node_t* node, /*!< in: instance to traverse*/
- fts_ast_callback visitor, /*!< in: callback */
- void* arg) /*!< in: callback arg */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
/********************************************************************
Create a lex instance.*/
UNIV_INTERN
diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h
index 714f811db27..4d07ac1612f 100644
--- a/storage/xtradb/include/fts0fts.h
+++ b/storage/xtradb/include/fts0fts.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -899,21 +899,19 @@ fts_valid_stopword_table(
name */
/****************************************************************//**
This function loads specified stopword into FTS cache
-@return TRUE if success */
+@return true if success */
UNIV_INTERN
-ibool
+bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transaction */
- const char* global_stopword_table, /*!< in: Global stopword table
- name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
- ibool stopword_is_on, /*!< in: Whether stopword
+ bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
- ibool reload); /*!< in: Whether it is during
+ bool reload); /*!< in: Whether it is during
reload of FTS table */
/****************************************************************//**
diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h
index 878a42ea81b..a6b6e08b68b 100644
--- a/storage/xtradb/include/lock0lock.h
+++ b/storage/xtradb/include/lock0lock.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1013,8 +1014,6 @@ std::string
lock_get_info(
const lock_t*);
-#define wsrep_on_trx(trx) ((trx)->mysql_thd && wsrep_on((trx)->mysql_thd))
-
#ifndef UNIV_NONINL
#include "lock0lock.ic"
#endif
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index 2d3da4d2a25..7d115eed5fd 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -57,6 +58,7 @@ first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
#endif /* UNIV_DEBUG */
#define MTR_MEMO_S_LOCK 55
#define MTR_MEMO_X_LOCK 56
+#define MTR_MEMO_SPACE_X_LOCK 57
/** @name Log item types
The log items are declared 'byte' so that the compiler can warn if val
@@ -293,6 +295,8 @@ This macro locks an rw-lock in s-mode. */
This macro locks an rw-lock in x-mode. */
#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), __FILE__, __LINE__,\
(MTR))
+#define mtr_x_space_lock(B, MTR) mtr_x_space_lock_func(B, __FILE__, __LINE__,\
+ MTR)
/*********************************************************************//**
NOTE! Use the macro above!
Locks a lock in s-mode. */
@@ -315,6 +319,14 @@ mtr_x_lock_func(
const char* file, /*!< in: file name */
ulint line, /*!< in: line number */
mtr_t* mtr); /*!< in: mtr */
+
+/** Acquire exclusive tablespace latch.
+@param lock fil_space_t::latch
+@param file source code file name of the caller
+@param line source code line number of the caller
+@param mtr mini-transaction */
+inline void mtr_x_space_lock_func(prio_rw_lock_t *lock,
+ const char *file, ulint line, mtr_t *mtr);
#endif /* !UNIV_HOTBACKUP */
/***************************************************//**
diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic
index a44728463ae..0aea0994267 100644
--- a/storage/xtradb/include/mtr0mtr.ic
+++ b/storage/xtradb/include/mtr0mtr.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -78,7 +79,7 @@ mtr_memo_push(
ut_ad(object);
ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
- ut_ad(type <= MTR_MEMO_X_LOCK);
+ ut_ad(type <= MTR_MEMO_SPACE_X_LOCK);
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
@@ -293,4 +294,16 @@ mtr_x_lock_func(
mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK);
}
+
+/** Acquire exclusive tablespace latch.
+@param lock fil_space_t::latch
+@param file source code file name of the caller
+@param line source code line number of the caller
+@param mtr mini-transaction */
+inline void mtr_x_space_lock_func(prio_rw_lock_t *lock,
+ const char *file, ulint line, mtr_t *mtr)
+{
+ rw_lock_x_lock_inline(lock, 0, file, line);
+ mtr_memo_push(mtr, lock, MTR_MEMO_SPACE_X_LOCK);
+}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/page0page.h b/storage/xtradb/include/page0page.h
index 2efc2d302a1..b377aa68ac7 100644
--- a/storage/xtradb/include/page0page.h
+++ b/storage/xtradb/include/page0page.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -749,21 +749,6 @@ page_mem_alloc_free(
free record list */
ulint need); /*!< in: number of bytes allocated */
/************************************************************//**
-Allocates a block of memory from the heap of an index page.
-@return pointer to start of allocated buffer, or NULL if allocation fails */
-UNIV_INTERN
-byte*
-page_mem_alloc_heap(
-/*================*/
- page_t* page, /*!< in/out: index page */
- page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
- space available for inserting the record,
- or NULL */
- ulint need, /*!< in: total number of bytes needed */
- ulint* heap_no);/*!< out: this contains the heap number
- of the allocated record
- if allocation succeeds */
-/************************************************************//**
Puts a record to free list. */
UNIV_INLINE
void
diff --git a/storage/xtradb/include/sync0rw.h b/storage/xtradb/include/sync0rw.h
index 2e25a27192e..19b4793fc7b 100644
--- a/storage/xtradb/include/sync0rw.h
+++ b/storage/xtradb/include/sync0rw.h
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -763,13 +764,6 @@ struct rw_lock_t {
/* last s-lock file/line is not guaranteed to be correct */
const char* last_s_file_name;/*!< File name where last s-locked */
const char* last_x_file_name;/*!< File name where last x-locked */
- ibool writer_is_wait_ex;
- /*!< This is TRUE if the writer field is
- RW_LOCK_WAIT_EX; this field is located far
- from the memory update hotspot fields which
- are at the start of this struct, thus we can
- peek this field without causing much memory
- bus traffic */
unsigned cline:14; /*!< Line where created */
unsigned last_s_line:14; /*!< Line number where last time s-locked */
unsigned last_x_line:14; /*!< Line number where last time x-locked */
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index e833bd0341f..2d7baff6b04 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -815,15 +815,21 @@ struct trx_t{
ro_trx_list the first time they try to acquire a lock ie. by default
we treat all read-only transactions as non-locking. */
trx_state_t state;
-
trx_lock_t lock; /*!< Information about the transaction
locks and state. Protected by
trx->mutex or lock_sys->mutex
or both */
- ulint is_recovered; /*!< 0=normal transaction,
- 1=recovered, must be rolled back,
+ bool is_recovered; /*!< false=normal transaction,
+ true=recovered, must be rolled back,
protected by trx_sys->mutex when
trx->in_rw_trx_list holds */
+#ifdef WITH_WSREP
+ /** whether wsrep_on(mysql_thd) held at the start of transaction */
+ bool wsrep;
+ bool is_wsrep() const { return UNIV_UNLIKELY(wsrep); }
+#else /* WITH_WSREP */
+ bool is_wsrep() const { return false; }
+#endif /* WITH_WSREP */
/* These fields are not protected by any mutex. */
const char* op_info; /*!< English text describing the
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 011921d9a39..61a8639691a 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -45,10 +45,10 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 45
+#define INNODB_VERSION_BUGFIX 49
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 86.1
+#define PERCONA_INNODB_VERSION 89.0
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index c110c83cbe7..4d40111ac20 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1770,7 +1770,7 @@ wsrep_kill_victim(
ut_ad(trx_mutex_own(lock->trx));
/* quit for native mysql */
- if (!wsrep_on(trx->mysql_thd)) return;
+ if (!trx->is_wsrep()) return;
my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE);
my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
@@ -1856,7 +1856,7 @@ lock_rec_other_has_conflicting(
#ifdef WITH_WSREP
if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) {
- if (wsrep_on_trx(trx)) {
+ if (trx->is_wsrep()) {
trx_mutex_enter(lock->trx);
/* Below function will roll back either trx
or lock->trx depending on priority of the
@@ -2318,8 +2318,7 @@ lock_rec_create(
ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
- if (c_lock &&
- wsrep_on_trx(trx) &&
+ if (c_lock && trx->is_wsrep() &&
wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
@@ -5009,7 +5008,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock && wsrep_on_trx(trx)) {
+ if (c_lock && trx->is_wsrep()) {
if (wsrep_thd_is_wsrep(trx->mysql_thd)
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
UT_LIST_INSERT_AFTER(
@@ -5248,7 +5247,7 @@ lock_table_enqueue_waiting(
/* Enqueue the lock request that will wait to be granted */
#ifdef WITH_WSREP
- if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
+ if (trx->lock.was_chosen_as_deadlock_victim && trx->is_wsrep()) {
return(DB_DEADLOCK);
}
diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc
index fe43ef3cc73..70ade1191d7 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -255,8 +255,7 @@ wsrep_is_BF_lock_timeout(
const trx_t* trx,
bool locked = true)
{
- if (wsrep_on_trx(trx)
- && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
fprintf(stderr, "WSREP: BF lock wait long for trx " TRX_ID_FMT "\n", trx->id);
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
@@ -447,7 +446,7 @@ lock_wait_suspend_thread(
if (lock_wait_timeout < 100000000
&& wait_time > (double) lock_wait_timeout) {
#ifdef WITH_WSREP
- if (!wsrep_on_trx(trx) ||
+ if (!trx->is_wsrep() ||
(!wsrep_is_BF_lock_timeout(trx) &&
trx->error_state != DB_DEADLOCK)) {
#endif /* WITH_WSREP */
diff --git a/storage/xtradb/mtr/mtr0mtr.cc b/storage/xtradb/mtr/mtr0mtr.cc
index 77af6e9eb60..ce1002a00f0 100644
--- a/storage/xtradb/mtr/mtr0mtr.cc
+++ b/storage/xtradb/mtr/mtr0mtr.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -88,6 +89,15 @@ mtr_memo_slot_release_func(
case MTR_MEMO_X_LOCK:
rw_lock_x_unlock((prio_rw_lock_t*) object);
break;
+ case MTR_MEMO_SPACE_X_LOCK:
+ {
+ fil_space_t* space = reinterpret_cast<fil_space_t*>(
+ static_cast<char*>(object)
+ - my_offsetof(fil_space_t, latch));
+ space->committed_size = space->size;
+ rw_lock_x_unlock(&space->latch);
+ }
+ break;
#ifdef UNIV_DEBUG
default:
ut_ad(slot->type == MTR_MEMO_MODIFY);
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 1e0f28d393f..66af4a39f7c 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -2716,6 +2716,7 @@ os_file_set_size(
errno = err;
return false;
case EINVAL:
+ case EOPNOTSUPP:
/* fall back to the code below */
break;
}
diff --git a/storage/xtradb/page/page0cur.cc b/storage/xtradb/page/page0cur.cc
index e9ac4b4bb04..94e861ab554 100644
--- a/storage/xtradb/page/page0cur.cc
+++ b/storage/xtradb/page/page0cur.cc
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -941,6 +942,52 @@ page_cur_parse_insert_rec(
return(ptr + end_seg_len);
}
+/************************************************************//**
+Allocates a block of memory from the heap of an index page.
+@return pointer to start of allocated buffer, or NULL if allocation fails */
+static
+byte*
+page_mem_alloc_heap(
+/*================*/
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
+ space available for inserting the record,
+ or NULL */
+ ulint need, /*!< in: total number of bytes needed */
+ ulint* heap_no)/*!< out: this contains the heap number
+ of the allocated record
+ if allocation succeeds */
+{
+ byte* block;
+ ulint avl_space;
+
+ ut_ad(page && heap_no);
+
+ avl_space = page_get_max_insert_size(page, 1);
+
+ if (avl_space >= need) {
+ const ulint h = page_dir_get_n_heap(page);
+ if (UNIV_UNLIKELY(h >= 8191)) {
+ /* At the minimum record size of 5+2 bytes,
+ we can only reach this condition when using
+ innodb_page_size=64k. */
+ ut_ad(srv_page_size == 65536);
+ return(NULL);
+ }
+ *heap_no = h;
+
+ block = page_header_get_ptr(page, PAGE_HEAP_TOP);
+
+ page_header_set_ptr(page, page_zip, PAGE_HEAP_TOP,
+ block + need);
+ page_dir_set_n_heap(page, page_zip, 1 + *heap_no);
+
+ return(block);
+ }
+
+ return(NULL);
+}
+
/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
diff --git a/storage/xtradb/page/page0page.cc b/storage/xtradb/page/page0page.cc
index 16587f872ef..ee31c9dbd87 100644
--- a/storage/xtradb/page/page0page.cc
+++ b/storage/xtradb/page/page0page.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2018, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -240,44 +240,6 @@ page_set_max_trx_id(
}
}
-/************************************************************//**
-Allocates a block of memory from the heap of an index page.
-@return pointer to start of allocated buffer, or NULL if allocation fails */
-UNIV_INTERN
-byte*
-page_mem_alloc_heap(
-/*================*/
- page_t* page, /*!< in/out: index page */
- page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
- space available for inserting the record,
- or NULL */
- ulint need, /*!< in: total number of bytes needed */
- ulint* heap_no)/*!< out: this contains the heap number
- of the allocated record
- if allocation succeeds */
-{
- byte* block;
- ulint avl_space;
-
- ut_ad(page && heap_no);
-
- avl_space = page_get_max_insert_size(page, 1);
-
- if (avl_space >= need) {
- block = page_header_get_ptr(page, PAGE_HEAP_TOP);
-
- page_header_set_ptr(page, page_zip, PAGE_HEAP_TOP,
- block + need);
- *heap_no = page_dir_get_n_heap(page);
-
- page_dir_set_n_heap(page, page_zip, 1 + *heap_no);
-
- return(block);
- }
-
- return(NULL);
-}
-
#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Writes a log record of page creation. */
diff --git a/storage/xtradb/page/page0zip.cc b/storage/xtradb/page/page0zip.cc
index 0c7f9b6feff..d85594c5ce3 100644
--- a/storage/xtradb/page/page0zip.cc
+++ b/storage/xtradb/page/page0zip.cc
@@ -4927,35 +4927,28 @@ page_zip_verify_checksum(
ib_uint32_t crc32 = 0 /* silence bogus warning */;
ib_uint32_t innodb = 0 /* silence bogus warning */;
- stored = static_cast<ib_uint32_t>(mach_read_from_4(
- static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+ const srv_checksum_algorithm_t curr_algo =
+ static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-#if FIL_PAGE_LSN % 8
-#error "FIL_PAGE_LSN must be 64 bit aligned"
-#endif
+ if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
+ return true;
+ }
- /* Check if page is empty */
- if (stored == 0
- && *reinterpret_cast<const ib_uint64_t*>(static_cast<const char*>(
- data)
- + FIL_PAGE_LSN) == 0) {
- /* make sure that the page is really empty */
- for (ulint i = 0; i < size; i++) {
- if (*((const char*) data + i) != 0) {
- return(FALSE);
- }
+ bool all_zeroes = true;
+ for (size_t i = 0; i < size; i++) {
+ if (static_cast<const byte*>(data)[i] != 0) {
+ all_zeroes = false;
+ break;
}
- /* Empty page */
- return(TRUE);
}
- const srv_checksum_algorithm_t curr_algo =
- static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-
- if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
- return(TRUE);
+ if (all_zeroes) {
+ return true;
}
+ stored = static_cast<ib_uint32_t>(mach_read_from_4(
+ static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+
calc = static_cast<ib_uint32_t>(page_zip_calc_checksum(
data, size, curr_algo));
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index 5a3a86ae02c..f3375f838ba 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2018, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -561,14 +561,6 @@ protected:
/** Space id of the file being iterated over. */
ulint m_space;
- /** Minimum page number for which the free list has not been
- initialized: the pages >= this limit are, by definition, free;
- note that in a single-table tablespace where size < 64 pages,
- this number is 64, i.e., we have initialized the space about
- the first extent, but have not physically allocted those pages
- to the file. @see FSP_LIMIT. */
- ulint m_free_limit;
-
/** Current size of the space in pages */
ulint m_size;
@@ -647,7 +639,6 @@ AbstractCallback::init(
ut_a(m_space == ULINT_UNDEFINED);
m_size = mach_read_from_4(page + FSP_SIZE);
- m_free_limit = mach_read_from_4(page + FSP_FREE_LIMIT);
m_space = mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID);
return set_current_xdes(0, page);
@@ -1353,8 +1344,8 @@ uncompressed:
return(DB_ERROR);
} else if (m_table->n_cols != m_n_cols) {
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
- "Number of columns don't match, table has %u"
- " columns but the tablespace meta-data file has "
+ "Number of columns don't match, table has %u "
+ "columns but the tablespace meta-data file has "
ULINTPF " columns",
m_table->n_cols, m_n_cols);
@@ -1924,6 +1915,23 @@ PageConverter::update_index_page(
return(DB_SUCCESS);
}
+ if (m_index && block->page.offset == m_index->m_page_no) {
+ byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE
+ + page;
+ mach_write_to_4(b, block->page.space);
+
+ memcpy(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP + FSEG_HDR_SPACE
+ + page, b, 4);
+ if (UNIV_LIKELY_NULL(block->page.zip.data)) {
+ memcpy(&block->page.zip.data[FIL_PAGE_DATA
+ + PAGE_BTR_SEG_TOP
+ + FSEG_HDR_SPACE], b, 4);
+ memcpy(&block->page.zip.data[FIL_PAGE_DATA
+ + PAGE_BTR_SEG_LEAF
+ + FSEG_HDR_SPACE], b, 4);
+ }
+ }
+
#ifdef UNIV_ZIP_DEBUG
ut_a(!is_compressed_table()
|| page_zip_validate(m_page_zip_ptr, page, m_index->m_srv_index));
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index 50da7fb40ad..c78f5bc8dc4 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -516,7 +516,7 @@ row_ins_cascade_calc_update_vec(
n_fields_updated = 0;
- *fts_col_affected = FALSE;
+ *fts_col_affected = foreign->affects_fulltext();
if (table->fts) {
doc_id_pos = dict_table_get_nth_col_pos(
@@ -637,16 +637,6 @@ row_ins_cascade_calc_update_vec(
padded_data, min_size);
}
- /* Check whether the current column has
- FTS index on it */
- if (table->fts
- && dict_table_is_fts_column(
- table->fts->indexes,
- dict_col_get_no(col))
- != ULINT_UNDEFINED) {
- *fts_col_affected = TRUE;
- }
-
/* If Doc ID is updated, check whether the
Doc ID is valid */
if (table->fts
@@ -983,7 +973,6 @@ row_ins_foreign_check_on_constraint(
upd_t* update;
ulint n_to_update;
dberr_t err;
- ulint i;
trx_t* trx;
mem_heap_t* tmp_heap = NULL;
doc_id_t doc_id = FTS_NULL_DOC_ID;
@@ -1197,7 +1186,7 @@ row_ins_foreign_check_on_constraint(
UNIV_MEM_INVALID(update->fields,
update->n_fields * sizeof *update->fields);
- for (i = 0; i < foreign->n_fields; i++) {
+ for (ulint i = 0; i < foreign->n_fields; i++) {
upd_field_t* ufield = &update->fields[i];
ufield->field_no = dict_table_get_nth_col_pos(
@@ -1206,32 +1195,14 @@ row_ins_foreign_check_on_constraint(
ufield->orig_len = 0;
ufield->exp = NULL;
dfield_set_null(&ufield->new_val);
-
- if (table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i))
- != ULINT_UNDEFINED) {
- fts_col_affacted = TRUE;
- }
}
- if (fts_col_affacted) {
- fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
- }
- } else if (table->fts && cascade->is_delete) {
- /* DICT_FOREIGN_ON_DELETE_CASCADE case */
- for (i = 0; i < foreign->n_fields; i++) {
- if (table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i))
- != ULINT_UNDEFINED) {
- fts_col_affacted = TRUE;
- }
- }
-
- if (fts_col_affacted) {
+ if (foreign->affects_fulltext()) {
fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
+ } else if (table->fts && cascade->is_delete
+ && foreign->affects_fulltext()) {
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
if (!node->is_delete
@@ -1651,7 +1622,7 @@ run_again:
if (check_ref) {
err = DB_SUCCESS;
#ifdef WITH_WSREP
- if (!wsrep_on(trx->mysql_thd)) {
+ if (!trx->is_wsrep()) {
goto end_scan;
}
enum wsrep_key_type key_type;
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index b5bd626db63..587fcda27b1 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -3209,6 +3209,16 @@ row_discard_tablespace_for_mysql(
err = DB_ERROR;
} else {
+ bool fts_exist = (dict_table_has_fts_index(table)
+ || DICT_TF2_FLAG_IS_SET(
+ table, DICT_TF2_FTS_HAS_DOC_ID));
+
+ if (fts_exist) {
+ row_mysql_unlock_data_dictionary(trx);
+ fts_optimize_remove_table(table);
+ row_mysql_lock_data_dictionary(trx);
+ }
+
/* Do foreign key constraint checks. */
err = row_discard_tablespace_foreign_key_checks(trx, table);
@@ -3216,6 +3226,11 @@ row_discard_tablespace_for_mysql(
if (err == DB_SUCCESS) {
err = row_discard_tablespace(trx, table);
}
+
+ if (fts_exist && err != DB_SUCCESS) {
+ fts_optimize_add_table(table);
+ }
+
}
return(row_discard_tablespace_end(trx, table, err));
diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc
index c9c7f1dd9c1..a968fc83243 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2015, 2018, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -3740,9 +3740,16 @@ bool row_search_with_covering_prefix(
return false;
}
+ /* We can avoid a clustered index lookup if
+ all of the following hold:
+ (1) all columns are in the secondary index
+ (2) all values for columns that are prefix-only
+ indexes are shorter than the prefix size
+ This optimization can avoid many IOs for certain schemas. */
for (ulint i = 0; i < prebuilt->n_template; i++) {
mysql_row_templ_t* templ = prebuilt->mysql_template + i;
ulint j = templ->rec_prefix_field_no;
+ ut_ad(!templ->mbminlen == !templ->mbmaxlen);
/** Condition (1) : is the field in the index. */
if (j == ULINT_UNDEFINED) {
@@ -3752,34 +3759,29 @@ bool row_search_with_covering_prefix(
/** Condition (2): If this is a prefix index then
row's value size shorter than prefix length. */
- if (!templ->rec_field_is_prefix) {
+ if (!templ->rec_field_is_prefix
+ || rec_offs_nth_sql_null(offsets, j)) {
continue;
}
- ulint rec_size = rec_offs_nth_size(offsets, j);
const dict_field_t* field = dict_index_get_nth_field(index, j);
- ulint max_chars = field->prefix_len / templ->mbmaxlen;
- ut_a(field->prefix_len > 0);
-
- if (rec_size < max_chars) {
- /* Record in bytes shorter than the index
- prefix length in char. */
+ if (!field->prefix_len) {
continue;
}
- if (rec_size * templ->mbminlen >= field->prefix_len) {
+ const ulint rec_size = rec_offs_nth_size(offsets, j);
+
+ if (rec_size >= field->prefix_len) {
/* Shortest representation string by the
byte length of the record is longer than the
maximum possible index prefix. */
return false;
}
-
- size_t num_chars = rec_field_len_in_chars(
- field->col, j, rec, offsets);
-
- if (num_chars >= max_chars) {
+ if (templ->mbminlen != templ->mbmaxlen
+ && rec_field_len_in_chars(field->col, j, rec, offsets)
+ >= field->prefix_len / templ->mbmaxlen) {
/* No of chars to store the record exceeds
the index prefix character length. */
return false;
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 6324c1d71a1..a5e5988113d 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2019, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1814,7 +1814,7 @@ row_upd_store_row(
inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
{
- if (!wsrep_on_trx(trx)) {
+ if (!trx->is_wsrep()) {
return false;
}
return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
diff --git a/storage/xtradb/srv/srv0conc.cc b/storage/xtradb/srv/srv0conc.cc
index 1a198fceaec..1a2a6e0342f 100644
--- a/storage/xtradb/srv/srv0conc.cc
+++ b/storage/xtradb/srv/srv0conc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -218,8 +218,7 @@ srv_conc_enter_innodb_with_atomics(
for (;;) {
ulint sleep_in_us;
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_trx_is_aborting(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_trx_is_aborting(trx->mysql_thd)) {
if (wsrep_debug)
fprintf(stderr,
"srv_conc_enter due to MUST_ABORT");
@@ -430,8 +429,7 @@ retry:
return;
}
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_thd_is_brute_force(trx->mysql_thd)) {
srv_conc_force_enter_innodb(trx);
return;
}
@@ -514,8 +512,7 @@ retry:
srv_conc.n_waiting++;
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_trx_is_aborting(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_trx_is_aborting(trx->mysql_thd)) {
os_fast_mutex_unlock(&srv_conc_mutex);
if (wsrep_debug)
fprintf(stderr, "srv_conc_enter due to MUST_ABORT");
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 8e534714ce8..91234a0cca8 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -3,7 +3,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -673,7 +673,6 @@ current_time % 60 == 0 and no tasks will be performed when
current_time % 5 != 0. */
# define SRV_MASTER_CHECKPOINT_INTERVAL (7)
-# define SRV_MASTER_PURGE_INTERVAL (10)
#ifdef MEM_PERIODIC_CHECK
# define SRV_MASTER_MEM_VALIDATE_INTERVAL (13)
#endif /* MEM_PERIODIC_CHECK */
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index 6ea430699d4..0ad755c1e3a 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -3,7 +3,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1240,6 +1240,10 @@ check_first_page:
}
}
+ if (fil_space_t* s = fil_space_get(0)) {
+ s->committed_size = s->size;
+ }
+
return(DB_SUCCESS);
}
@@ -1408,6 +1412,10 @@ srv_undo_tablespace_open(
if (fil_node_create(name, (ulint) n_pages, space, FALSE)) {
err = DB_SUCCESS;
}
+
+ if (fil_space_t* s = fil_space_get(space)) {
+ s->committed_size = n_pages;
+ }
}
return(err);
diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc
index c085e8ebcf5..4de46089790 100644
--- a/storage/xtradb/sync/sync0arr.cc
+++ b/storage/xtradb/sync/sync0arr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1164,7 +1164,7 @@ sync_array_print_long_waits(
sync_array_exit(arr);
}
- if (noticed) {
+ if (noticed && srv_monitor_event) {
ibool old_val;
fprintf(stderr,
diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc
index 97f08d1fa0c..7624d92a831 100644
--- a/storage/xtradb/trx/trx0roll.cc
+++ b/storage/xtradb/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -379,8 +379,7 @@ trx_rollback_to_savepoint_for_mysql_low(
trx->op_info = "";
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- trx->lock.was_chosen_as_deadlock_victim) {
+ if (trx->is_wsrep()) {
trx->lock.was_chosen_as_deadlock_victim = FALSE;
}
#endif
@@ -1083,12 +1082,6 @@ trx_roll_try_truncate(
if (trx->update_undo) {
trx_undo_truncate_end(trx, trx->update_undo, limit);
}
-
-#ifdef WITH_WSREP_OUT
- if (wsrep_on(trx->mysql_thd)) {
- trx->lock.was_chosen_as_deadlock_victim = FALSE;
- }
-#endif /* WITH_WSREP */
}
/***********************************************************************//**
diff --git a/storage/xtradb/trx/trx0rseg.cc b/storage/xtradb/trx/trx0rseg.cc
index 1d0eb6d29fd..8ce6fb6729f 100644
--- a/storage/xtradb/trx/trx0rseg.cc
+++ b/storage/xtradb/trx/trx0rseg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -65,7 +65,7 @@ trx_rseg_header_create(
ut_ad(mtr);
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
/* Allocate a new file segment for the rollback segment */
block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
@@ -312,7 +312,7 @@ trx_rseg_create(ulint space)
/* To obey the latching order, acquire the file space
x-latch before the trx_sys->mutex. */
- mtr_x_lock(fil_space_get_latch(space, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, NULL), &mtr);
slot_no = trx_sysf_rseg_find_free(&mtr);
diff --git a/storage/xtradb/trx/trx0sys.cc b/storage/xtradb/trx/trx0sys.cc
index fcdce291cf0..94a79a1f944 100644
--- a/storage/xtradb/trx/trx0sys.cc
+++ b/storage/xtradb/trx/trx0sys.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -554,7 +554,7 @@ trx_sysf_create(
then enter the kernel: we must do it in this order to conform
to the latching order rules. */
- mtr_x_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), mtr);
+ mtr_x_space_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), mtr);
/* Create the trx sys file block in a new allocated file segment */
block = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc
index a65132cf572..bfbd15d62a2 100644
--- a/storage/xtradb/trx/trx0trx.cc
+++ b/storage/xtradb/trx/trx0trx.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1555,11 +1555,7 @@ trx_commit_in_memory(
ut_ad(!trx->in_ro_trx_list);
ut_ad(!trx->in_rw_trx_list);
-#ifdef WITH_WSREP
- if (trx->mysql_thd && wsrep_on(trx->mysql_thd)) {
- trx->lock.was_chosen_as_deadlock_victim = FALSE;
- }
-#endif
+ trx->lock.was_chosen_as_deadlock_victim = FALSE;
trx->dict_operation = TRX_DICT_OP_NONE;
trx->error_state = DB_SUCCESS;