mirror of
https://github.com/MariaDB/server.git
synced 2025-01-23 15:24:16 +01:00
e76b873f24
------------------------------------------------------------------------ r4670 | vasil | 2009-04-07 09:35:23 +0300 (Tue, 07 Apr 2009) | 11 lines branches/zip: Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for indexes of InnoDB table by replacing the pseudo random number generator with a better one (LCG). This also fixes Mantis Issue#212. Approved by: Heikki (rb://110) ------------------------------------------------------------------------ r4671 | vasil | 2009-04-07 09:37:31 +0300 (Tue, 07 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for r4670. ------------------------------------------------------------------------ r4673 | marko | 2009-04-07 15:45:28 +0300 (Tue, 07 Apr 2009) | 4 lines branches/zip: Allow in-place updates of UTF-8 CHAR columns from or to NULL in ROW_FORMAT=REDUNDANT. (Bug #44032) rb://107 approved by Heikki Tuuri. ------------------------------------------------------------------------ r4677 | marko | 2009-04-07 16:19:31 +0300 (Tue, 07 Apr 2009) | 1 line branches/zip: Adjust r4673 as in the merge to branches/6.0 -r4676. ------------------------------------------------------------------------ r4678 | inaam | 2009-04-07 18:45:37 +0300 (Tue, 07 Apr 2009) | 12 lines branches/zip Enable atomics on solaris (using the libc functions as defined in atomic.h) if GCC atomic builtins are not present. There still remains some work to be done (by Vasil?). This patch makes changes to plug.in to check pthread_t size and presence of atomic functions when running on solaris. The same has to become a part of the generated Makefile.in when we bake our source. Reviewed by: Heikki rb://106 ------------------------------------------------------------------------ r4687 | vasil | 2009-04-08 13:08:59 +0300 (Wed, 08 Apr 2009) | 4 lines branches/zip: Whitespace fixup in the ChangeLog ------------------------------------------------------------------------ r4688 | vasil | 2009-04-08 13:11:15 +0300 (Wed, 08 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for r4678. ------------------------------------------------------------------------ r4689 | marko | 2009-04-08 14:24:49 +0300 (Wed, 08 Apr 2009) | 5 lines branches/zip: Hide unnecessarily visible globals. dict_ind_redundant, dict_ind_compact: Declare these UNIV_INTERN. innodb_hton_ptr: Declare static. We do not attempt to access the built-in InnoDB any more. trx_roll_savepoints_free(): Declare UNIV_INTERN. ------------------------------------------------------------------------ r4700 | calvin | 2009-04-11 00:37:10 +0300 (Sat, 11 Apr 2009) | 9 lines branches/zip: Rewrite CMakeLists.txt CMakeLists.txt is completely rewritten: - To replace the one written by mysql - Print out some useful information, such as system name, directory, generator used, win64, Microsoft compiler, etc. - Remove one workaround for mysqld.lib location. User does not need to specify a build type ------------------------------------------------------------------------ r4702 | calvin | 2009-04-13 18:16:44 +0300 (Mon, 13 Apr 2009) | 3 lines branches/zip: delete the original CMakeLists.txt A new version will be committed, suggested by Ken. ------------------------------------------------------------------------ r4703 | calvin | 2009-04-13 18:20:45 +0300 (Mon, 13 Apr 2009) | 9 lines branches/zip: new CMakeLists.txt CMakeLists.txt is completely rewritten with enhancements: - Print out useful information, such as system name, directory, generator used, win64, Microsoft compiler, etc. - Remove one workaround for mysqld.lib location. User does not need to specify a build type when invoking MSVC generator. ------------------------------------------------------------------------ r4706 | vasil | 2009-04-14 14:32:11 +0300 (Tue, 14 Apr 2009) | 5 lines branches/zip: When using the random function, first take the modulus by the number of pages and then typecast to ulint. ------------------------------------------------------------------------ r4707 | calvin | 2009-04-14 17:47:31 +0300 (Tue, 14 Apr 2009) | 13 lines branches/zip: remove statically linked libraries from mysql To make zlib and strings dynamically linked; mysqld will export additional functions required by InnoDB. Since the symbols will be resolved dynamically during runtime, wdl_load_mapfile() is no longer able to make any function calls to ones in mysqld. As the result, strtoull() (from strings.lib) is replaced with _strtoui64(). rb://111 Approved by: Marko ------------------------------------------------------------------------ r4712 | vasil | 2009-04-15 12:26:32 +0300 (Wed, 15 Apr 2009) | 157 lines branches/zip: Merge revisions 4481:4710 from branches/5.1: (resolving conflict in r4574, r4575 and skipping r4699 and r4705 because analogous changes to r4699 and r4705 were already made to branches/zip) ------------------------------------------------------------------------ r4573 | vasil | 2009-03-30 14:17:13 +0300 (Mon, 30 Mar 2009) | 4 lines Changed paths: M /branches/5.1/mysql-test/innodb.test branches/5.1: Fix email address from dev@innodb.com to innodb_dev_ww@oracle.com ------------------------------------------------------------------------ r4574 | vasil | 2009-03-30 14:27:08 +0300 (Mon, 30 Mar 2009) | 38 lines Changed paths: M /branches/5.1/Makefile.am M /branches/5.1/mysql-test/innodb.test branches/5.1: Restore the state of INNODB_THREAD_CONCURRENCY to silence this warning: TEST RESULT TIME (ms) ------------------------------------------------------------ worker[1] Using MTR_BUILD_THREAD 250, with reserved ports 12500..12509 main.innodb [ pass ] 8803 MTR's internal check of the test case 'main.innodb' failed. This means that the test case does not preserve the state that existed before the test case was executed. Most likely the test case did not do a proper clean-up. This is the diff of the states of the servers before and after the test case was executed: mysqltest: Logging to '/tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.log'. mysqltest: Results saved in '/tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.result'. mysqltest: Connecting to server localhost:12500 (socket /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/mysqld.1.sock) as 'root', connection 'default', attempt 0 ... mysqltest: ... Connected. mysqltest: Start processing test commands from './include/check-testcase.test' ... mysqltest: ... Done processing test commands. --- /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.result 2009-03-30 14:12:31.000000000 +0300 +++ /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.reject 2009-03-30 14:12:41.000000000 +0300 @@ -99,7 +99,7 @@ INNODB_SUPPORT_XA ON INNODB_SYNC_SPIN_LOOPS 20 INNODB_TABLE_LOCKS ON -INNODB_THREAD_CONCURRENCY 8 +INNODB_THREAD_CONCURRENCY 16 INNODB_THREAD_SLEEP_DELAY 10000 INSERT_ID 0 INTERACTIVE_TIMEOUT 28800 mysqltest: Result content mismatch not ok ------------------------------------------------------------------------ r4575 | vasil | 2009-03-30 15:55:31 +0300 (Mon, 30 Mar 2009) | 8 lines Changed paths: M /branches/5.1/mysql-test/innodb.result M /branches/5.1/mysql-test/innodb.test branches/5.1: Fix Bug#43309 Test main.innodb can't be run twice Make the innodb mysql-test more flexible by inspecting how much a variable of interest has changed since the start of the test. Do not assume the variables have zero values at the start of the test. ------------------------------------------------------------------------ r4576 | vasil | 2009-03-30 16:25:10 +0300 (Mon, 30 Mar 2009) | 4 lines Changed paths: M /branches/5.1/Makefile.am branches/5.1: Revert a change to Makefile.am that I committed accidentally in c4574. ------------------------------------------------------------------------ r4659 | vasil | 2009-04-06 15:34:51 +0300 (Mon, 06 Apr 2009) | 6 lines Changed paths: M /branches/5.1/mysql-test/innodb.test branches/5.1: Followup to r4575 and the fix of Bug#43309 Test main.innodb can't be run twice: Add an explanatory comment, as suggested by Patrick Crews in the bug report. ------------------------------------------------------------------------ r4699 | vasil | 2009-04-09 14:01:52 +0300 (Thu, 09 Apr 2009) | 15 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/include/srv0srv.h M /branches/5.1/page/page0cur.c M /branches/5.1/srv/srv0srv.c branches/5.1: Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for indexes of InnoDB table by replacing the PRNG that is used to pick random pages with a better one. This is based on r4670 but also adds a new configuration option and enables the fix only if this option is changed. Please skip the present revision when merging. Approved by: Heikki (via email) ------------------------------------------------------------------------ r4705 | vasil | 2009-04-14 14:30:13 +0300 (Tue, 14 Apr 2009) | 5 lines Changed paths: M /branches/5.1/page/page0cur.c branches/5.1: When using the random function, first take the modulus by the number of pages and then typecast to ulint. ------------------------------------------------------------------------ r4710 | vasil | 2009-04-15 11:55:18 +0300 (Wed, 15 Apr 2009) | 25 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL (looks like this is against 5.0 but they later merged it to 5.1): ------------------------------------------------------------ revno: 1810.3846.1 committer: Alexey Botchkov <holyfoot@mysql.com> branch nick: 31435 timestamp: Tue 2008-11-11 14:42:32 +0400 message: Bug#31435 ha_innodb.cc:3983: ulint convert_search_mode_to_innobase(ha_rkey_function): Asse I think we don't need to issue an error statement in the convert_search_mode_to_innobase(). Returning the PAGE_CUR_UNSUPP value is enough as allows to handle this case depending on the requirements. per-file comments: sql/ha_innodb.cc Bug#31435 ha_innodb.cc:3983: ulint convert_search_mode_to_innobase(ha_rkey_function): Asse no error issued in convert_search_mode_to_innobase. ha_innobase::records_in_range() returns HA_POS_ERROR if search mode isn't supported. modified: sql/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4713 | vasil | 2009-04-15 12:36:16 +0300 (Wed, 15 Apr 2009) | 4 lines branches/zip: Add missing ChangeLog entries ------------------------------------------------------------------------ r4714 | vasil | 2009-04-15 12:36:57 +0300 (Wed, 15 Apr 2009) | 4 lines branches/zip: Fix typo in the ChangeLog ------------------------------------------------------------------------ r4715 | vasil | 2009-04-15 12:39:04 +0300 (Wed, 15 Apr 2009) | 4 lines branches/zip: Whitespace cleanup in ChangeLog ------------------------------------------------------------------------ r4716 | vasil | 2009-04-15 21:36:06 +0300 (Wed, 15 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for r4543. ------------------------------------------------------------------------ r4717 | calvin | 2009-04-16 01:22:35 +0300 (Thu, 16 Apr 2009) | 18 lines branches/zip: Use the Windows Interlocked functions for atomic memory access Mapping the atomic operations to Windows Interlocked functions: os_compare_and_swap_* to InterlockedCompareExchange(64) os_atomic_increment_* to InterlockedExchangeAdd(64) os_atomic_test_and_set_byte to InterlockedExchange In this patch, the legacy code under UNIV_CAN_USE_X86_ASSEMBLER is removed all together, and add HAVE_WINDOWS_ATOMICS and INNODB_RW_LOCKS_USE_ATOMICS to CMakeLists.txt This is to address mantis issue#194. rb://113 Approved by: Marko ------------------------------------------------------------------------ r4720 | vasil | 2009-04-16 09:44:48 +0300 (Thu, 16 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for r4717. ------------------------------------------------------------------------ r4721 | marko | 2009-04-16 10:32:09 +0300 (Thu, 16 Apr 2009) | 2 lines branches/zip: row_scan_and_check_index(): Initialize prebuilt->index_usable. This should have been done in r4631. Spotted by Michael. ------------------------------------------------------------------------ r4728 | marko | 2009-04-16 16:02:27 +0300 (Thu, 16 Apr 2009) | 3 lines branches/zip: univ.i: Define REFMAN as the base URL of the MySQL Reference Manual and use it in every string. This fixes Issue #221. ------------------------------------------------------------------------ r4733 | calvin | 2009-04-17 08:13:20 +0300 (Fri, 17 Apr 2009) | 6 lines branches/zip: minor changes to CMakeLists.txt All are non-functional changes: - should check for long (not int), spotted by Sunny - comment out the project definition, avoiding to generate another .sln file. ------------------------------------------------------------------------ r4748 | vasil | 2009-04-18 00:50:09 +0300 (Sat, 18 Apr 2009) | 118 lines branches/zip: Merge revisions 4710:4746 from branches/5.1: ------------------------------------------------------------------------ r4746 | vasil | 2009-04-18 00:32:08 +0300 (Sat, 18 Apr 2009) | 110 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/include/pars0pars.h branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2728.10.2 committer: Ignacio Galarza <iggy@mysql.com> branch nick: mysql-5.1-bugteam-bug29125 timestamp: Fri 2009-02-13 11:41:47 -0500 message: Bug#29125 Windows Server X64: so many compiler warnings - Remove bothersome warning messages. This change focuses on the warnings that are covered by the ignore file: support-files/compiler_warnings.supp. - Strings are guaranteed to be max uint in length modified: client/mysql_upgrade.c client/mysqladmin.cc client/mysqlbinlog.cc client/mysqlcheck.c client/mysqldump.c client/mysqlslap.c client/mysqltest.cc client/sql_string.cc extra/comp_err.c extra/yassl/src/buffer.cpp extra/yassl/taocrypt/include/block.hpp extra/yassl/taocrypt/src/algebra.cpp extra/yassl/taocrypt/src/asn.cpp include/config-win.h libmysql/libmysql.c mysys/array.c mysys/base64.c mysys/charset.c mysys/checksum.c mysys/default.c mysys/default_modify.c mysys/hash.c mysys/mf_keycache.c mysys/mf_tempdir.c mysys/my_append.c mysys/my_compress.c mysys/my_conio.c mysys/my_copy.c mysys/my_getwd.c mysys/my_pread.c mysys/my_quick.c mysys/my_read.c mysys/safemalloc.c mysys/string.c server-tools/instance-manager/buffer.cc server-tools/instance-manager/instance.cc server-tools/instance-manager/options.cc server-tools/instance-manager/parse.h sql-common/client.c sql-common/my_user.c sql/event_data_objects.cc sql/event_parse_data.cc sql/events.cc sql/gen_lex_hash.cc sql/item.h sql/item_func.cc sql/item_strfunc.cc sql/item_timefunc.cc sql/lock.cc sql/log_event.cc sql/log_event.h sql/log_event_old.cc sql/net_serv.cc sql/sp_head.h sql/spatial.h sql/sql_class.h sql/sql_connect.cc sql/sql_crypt.cc sql/sql_error.cc sql/sql_insert.cc sql/sql_lex.cc sql/sql_lex.h sql/sql_load.cc sql/sql_prepare.cc sql/sql_profile.cc sql/sql_repl.cc sql/sql_servers.cc sql/sql_string.cc sql/sql_table.cc sql/sql_trigger.cc sql/sql_udf.cc sql/sql_view.cc sql/udf_example.c sql/uniques.cc storage/archive/azio.c storage/archive/azlib.h storage/csv/ha_tina.cc storage/csv/ha_tina.h storage/csv/transparent_file.h storage/federated/ha_federated.cc storage/federated/ha_federated.h storage/heap/hp_write.c storage/innobase/handler/ha_innodb.cc storage/innobase/include/pars0pars.h storage/myisam/ha_myisam.cc storage/myisam/mi_check.c storage/myisam/mi_packrec.c storage/myisam/mi_search.c storage/myisam/rt_index.c storage/myisammrg/ha_myisammrg.cc strings/ctype.c strings/my_vsnprintf.c tests/bug25714.c tests/mysql_client_test.c ------------------------------------------------------------------------ r4749 | vasil | 2009-04-18 00:58:08 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for t4748. ------------------------------------------------------------------------ r4751 | vasil | 2009-04-18 01:29:16 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Silence warning about unused variables. ------------------------------------------------------------------------ r4752 | vasil | 2009-04-18 01:30:37 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Include the needed header for memset(). ------------------------------------------------------------------------ r4753 | vasil | 2009-04-18 01:31:34 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Silence a compiler warning. ------------------------------------------------------------------------ r4756 | vasil | 2009-04-18 02:19:03 +0300 (Sat, 18 Apr 2009) | 5 lines branches/zip: Rename the aux config program and give it a more specific name because more are coming. ------------------------------------------------------------------------ r4757 | vasil | 2009-04-18 02:22:33 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Add comment and copyright notice to the aux config program. ------------------------------------------------------------------------ r4758 | vasil | 2009-04-18 02:40:47 +0300 (Sat, 18 Apr 2009) | 5 lines branches/zip: Add aux config programs to emulate the newly added checks in plug.in (from r4678). ------------------------------------------------------------------------ r4830 | marko | 2009-04-20 16:11:38 +0300 (Mon, 20 Apr 2009) | 6 lines branches/zip: Cosmetic fixes. row_unlock_for_mysql(): Add a const qualifier to read-only rec_t*. Use dict_index_is_clust(). CMakeLists.txt: svn propset svn:eol-style native. ------------------------------------------------------------------------ r4893 | marko | 2009-04-23 09:32:36 +0300 (Thu, 23 Apr 2009) | 11 lines branches/zip: Introduce the logical type names trx_id_t, roll_ptr_t, and undo_no_t. Each type is still defined as dulint. This is an initial step towards replacing dulint with a 64-bit data type. Because modern compilers have no trouble supporting 64-bit arithmetics even on 32-bit targets, the dulint struct is a relic that should go. The last remaining major use of dulint is dictionary IDs (table, index, and row ids). rb://114 approved by Sunny Bains ------------------------------------------------------------------------ r4894 | marko | 2009-04-23 10:21:07 +0300 (Thu, 23 Apr 2009) | 1 line branches/zip: ChangeLog: Document r4893. ------------------------------------------------------------------------ r4895 | marko | 2009-04-23 10:22:06 +0300 (Thu, 23 Apr 2009) | 1 line branches/zip: ChangeLog: Add the missing include/ to two files. ------------------------------------------------------------------------ r4896 | marko | 2009-04-23 10:37:40 +0300 (Thu, 23 Apr 2009) | 4 lines branches/zip: row_scan_and_check_index(): Improve the diagnostics, by reporting errors from row_search_for_mysql() in the error log. The errors will still be ignored by CHECK TABLE. This is somewhat related to Issue #211. ------------------------------------------------------------------------ r4897 | marko | 2009-04-23 10:40:34 +0300 (Thu, 23 Apr 2009) | 2 lines branches/zip: row_scan_and_check_index(): Check row_merge_is_index_usable() earlier, to make the logic clearer. ------------------------------------------------------------------------ r4898 | marko | 2009-04-23 15:15:07 +0300 (Thu, 23 Apr 2009) | 4 lines branches/zip: Correct a misleading comment. PAGE_MAX_TRX_ID will be updated in ibuf_insert_low() and updated from the insert buffer tree page to the secondary index tree page during the insert buffer merge. ------------------------------------------------------------------------ r4915 | marko | 2009-04-27 13:40:20 +0300 (Mon, 27 Apr 2009) | 2 lines branches/zip: row_scan_and_check_index(): Add some comments on prebuilt->index_usable, as suggested by Michael. ------------------------------------------------------------------------ r4921 | marko | 2009-04-29 11:51:25 +0300 (Wed, 29 Apr 2009) | 2 lines branches/zip: btr_cur_optimistic_insert(): Remove a redundant condition. The insert buffer tree is a clustered index. ------------------------------------------------------------------------ r4922 | marko | 2009-04-29 23:23:27 +0300 (Wed, 29 Apr 2009) | 22 lines branches/zip: Distinguish temporary tables in MLOG_FILE_CREATE. This addresses Mantis Issue #23 in InnoDB Hot Backup and some of MySQL Bug #41609. In MLOG_FILE_CREATE, we need to distinguish temporary tables, so that InnoDB Hot Backup can work correctly. It turns out that we can do this easily, by using a bit of the previously unused parameter for page number. (The page number parameter of MLOG_FILE_CREATE has been written as 0 ever since MySQL 4.1, which introduced MLOG_FILE_CREATE.) MLOG_FILE_FLAG_TEMP: A flag for indicating a temporary table in the page number parameter of MLOG_FILE_ operations. fil_op_write_log(): Add the parameter log_flags. fil_op_log_parse_or_replay(): Add the parameter log_flags. Do not replay MLOG_FILE_CREATE when MLOG_FILE_FLAG_TEMP is set in log_flags. This only affects ibbackup --apply-log. InnoDB itself never replays file operations. rb://117 approved by Heikki Tuuri ------------------------------------------------------------------------ r4977 | marko | 2009-05-13 15:49:38 +0300 (Wed, 13 May 2009) | 12 lines branches/zip: Merge revisions 4746:4976 from branches/5.1: ------------------------------------------------------------------------ r4976 | marko | 2009-05-13 15:44:54 +0300 (Wed, 13 May 2009) | 6 lines branches/5.1: Display DB_ROLL_PTR in the COLUMNS section of the innodb_table_monitor output. It was accidentally omitted due to an off-by-one loop condition. (Bug #44320) rb://116 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4978 | vasil | 2009-05-13 16:21:55 +0300 (Wed, 13 May 2009) | 4 lines branches/zip: Add ChangeLog entry for r4977. ------------------------------------------------------------------------ r4995 | marko | 2009-05-14 15:31:43 +0300 (Thu, 14 May 2009) | 24 lines branches/zip: Merge revisions 4976:4994 from branches/5.1: ------------------------------------------------------------------------ r4994 | marko | 2009-05-14 15:04:55 +0300 (Thu, 14 May 2009) | 18 lines branches/5.1: Prevent a race condition in innobase_commit() by ensuring that innodb_commit_concurrency>0 remains constant at run time. (Bug #42101) srv_commit_concurrency: Make this a static variable in ha_innodb.cc. innobase_commit_concurrency_validate(): Check that innodb_commit_concurrency is not changed from or to 0 at run time. This is needed, because innobase_commit() assumes that innodb_commit_concurrency>0 remains constant. Without this limitation, the checks for innodb_commit_concurrency>0 in innobase_commit() should be removed and that function would have to acquire and release commit_cond_m at least twice per invocation. Normally, innodb_commit_concurrency=0, and introducing the mutex operations would mean significant overhead. innodb_bug42101.test, innodb_bug42101-nonzero.test: Test cases. rb://123 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r5000 | vasil | 2009-05-14 20:13:41 +0300 (Thu, 14 May 2009) | 4 lines branches/zip: Add ChangeLog entry for r4994. ------------------------------------------------------------------------ r5026 | marko | 2009-05-18 16:29:51 +0300 (Mon, 18 May 2009) | 1 line branches/zip: buf_validate(): Add missing out: comment. ------------------------------------------------------------------------ r5027 | marko | 2009-05-18 16:36:10 +0300 (Mon, 18 May 2009) | 1 line branches/zip: Add some missing out: comments to buf0buf.h, buf0buf.c. ------------------------------------------------------------------------ r5028 | marko | 2009-05-18 16:40:07 +0300 (Mon, 18 May 2009) | 11 lines branches/zip: When executing an optimistic update by delete-and-insert, correctly estimate the free space on the compressed page by page_zip_available(..., create=TRUE). This was reported as Issue #231. btr_cur_update_alloc_zip(): Add the parameter ibool create and pass it to page_zip_available(). The parameter was previously passed as 0. btr_cur_optimistic_update(): Pass create=TRUE to btr_cur_update_alloc_zip(). rb://120 approved by Heikki Tuuri ------------------------------------------------------------------------ r5030 | marko | 2009-05-19 10:04:04 +0300 (Tue, 19 May 2009) | 2 lines branches/zip: os_thread_get_curr_id(), os_thread_get_curr(): Add missing out: comments. ------------------------------------------------------------------------ r5031 | marko | 2009-05-19 10:30:02 +0300 (Tue, 19 May 2009) | 1 line branches/zip: Add missing out: comments to nullary functions. ------------------------------------------------------------------------ r5033 | marko | 2009-05-19 11:00:51 +0300 (Tue, 19 May 2009) | 1 line branches/zip: Remove bogus out: comments of functions returning void. ------------------------------------------------------------------------ r5034 | marko | 2009-05-19 12:41:32 +0300 (Tue, 19 May 2009) | 1 line branches/zip: row_update_prebuilt_trx(): Correct bogus comment. ------------------------------------------------------------------------ r5035 | marko | 2009-05-19 13:04:58 +0300 (Tue, 19 May 2009) | 3 lines branches/zip: ut0auxconf_have_solaris_atomics.c: Get the function declarations from <atomic.h>. Call the functions with proper arguments. ------------------------------------------------------------------------ r5036 | marko | 2009-05-19 13:05:50 +0300 (Tue, 19 May 2009) | 1 line branches/zip: Add proper comments to some file page accessors. ------------------------------------------------------------------------ r5037 | marko | 2009-05-19 13:08:16 +0300 (Tue, 19 May 2009) | 1 line branches/zip: Fix a typo that was introduced in r5036. ------------------------------------------------------------------------ r5038 | marko | 2009-05-19 22:59:07 +0300 (Tue, 19 May 2009) | 30 lines branches/zip: Write PAGE_MAX_TRX_ID to the redo log. Otherwise, transactions that are started before the rollback of incomplete transactions has finished may have an inconsistent view of the secondary indexes. dict_index_is_sec_or_ibuf(): Auxiliary function for controlling updates and checks of PAGE_MAX_TRX_ID: check whether an index is a secondary index or the insert buffer tree. page_set_max_trx_id(), page_update_max_trx_id(), lock_rec_insert_check_and_lock(), lock_sec_rec_modify_check_and_lock(), btr_cur_ins_lock_and_undo(), btr_cur_upd_lock_and_undo(): Add the parameter mtr. page_set_max_trx_id(): Allow mtr to be NULL. When mtr==NULL, do not attempt to write to the redo log. This only occurs when creating a page or reorganizing a compressed page. In these cases, the PAGE_MAX_TRX_ID will be set correctly during the application of redo log records, even though there is no explicit log record about it. btr_discard_only_page_on_level(): Preserve PAGE_MAX_TRX_ID. This function should be unreachable, though. btr_cur_pessimistic_update(): Update PAGE_MAX_TRX_ID. Add some assertions for checking that PAGE_MAX_TRX_ID is set on all secondary index leaf pages. rb://115 tested by Michael, fixes Issue #211 ------------------------------------------------------------------------ r5039 | marko | 2009-05-19 23:13:12 +0300 (Tue, 19 May 2009) | 1 line branches/zip: ib_wqueue_wait(): Add decorative comment. ------------------------------------------------------------------------ r5041 | marko | 2009-05-20 08:42:12 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Add missing function comments. ------------------------------------------------------------------------ r5042 | marko | 2009-05-20 08:46:01 +0300 (Wed, 20 May 2009) | 1 line branches/zip: sync0rw.ic: Remove an extra ; that was added in r5041. ------------------------------------------------------------------------ r5044 | marko | 2009-05-20 11:11:58 +0300 (Wed, 20 May 2009) | 2 lines branches/zip: mlog_parse_index(): Correct a parameter comment and add a const qualifier that was missing. ------------------------------------------------------------------------ r5045 | marko | 2009-05-20 11:37:08 +0300 (Wed, 20 May 2009) | 1 line branches/zip: fil0fil.c: Correct some comments. ------------------------------------------------------------------------ r5046 | marko | 2009-05-20 12:19:40 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Fix some function comments. ------------------------------------------------------------------------ r5047 | marko | 2009-05-20 12:26:49 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ut_snprintf(): Fix the function comments. ------------------------------------------------------------------------ r5048 | marko | 2009-05-20 12:28:44 +0300 (Wed, 20 May 2009) | 3 lines branches/zip: inno_bcmp(): Remove this memcmp replacement. srv0start.c does not (any longer) call memcmp. srv_parse_megabytes(): Add a function comment. ------------------------------------------------------------------------ r5052 | marko | 2009-05-20 12:32:37 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ib_vector_is_empty(): Fix the function comment. ------------------------------------------------------------------------ r5054 | marko | 2009-05-20 12:35:33 +0300 (Wed, 20 May 2009) | 1 line branches/zip: page_cur_lcg_prng(): Add missing parameter list. ------------------------------------------------------------------------ r5057 | marko | 2009-05-20 12:45:17 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Remove bogus in: comments from struct members. ------------------------------------------------------------------------ r5058 | marko | 2009-05-20 13:06:03 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Clean up some function comments. ------------------------------------------------------------------------ r5060 | marko | 2009-05-20 14:06:59 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Clean up some comments. ------------------------------------------------------------------------ r5061 | marko | 2009-05-20 14:07:49 +0300 (Wed, 20 May 2009) | 2 lines branches/zip: innodb_export_status(): Remove the return(0), now that the function was declared void in r5060. ------------------------------------------------------------------------ r5062 | marko | 2009-05-20 14:45:03 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ha_innodb.cc: Clean up some comments. ------------------------------------------------------------------------ r5063 | marko | 2009-05-20 16:10:17 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ut_dulint_sort(): Write proper comments. ------------------------------------------------------------------------ r5064 | marko | 2009-05-20 16:17:26 +0300 (Wed, 20 May 2009) | 2 lines branches/zip: innobase_end(), innobase_flush_logs(): Document the function parameters. ------------------------------------------------------------------------ r5065 | marko | 2009-05-20 23:17:43 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ha_innodb.cc: Add some missing function comments. ------------------------------------------------------------------------ r5066 | marko | 2009-05-21 00:51:23 +0300 (Thu, 21 May 2009) | 2 lines branches/zip: Fix some function comments. ------------------------------------------------------------------------ r5070 | vasil | 2009-05-21 08:27:00 +0300 (Thu, 21 May 2009) | 4 lines branches/zip: Whitespace fixup. ------------------------------------------------------------------------
1079 lines
29 KiB
Text
1079 lines
29 KiB
Text
/*****************************************************************************
|
|
|
|
Copyright (c) 1994, 2009, Innobase Oy. 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., 59 Temple
|
|
Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/******************************************************
|
|
Index page routines
|
|
|
|
Created 2/2/1994 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#include "mach0data.h"
|
|
#ifdef UNIV_DEBUG
|
|
# include "log0recv.h"
|
|
#endif /* !UNIV_DEBUG */
|
|
#ifndef UNIV_HOTBACKUP
|
|
# include "rem0cmp.h"
|
|
#endif /* !UNIV_HOTBACKUP */
|
|
#include "mtr0log.h"
|
|
#include "page0zip.h"
|
|
|
|
#ifdef UNIV_MATERIALIZE
|
|
#undef UNIV_INLINE
|
|
#define UNIV_INLINE
|
|
#endif
|
|
|
|
/****************************************************************
|
|
Gets the start of a page. */
|
|
UNIV_INLINE
|
|
page_t*
|
|
page_align(
|
|
/*=======*/
|
|
/* out: start of the page */
|
|
const void* ptr) /* in: pointer to page frame */
|
|
{
|
|
return((page_t*) ut_align_down(ptr, UNIV_PAGE_SIZE));
|
|
}
|
|
/****************************************************************
|
|
Gets the offset within a page. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_offset(
|
|
/*========*/
|
|
/* out: offset from the start of the page */
|
|
const void* ptr) /* in: pointer to page frame */
|
|
{
|
|
return(ut_align_offset(ptr, UNIV_PAGE_SIZE));
|
|
}
|
|
/*****************************************************************
|
|
Returns the max trx id field value. */
|
|
UNIV_INLINE
|
|
trx_id_t
|
|
page_get_max_trx_id(
|
|
/*================*/
|
|
const page_t* page) /* in: page */
|
|
{
|
|
ut_ad(page);
|
|
|
|
return(mach_read_from_8(page + PAGE_HEADER + PAGE_MAX_TRX_ID));
|
|
}
|
|
|
|
/*****************************************************************
|
|
Sets the max trx id field value if trx_id is bigger than the previous
|
|
value. */
|
|
UNIV_INLINE
|
|
void
|
|
page_update_max_trx_id(
|
|
/*===================*/
|
|
buf_block_t* block, /* in/out: page */
|
|
page_zip_des_t* page_zip,/* in/out: compressed page whose
|
|
uncompressed part will be updated, or NULL */
|
|
trx_id_t trx_id, /* in: transaction id */
|
|
mtr_t* mtr) /* in/out: mini-transaction */
|
|
{
|
|
ut_ad(block);
|
|
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
|
|
/* During crash recovery, this function may be called on
|
|
something else than a leaf page of a secondary index or the
|
|
insert buffer index tree (dict_index_is_sec_or_ibuf() returns
|
|
TRUE for the dummy indexes constructed during redo log
|
|
application). In that case, PAGE_MAX_TRX_ID is unused,
|
|
and trx_id is usually zero. */
|
|
ut_ad(!ut_dulint_is_zero(trx_id) || recv_recovery_is_on());
|
|
ut_ad(page_is_leaf(buf_block_get_frame(block)));
|
|
|
|
if (ut_dulint_cmp(page_get_max_trx_id(buf_block_get_frame(block)),
|
|
trx_id) < 0) {
|
|
|
|
page_set_max_trx_id(block, page_zip, trx_id, mtr);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************
|
|
Reads the given header field. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_header_get_field(
|
|
/*==================*/
|
|
const page_t* page, /* in: page */
|
|
ulint field) /* in: PAGE_LEVEL, ... */
|
|
{
|
|
ut_ad(page);
|
|
ut_ad(field <= PAGE_INDEX_ID);
|
|
|
|
return(mach_read_from_2(page + PAGE_HEADER + field));
|
|
}
|
|
|
|
/*****************************************************************
|
|
Sets the given header field. */
|
|
UNIV_INLINE
|
|
void
|
|
page_header_set_field(
|
|
/*==================*/
|
|
page_t* page, /* in/out: page */
|
|
page_zip_des_t* page_zip,/* in/out: compressed page whose
|
|
uncompressed part will be updated, or NULL */
|
|
ulint field, /* in: PAGE_N_DIR_SLOTS, ... */
|
|
ulint val) /* in: value */
|
|
{
|
|
ut_ad(page);
|
|
ut_ad(field <= PAGE_N_RECS);
|
|
ut_ad(field == PAGE_N_HEAP || val < UNIV_PAGE_SIZE);
|
|
ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < UNIV_PAGE_SIZE);
|
|
|
|
mach_write_to_2(page + PAGE_HEADER + field, val);
|
|
if (UNIV_LIKELY_NULL(page_zip)) {
|
|
page_zip_write_header(page_zip,
|
|
page + PAGE_HEADER + field, 2, NULL);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************
|
|
Returns the offset stored in the given header field. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_header_get_offs(
|
|
/*=================*/
|
|
/* out: offset from the start of the page,
|
|
or 0 */
|
|
const page_t* page, /* in: page */
|
|
ulint field) /* in: PAGE_FREE, ... */
|
|
{
|
|
ulint offs;
|
|
|
|
ut_ad(page);
|
|
ut_ad((field == PAGE_FREE)
|
|
|| (field == PAGE_LAST_INSERT)
|
|
|| (field == PAGE_HEAP_TOP));
|
|
|
|
offs = page_header_get_field(page, field);
|
|
|
|
ut_ad((field != PAGE_HEAP_TOP) || offs);
|
|
|
|
return(offs);
|
|
}
|
|
|
|
/*****************************************************************
|
|
Sets the pointer stored in the given header field. */
|
|
UNIV_INLINE
|
|
void
|
|
page_header_set_ptr(
|
|
/*================*/
|
|
page_t* page, /* in: page */
|
|
page_zip_des_t* page_zip,/* in/out: compressed page whose
|
|
uncompressed part will be updated, or NULL */
|
|
ulint field, /* in: PAGE_FREE, ... */
|
|
const byte* ptr) /* in: pointer or NULL*/
|
|
{
|
|
ulint offs;
|
|
|
|
ut_ad(page);
|
|
ut_ad((field == PAGE_FREE)
|
|
|| (field == PAGE_LAST_INSERT)
|
|
|| (field == PAGE_HEAP_TOP));
|
|
|
|
if (ptr == NULL) {
|
|
offs = 0;
|
|
} else {
|
|
offs = ptr - page;
|
|
}
|
|
|
|
ut_ad((field != PAGE_HEAP_TOP) || offs);
|
|
|
|
page_header_set_field(page, page_zip, field, offs);
|
|
}
|
|
|
|
#ifndef UNIV_HOTBACKUP
|
|
/*****************************************************************
|
|
Resets the last insert info field in the page header. Writes to mlog
|
|
about this operation. */
|
|
UNIV_INLINE
|
|
void
|
|
page_header_reset_last_insert(
|
|
/*==========================*/
|
|
page_t* page, /* in/out: page */
|
|
page_zip_des_t* page_zip,/* in/out: compressed page whose
|
|
uncompressed part will be updated, or NULL */
|
|
mtr_t* mtr) /* in: mtr */
|
|
{
|
|
ut_ad(page && mtr);
|
|
|
|
if (UNIV_LIKELY_NULL(page_zip)) {
|
|
mach_write_to_2(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0);
|
|
page_zip_write_header(page_zip,
|
|
page + (PAGE_HEADER + PAGE_LAST_INSERT),
|
|
2, mtr);
|
|
} else {
|
|
mlog_write_ulint(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0,
|
|
MLOG_2BYTES, mtr);
|
|
}
|
|
}
|
|
#endif /* !UNIV_HOTBACKUP */
|
|
|
|
/****************************************************************
|
|
Determine whether the page is in new-style compact format. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_is_comp(
|
|
/*=========*/
|
|
/* out: nonzero if the page is in compact
|
|
format, zero if it is in old-style format */
|
|
const page_t* page) /* in: index page */
|
|
{
|
|
return(UNIV_EXPECT(page_header_get_field(page, PAGE_N_HEAP) & 0x8000,
|
|
0x8000));
|
|
}
|
|
|
|
/****************************************************************
|
|
TRUE if the record is on a page in compact format. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_rec_is_comp(
|
|
/*=============*/
|
|
/* out: nonzero if in compact format */
|
|
const rec_t* rec) /* in: record */
|
|
{
|
|
return(page_is_comp(page_align(rec)));
|
|
}
|
|
|
|
/*******************************************************************
|
|
Returns the heap number of a record. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_rec_get_heap_no(
|
|
/*=================*/
|
|
/* out: heap number */
|
|
const rec_t* rec) /* in: the physical record */
|
|
{
|
|
if (page_rec_is_comp(rec)) {
|
|
return(rec_get_heap_no_new(rec));
|
|
} else {
|
|
return(rec_get_heap_no_old(rec));
|
|
}
|
|
}
|
|
|
|
/****************************************************************
|
|
Determine whether the page is a B-tree leaf. */
|
|
UNIV_INLINE
|
|
ibool
|
|
page_is_leaf(
|
|
/*=========*/
|
|
/* out: TRUE if the page is a B-tree leaf */
|
|
const page_t* page) /* in: page */
|
|
{
|
|
return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
|
|
}
|
|
|
|
/****************************************************************
|
|
Gets the offset of the first record on the page. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_infimum_offset(
|
|
/*====================*/
|
|
/* out: offset of the first record
|
|
in record list, relative from page */
|
|
const page_t* page) /* in: page which must have record(s) */
|
|
{
|
|
ut_ad(page);
|
|
ut_ad(!page_offset(page));
|
|
|
|
if (page_is_comp(page)) {
|
|
return(PAGE_NEW_INFIMUM);
|
|
} else {
|
|
return(PAGE_OLD_INFIMUM);
|
|
}
|
|
}
|
|
|
|
/****************************************************************
|
|
Gets the offset of the last record on the page. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_supremum_offset(
|
|
/*=====================*/
|
|
/* out: offset of the last record in
|
|
record list, relative from page */
|
|
const page_t* page) /* in: page which must have record(s) */
|
|
{
|
|
ut_ad(page);
|
|
ut_ad(!page_offset(page));
|
|
|
|
if (page_is_comp(page)) {
|
|
return(PAGE_NEW_SUPREMUM);
|
|
} else {
|
|
return(PAGE_OLD_SUPREMUM);
|
|
}
|
|
}
|
|
|
|
/****************************************************************
|
|
TRUE if the record is a user record on the page. */
|
|
UNIV_INLINE
|
|
ibool
|
|
page_rec_is_user_rec_low(
|
|
/*=====================*/
|
|
/* out: TRUE if a user record */
|
|
ulint offset) /* in: record offset on page */
|
|
{
|
|
ut_ad(offset >= PAGE_NEW_INFIMUM);
|
|
#if PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM
|
|
# error "PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM"
|
|
#endif
|
|
#if PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM
|
|
# error "PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM"
|
|
#endif
|
|
#if PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM
|
|
# error "PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM"
|
|
#endif
|
|
#if PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM
|
|
# error "PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM"
|
|
#endif
|
|
#if PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END
|
|
# error "PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END"
|
|
#endif
|
|
#if PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END
|
|
# error "PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END"
|
|
#endif
|
|
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
|
|
|
|
return(UNIV_LIKELY(offset != PAGE_NEW_SUPREMUM)
|
|
&& UNIV_LIKELY(offset != PAGE_NEW_INFIMUM)
|
|
&& UNIV_LIKELY(offset != PAGE_OLD_INFIMUM)
|
|
&& UNIV_LIKELY(offset != PAGE_OLD_SUPREMUM));
|
|
}
|
|
|
|
/****************************************************************
|
|
TRUE if the record is the supremum record on a page. */
|
|
UNIV_INLINE
|
|
ibool
|
|
page_rec_is_supremum_low(
|
|
/*=====================*/
|
|
/* out: TRUE if the supremum record */
|
|
ulint offset) /* in: record offset on page */
|
|
{
|
|
ut_ad(offset >= PAGE_NEW_INFIMUM);
|
|
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
|
|
|
|
return(UNIV_UNLIKELY(offset == PAGE_NEW_SUPREMUM)
|
|
|| UNIV_UNLIKELY(offset == PAGE_OLD_SUPREMUM));
|
|
}
|
|
|
|
/****************************************************************
|
|
TRUE if the record is the infimum record on a page. */
|
|
UNIV_INLINE
|
|
ibool
|
|
page_rec_is_infimum_low(
|
|
/*====================*/
|
|
/* out: TRUE if the infimum record */
|
|
ulint offset) /* in: record offset on page */
|
|
{
|
|
ut_ad(offset >= PAGE_NEW_INFIMUM);
|
|
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
|
|
|
|
return(UNIV_UNLIKELY(offset == PAGE_NEW_INFIMUM)
|
|
|| UNIV_UNLIKELY(offset == PAGE_OLD_INFIMUM));
|
|
}
|
|
|
|
/****************************************************************
|
|
TRUE if the record is a user record on the page. */
|
|
UNIV_INLINE
|
|
ibool
|
|
page_rec_is_user_rec(
|
|
/*=================*/
|
|
/* out: TRUE if a user record */
|
|
const rec_t* rec) /* in: record */
|
|
{
|
|
return(page_rec_is_user_rec_low(page_offset(rec)));
|
|
}
|
|
|
|
/****************************************************************
|
|
TRUE if the record is the supremum record on a page. */
|
|
UNIV_INLINE
|
|
ibool
|
|
page_rec_is_supremum(
|
|
/*=================*/
|
|
/* out: TRUE if the supremum record */
|
|
const rec_t* rec) /* in: record */
|
|
{
|
|
return(page_rec_is_supremum_low(page_offset(rec)));
|
|
}
|
|
|
|
/****************************************************************
|
|
TRUE if the record is the infimum record on a page. */
|
|
UNIV_INLINE
|
|
ibool
|
|
page_rec_is_infimum(
|
|
/*================*/
|
|
/* out: TRUE if the infimum record */
|
|
const rec_t* rec) /* in: record */
|
|
{
|
|
return(page_rec_is_infimum_low(page_offset(rec)));
|
|
}
|
|
|
|
#ifndef UNIV_HOTBACKUP
|
|
/*****************************************************************
|
|
Compares a data tuple to a physical record. Differs from the function
|
|
cmp_dtuple_rec_with_match in the way that the record must reside on an
|
|
index page, and also page infimum and supremum records can be given in
|
|
the parameter rec. These are considered as the negative infinity and
|
|
the positive infinity in the alphabetical order. */
|
|
UNIV_INLINE
|
|
int
|
|
page_cmp_dtuple_rec_with_match(
|
|
/*===========================*/
|
|
/* out: 1, 0, -1, if dtuple is greater, equal,
|
|
less than rec, respectively, when only the
|
|
common first fields are compared */
|
|
const dtuple_t* dtuple, /* in: data tuple */
|
|
const rec_t* rec, /* in: physical record on a page; may also
|
|
be page infimum or supremum, in which case
|
|
matched-parameter values below are not
|
|
affected */
|
|
const ulint* offsets,/* in: array returned by rec_get_offsets() */
|
|
ulint* matched_fields, /* in/out: number of already completely
|
|
matched fields; when function returns
|
|
contains the value for current comparison */
|
|
ulint* matched_bytes) /* in/out: number of already matched
|
|
bytes within the first field not completely
|
|
matched; when function returns contains the
|
|
value for current comparison */
|
|
{
|
|
ulint rec_offset;
|
|
|
|
ut_ad(dtuple_check_typed(dtuple));
|
|
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
|
ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
|
|
|
|
rec_offset = page_offset(rec);
|
|
|
|
if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_INFIMUM)
|
|
|| UNIV_UNLIKELY(rec_offset == PAGE_OLD_INFIMUM)) {
|
|
return(1);
|
|
}
|
|
if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_SUPREMUM)
|
|
|| UNIV_UNLIKELY(rec_offset == PAGE_OLD_SUPREMUM)) {
|
|
return(-1);
|
|
}
|
|
|
|
return(cmp_dtuple_rec_with_match(dtuple, rec, offsets,
|
|
matched_fields,
|
|
matched_bytes));
|
|
}
|
|
#endif /* !UNIV_HOTBACKUP */
|
|
|
|
/*****************************************************************
|
|
Gets the page number. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_page_no(
|
|
/*=============*/
|
|
/* out: page number */
|
|
const page_t* page) /* in: page */
|
|
{
|
|
ut_ad(page == page_align((page_t*) page));
|
|
return(mach_read_from_4(page + FIL_PAGE_OFFSET));
|
|
}
|
|
|
|
/*****************************************************************
|
|
Gets the tablespace identifier. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_space_id(
|
|
/*==============*/
|
|
/* out: space id */
|
|
const page_t* page) /* in: page */
|
|
{
|
|
ut_ad(page == page_align((page_t*) page));
|
|
return(mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID));
|
|
}
|
|
|
|
/*****************************************************************
|
|
Gets the number of user records on page (infimum and supremum records
|
|
are not user records). */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_n_recs(
|
|
/*============*/
|
|
/* out: number of user records */
|
|
const page_t* page) /* in: index page */
|
|
{
|
|
return(page_header_get_field(page, PAGE_N_RECS));
|
|
}
|
|
|
|
/*****************************************************************
|
|
Gets the number of dir slots in directory. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_dir_get_n_slots(
|
|
/*=================*/
|
|
/* out: number of slots */
|
|
const page_t* page) /* in: index page */
|
|
{
|
|
return(page_header_get_field(page, PAGE_N_DIR_SLOTS));
|
|
}
|
|
/*****************************************************************
|
|
Sets the number of dir slots in directory. */
|
|
UNIV_INLINE
|
|
void
|
|
page_dir_set_n_slots(
|
|
/*=================*/
|
|
page_t* page, /* in/out: page */
|
|
page_zip_des_t* page_zip,/* in/out: compressed page whose
|
|
uncompressed part will be updated, or NULL */
|
|
ulint n_slots)/* in: number of slots */
|
|
{
|
|
page_header_set_field(page, page_zip, PAGE_N_DIR_SLOTS, n_slots);
|
|
}
|
|
|
|
/*****************************************************************
|
|
Gets the number of records in the heap. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_dir_get_n_heap(
|
|
/*================*/
|
|
/* out: number of user records */
|
|
const page_t* page) /* in: index page */
|
|
{
|
|
return(page_header_get_field(page, PAGE_N_HEAP) & 0x7fff);
|
|
}
|
|
|
|
/*****************************************************************
|
|
Sets the number of records in the heap. */
|
|
UNIV_INLINE
|
|
void
|
|
page_dir_set_n_heap(
|
|
/*================*/
|
|
page_t* page, /* in/out: index page */
|
|
page_zip_des_t* page_zip,/* in/out: compressed page whose
|
|
uncompressed part will be updated, or NULL.
|
|
Note that the size of the dense page directory
|
|
in the compressed page trailer is
|
|
n_heap * PAGE_ZIP_DIR_SLOT_SIZE. */
|
|
ulint n_heap) /* in: number of records */
|
|
{
|
|
ut_ad(n_heap < 0x8000);
|
|
ut_ad(!page_zip || n_heap
|
|
== (page_header_get_field(page, PAGE_N_HEAP) & 0x7fff) + 1);
|
|
|
|
page_header_set_field(page, page_zip, PAGE_N_HEAP, n_heap
|
|
| (0x8000
|
|
& page_header_get_field(page, PAGE_N_HEAP)));
|
|
}
|
|
|
|
#ifdef UNIV_DEBUG
|
|
/*****************************************************************
|
|
Gets pointer to nth directory slot. */
|
|
UNIV_INLINE
|
|
page_dir_slot_t*
|
|
page_dir_get_nth_slot(
|
|
/*==================*/
|
|
/* out: pointer to dir slot */
|
|
const page_t* page, /* in: index page */
|
|
ulint n) /* in: position */
|
|
{
|
|
ut_ad(page_dir_get_n_slots(page) > n);
|
|
|
|
return((page_dir_slot_t*)
|
|
page + UNIV_PAGE_SIZE - PAGE_DIR
|
|
- (n + 1) * PAGE_DIR_SLOT_SIZE);
|
|
}
|
|
#endif /* UNIV_DEBUG */
|
|
|
|
/******************************************************************
|
|
Used to check the consistency of a record on a page. */
|
|
UNIV_INLINE
|
|
ibool
|
|
page_rec_check(
|
|
/*===========*/
|
|
/* out: TRUE if succeed */
|
|
const rec_t* rec) /* in: record */
|
|
{
|
|
const page_t* page = page_align(rec);
|
|
|
|
ut_a(rec);
|
|
|
|
ut_a(page_offset(rec) <= page_header_get_field(page, PAGE_HEAP_TOP));
|
|
ut_a(page_offset(rec) >= PAGE_DATA);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/*******************************************************************
|
|
Gets the record pointed to by a directory slot. */
|
|
UNIV_INLINE
|
|
const rec_t*
|
|
page_dir_slot_get_rec(
|
|
/*==================*/
|
|
/* out: pointer to record */
|
|
const page_dir_slot_t* slot) /* in: directory slot */
|
|
{
|
|
return(page_align(slot) + mach_read_from_2(slot));
|
|
}
|
|
|
|
/*******************************************************************
|
|
This is used to set the record offset in a directory slot. */
|
|
UNIV_INLINE
|
|
void
|
|
page_dir_slot_set_rec(
|
|
/*==================*/
|
|
page_dir_slot_t* slot, /* in: directory slot */
|
|
rec_t* rec) /* in: record on the page */
|
|
{
|
|
ut_ad(page_rec_check(rec));
|
|
|
|
mach_write_to_2(slot, page_offset(rec));
|
|
}
|
|
|
|
/*******************************************************************
|
|
Gets the number of records owned by a directory slot. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_dir_slot_get_n_owned(
|
|
/*======================*/
|
|
/* out: number of records */
|
|
const page_dir_slot_t* slot) /* in: page directory slot */
|
|
{
|
|
const rec_t* rec = page_dir_slot_get_rec(slot);
|
|
if (page_rec_is_comp(slot)) {
|
|
return(rec_get_n_owned_new(rec));
|
|
} else {
|
|
return(rec_get_n_owned_old(rec));
|
|
}
|
|
}
|
|
|
|
/*******************************************************************
|
|
This is used to set the owned records field of a directory slot. */
|
|
UNIV_INLINE
|
|
void
|
|
page_dir_slot_set_n_owned(
|
|
/*======================*/
|
|
page_dir_slot_t*slot, /* in/out: directory slot */
|
|
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
|
|
ulint n) /* in: number of records owned by the slot */
|
|
{
|
|
rec_t* rec = (rec_t*) page_dir_slot_get_rec(slot);
|
|
if (page_rec_is_comp(slot)) {
|
|
rec_set_n_owned_new(rec, page_zip, n);
|
|
} else {
|
|
ut_ad(!page_zip);
|
|
rec_set_n_owned_old(rec, n);
|
|
}
|
|
}
|
|
|
|
/****************************************************************
|
|
Calculates the space reserved for directory slots of a given number of
|
|
records. The exact value is a fraction number n * PAGE_DIR_SLOT_SIZE /
|
|
PAGE_DIR_SLOT_MIN_N_OWNED, and it is rounded upwards to an integer. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_dir_calc_reserved_space(
|
|
/*=========================*/
|
|
ulint n_recs) /* in: number of records */
|
|
{
|
|
return((PAGE_DIR_SLOT_SIZE * n_recs + PAGE_DIR_SLOT_MIN_N_OWNED - 1)
|
|
/ PAGE_DIR_SLOT_MIN_N_OWNED);
|
|
}
|
|
|
|
/****************************************************************
|
|
Gets the pointer to the next record on the page. */
|
|
UNIV_INLINE
|
|
const rec_t*
|
|
page_rec_get_next_low(
|
|
/*==================*/
|
|
/* out: pointer to next record */
|
|
const rec_t* rec, /* in: pointer to record */
|
|
ulint comp) /* in: nonzero=compact page layout */
|
|
{
|
|
ulint offs;
|
|
const page_t* page;
|
|
|
|
ut_ad(page_rec_check(rec));
|
|
|
|
page = page_align(rec);
|
|
|
|
offs = rec_get_next_offs(rec, comp);
|
|
|
|
if (UNIV_UNLIKELY(offs >= UNIV_PAGE_SIZE)) {
|
|
fprintf(stderr,
|
|
"InnoDB: Next record offset is nonsensical %lu"
|
|
" in record at offset %lu\n"
|
|
"InnoDB: rec address %p, space id %lu, page %lu\n",
|
|
(ulong)offs, (ulong) page_offset(rec),
|
|
(void*) rec,
|
|
(ulong) page_get_space_id(page),
|
|
(ulong) page_get_page_no(page));
|
|
buf_page_print(page, 0);
|
|
|
|
ut_error;
|
|
}
|
|
|
|
if (UNIV_UNLIKELY(offs == 0)) {
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
return(page + offs);
|
|
}
|
|
|
|
/****************************************************************
|
|
Gets the pointer to the next record on the page. */
|
|
UNIV_INLINE
|
|
rec_t*
|
|
page_rec_get_next(
|
|
/*==============*/
|
|
/* out: pointer to next record */
|
|
rec_t* rec) /* in: pointer to record */
|
|
{
|
|
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
|
|
}
|
|
|
|
/****************************************************************
|
|
Gets the pointer to the next record on the page. */
|
|
UNIV_INLINE
|
|
const rec_t*
|
|
page_rec_get_next_const(
|
|
/*====================*/
|
|
/* out: pointer to next record */
|
|
const rec_t* rec) /* in: pointer to record */
|
|
{
|
|
return(page_rec_get_next_low(rec, page_rec_is_comp(rec)));
|
|
}
|
|
|
|
/****************************************************************
|
|
Sets the pointer to the next record on the page. */
|
|
UNIV_INLINE
|
|
void
|
|
page_rec_set_next(
|
|
/*==============*/
|
|
rec_t* rec, /* in: pointer to record,
|
|
must not be page supremum */
|
|
rec_t* next) /* in: pointer to next record,
|
|
must not be page infimum */
|
|
{
|
|
ulint offs;
|
|
|
|
ut_ad(page_rec_check(rec));
|
|
ut_ad(!page_rec_is_supremum(rec));
|
|
ut_ad(rec != next);
|
|
|
|
ut_ad(!next || !page_rec_is_infimum(next));
|
|
ut_ad(!next || page_align(rec) == page_align(next));
|
|
|
|
if (UNIV_LIKELY(next != NULL)) {
|
|
offs = page_offset(next);
|
|
} else {
|
|
offs = 0;
|
|
}
|
|
|
|
if (page_rec_is_comp(rec)) {
|
|
rec_set_next_offs_new(rec, offs);
|
|
} else {
|
|
rec_set_next_offs_old(rec, offs);
|
|
}
|
|
}
|
|
|
|
/****************************************************************
|
|
Gets the pointer to the previous record. */
|
|
UNIV_INLINE
|
|
const rec_t*
|
|
page_rec_get_prev_const(
|
|
/*====================*/
|
|
/* out: pointer to previous record */
|
|
const rec_t* rec) /* in: pointer to record, must not be page
|
|
infimum */
|
|
{
|
|
const page_dir_slot_t* slot;
|
|
ulint slot_no;
|
|
const rec_t* rec2;
|
|
const rec_t* prev_rec = NULL;
|
|
const page_t* page;
|
|
|
|
ut_ad(page_rec_check(rec));
|
|
|
|
page = page_align(rec);
|
|
|
|
ut_ad(!page_rec_is_infimum(rec));
|
|
|
|
slot_no = page_dir_find_owner_slot(rec);
|
|
|
|
ut_a(slot_no != 0);
|
|
|
|
slot = page_dir_get_nth_slot(page, slot_no - 1);
|
|
|
|
rec2 = page_dir_slot_get_rec(slot);
|
|
|
|
if (page_is_comp(page)) {
|
|
while (rec != rec2) {
|
|
prev_rec = rec2;
|
|
rec2 = page_rec_get_next_low(rec2, TRUE);
|
|
}
|
|
} else {
|
|
while (rec != rec2) {
|
|
prev_rec = rec2;
|
|
rec2 = page_rec_get_next_low(rec2, FALSE);
|
|
}
|
|
}
|
|
|
|
ut_a(prev_rec);
|
|
|
|
return(prev_rec);
|
|
}
|
|
|
|
/****************************************************************
|
|
Gets the pointer to the previous record. */
|
|
UNIV_INLINE
|
|
rec_t*
|
|
page_rec_get_prev(
|
|
/*==============*/
|
|
/* out: pointer to previous record */
|
|
rec_t* rec) /* in: pointer to record, must not be page
|
|
infimum */
|
|
{
|
|
return((rec_t*) page_rec_get_prev_const(rec));
|
|
}
|
|
|
|
/*******************************************************************
|
|
Looks for the record which owns the given record. */
|
|
UNIV_INLINE
|
|
rec_t*
|
|
page_rec_find_owner_rec(
|
|
/*====================*/
|
|
/* out: the owner record */
|
|
rec_t* rec) /* in: the physical record */
|
|
{
|
|
ut_ad(page_rec_check(rec));
|
|
|
|
if (page_rec_is_comp(rec)) {
|
|
while (rec_get_n_owned_new(rec) == 0) {
|
|
rec = page_rec_get_next(rec);
|
|
}
|
|
} else {
|
|
while (rec_get_n_owned_old(rec) == 0) {
|
|
rec = page_rec_get_next(rec);
|
|
}
|
|
}
|
|
|
|
return(rec);
|
|
}
|
|
|
|
/**************************************************************
|
|
Returns the base extra size of a physical record. This is the
|
|
size of the fixed header, independent of the record size. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_rec_get_base_extra_size(
|
|
/*=========================*/
|
|
/* out: REC_N_NEW_EXTRA_BYTES
|
|
or REC_N_OLD_EXTRA_BYTES */
|
|
const rec_t* rec) /* in: physical record */
|
|
{
|
|
#if REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES
|
|
# error "REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES"
|
|
#endif
|
|
return(REC_N_NEW_EXTRA_BYTES + (ulint) !page_rec_is_comp(rec));
|
|
}
|
|
|
|
/****************************************************************
|
|
Returns the sum of the sizes of the records in the record list, excluding
|
|
the infimum and supremum records. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_data_size(
|
|
/*===============*/
|
|
/* out: data in bytes */
|
|
const page_t* page) /* in: index page */
|
|
{
|
|
ulint ret;
|
|
|
|
ret = (ulint)(page_header_get_field(page, PAGE_HEAP_TOP)
|
|
- (page_is_comp(page)
|
|
? PAGE_NEW_SUPREMUM_END
|
|
: PAGE_OLD_SUPREMUM_END)
|
|
- page_header_get_field(page, PAGE_GARBAGE));
|
|
|
|
ut_ad(ret < UNIV_PAGE_SIZE);
|
|
|
|
return(ret);
|
|
}
|
|
|
|
|
|
/****************************************************************
|
|
Allocates a block of memory from the free list of an index page. */
|
|
UNIV_INTERN
|
|
void
|
|
page_mem_alloc_free(
|
|
/*================*/
|
|
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 */
|
|
rec_t* next_rec,/* in: pointer to the new head of the
|
|
free record list */
|
|
ulint need) /* in: number of bytes allocated */
|
|
{
|
|
ulint garbage;
|
|
|
|
#ifdef UNIV_DEBUG
|
|
const rec_t* old_rec = page_header_get_ptr(page, PAGE_FREE);
|
|
ulint next_offs;
|
|
|
|
ut_ad(old_rec);
|
|
next_offs = rec_get_next_offs(old_rec, page_is_comp(page));
|
|
ut_ad(next_rec == (next_offs ? page + next_offs : NULL));
|
|
#endif
|
|
|
|
page_header_set_ptr(page, page_zip, PAGE_FREE, next_rec);
|
|
|
|
garbage = page_header_get_field(page, PAGE_GARBAGE);
|
|
ut_ad(garbage >= need);
|
|
|
|
page_header_set_field(page, page_zip, PAGE_GARBAGE, garbage - need);
|
|
}
|
|
|
|
/*****************************************************************
|
|
Calculates free space if a page is emptied. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_free_space_of_empty(
|
|
/*=========================*/
|
|
/* out: free space */
|
|
ulint comp) /* in: nonzero=compact page layout */
|
|
{
|
|
if (UNIV_LIKELY(comp)) {
|
|
return((ulint)(UNIV_PAGE_SIZE
|
|
- PAGE_NEW_SUPREMUM_END
|
|
- PAGE_DIR
|
|
- 2 * PAGE_DIR_SLOT_SIZE));
|
|
}
|
|
|
|
return((ulint)(UNIV_PAGE_SIZE
|
|
- PAGE_OLD_SUPREMUM_END
|
|
- PAGE_DIR
|
|
- 2 * PAGE_DIR_SLOT_SIZE));
|
|
}
|
|
|
|
/****************************************************************
|
|
Each user record on a page, and also the deleted user records in the heap
|
|
takes its size plus the fraction of the dir cell size /
|
|
PAGE_DIR_SLOT_MIN_N_OWNED bytes for it. If the sum of these exceeds the
|
|
value of page_get_free_space_of_empty, the insert is impossible, otherwise
|
|
it is allowed. This function returns the maximum combined size of records
|
|
which can be inserted on top of the record heap. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_max_insert_size(
|
|
/*=====================*/
|
|
/* out: maximum combined size for
|
|
inserted records */
|
|
const page_t* page, /* in: index page */
|
|
ulint n_recs) /* in: number of records */
|
|
{
|
|
ulint occupied;
|
|
ulint free_space;
|
|
|
|
if (page_is_comp(page)) {
|
|
occupied = page_header_get_field(page, PAGE_HEAP_TOP)
|
|
- PAGE_NEW_SUPREMUM_END
|
|
+ page_dir_calc_reserved_space(
|
|
n_recs + page_dir_get_n_heap(page) - 2);
|
|
|
|
free_space = page_get_free_space_of_empty(TRUE);
|
|
} else {
|
|
occupied = page_header_get_field(page, PAGE_HEAP_TOP)
|
|
- PAGE_OLD_SUPREMUM_END
|
|
+ page_dir_calc_reserved_space(
|
|
n_recs + page_dir_get_n_heap(page) - 2);
|
|
|
|
free_space = page_get_free_space_of_empty(FALSE);
|
|
}
|
|
|
|
/* Above the 'n_recs +' part reserves directory space for the new
|
|
inserted records; the '- 2' excludes page infimum and supremum
|
|
records */
|
|
|
|
if (occupied > free_space) {
|
|
|
|
return(0);
|
|
}
|
|
|
|
return(free_space - occupied);
|
|
}
|
|
|
|
/****************************************************************
|
|
Returns the maximum combined size of records which can be inserted on top
|
|
of the record heap if a page is first reorganized. */
|
|
UNIV_INLINE
|
|
ulint
|
|
page_get_max_insert_size_after_reorganize(
|
|
/*======================================*/
|
|
/* out: maximum combined size for
|
|
inserted records */
|
|
const page_t* page, /* in: index page */
|
|
ulint n_recs) /* in: number of records */
|
|
{
|
|
ulint occupied;
|
|
ulint free_space;
|
|
|
|
occupied = page_get_data_size(page)
|
|
+ page_dir_calc_reserved_space(n_recs + page_get_n_recs(page));
|
|
|
|
free_space = page_get_free_space_of_empty(page_is_comp(page));
|
|
|
|
if (occupied > free_space) {
|
|
|
|
return(0);
|
|
}
|
|
|
|
return(free_space - occupied);
|
|
}
|
|
|
|
/****************************************************************
|
|
Puts a record to free list. */
|
|
UNIV_INLINE
|
|
void
|
|
page_mem_free(
|
|
/*==========*/
|
|
page_t* page, /* in/out: index page */
|
|
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
|
|
rec_t* rec, /* in: pointer to the (origin of) record */
|
|
dict_index_t* index, /* in: index of rec */
|
|
const ulint* offsets)/* in: array returned by rec_get_offsets() */
|
|
{
|
|
rec_t* free;
|
|
ulint garbage;
|
|
|
|
ut_ad(rec_offs_validate(rec, index, offsets));
|
|
free = page_header_get_ptr(page, PAGE_FREE);
|
|
|
|
page_rec_set_next(rec, free);
|
|
page_header_set_ptr(page, page_zip, PAGE_FREE, rec);
|
|
|
|
garbage = page_header_get_field(page, PAGE_GARBAGE);
|
|
|
|
page_header_set_field(page, page_zip, PAGE_GARBAGE,
|
|
garbage + rec_offs_size(offsets));
|
|
|
|
if (UNIV_LIKELY_NULL(page_zip)) {
|
|
page_zip_dir_delete(page_zip, rec, index, offsets, free);
|
|
} else {
|
|
page_header_set_field(page, page_zip, PAGE_N_RECS,
|
|
page_get_n_recs(page) - 1);
|
|
}
|
|
}
|
|
|
|
#ifdef UNIV_MATERIALIZE
|
|
#undef UNIV_INLINE
|
|
#define UNIV_INLINE UNIV_INLINE_ORIGINAL
|
|
#endif
|