summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2010-03-20 15:01:47 +0300
committerSergey Petrunya <psergey@askmonty.org>2010-03-20 15:01:47 +0300
commit7df026676b6d845cc0ed7a7437995c3019a5f42d (patch)
treedc051ac4712ac159b52fc2b48e5dd918cbc39799 /storage/xtradb
parentf59d1dcf0acc12c482c28c902a0030f12ba263af (diff)
parentf09ca00e088b316441bb76e97ba097bc9f3da7d3 (diff)
downloadmariadb-git-7df026676b6d845cc0ed7a7437995c3019a5f42d.tar.gz
Merge MariaDB-5.2 -> MariaDB 5.3
Diffstat (limited to 'storage/xtradb')
-rw-r--r--storage/xtradb/CMakeLists.txt134
-rw-r--r--storage/xtradb/COPYING.Percona30
-rw-r--r--storage/xtradb/COPYING.Sun_Microsystems31
-rw-r--r--storage/xtradb/ChangeLog690
-rw-r--r--storage/xtradb/Doxyfile1419
-rw-r--r--storage/xtradb/Makefile.am439
-rw-r--r--storage/xtradb/btr/btr0btr.c687
-rw-r--r--storage/xtradb/btr/btr0cur.c956
-rw-r--r--storage/xtradb/btr/btr0pcur.c86
-rw-r--r--storage/xtradb/btr/btr0sea.c317
-rw-r--r--storage/xtradb/buf/buf0buddy.c168
-rw-r--r--storage/xtradb/buf/buf0buf.c1060
-rw-r--r--storage/xtradb/buf/buf0flu.c396
-rw-r--r--storage/xtradb/buf/buf0lru.c776
-rw-r--r--storage/xtradb/buf/buf0rea.c367
-rw-r--r--storage/xtradb/data/data0data.c134
-rw-r--r--storage/xtradb/data/data0type.c121
-rw-r--r--storage/xtradb/dict/dict0boot.c46
-rw-r--r--storage/xtradb/dict/dict0crea.c228
-rw-r--r--storage/xtradb/dict/dict0dict.c1095
-rw-r--r--storage/xtradb/dict/dict0load.c134
-rw-r--r--storage/xtradb/dict/dict0mem.c103
-rw-r--r--storage/xtradb/dyn/dyn0dyn.c11
-rw-r--r--storage/xtradb/eval/eval0eval.c83
-rw-r--r--storage/xtradb/eval/eval0proc.c51
-rw-r--r--storage/xtradb/fil/fil0fil.c1622
-rw-r--r--storage/xtradb/fsp/fsp0fsp.c1104
-rw-r--r--storage/xtradb/fut/fut0fut.c3
-rw-r--r--storage/xtradb/fut/fut0lst.c91
-rw-r--r--storage/xtradb/ha/ha0ha.c129
-rw-r--r--storage/xtradb/ha/ha0storage.c21
-rw-r--r--storage/xtradb/ha/hash0hash.c57
-rw-r--r--storage/xtradb/handler/ha_innodb.cc2894
-rw-r--r--storage/xtradb/handler/ha_innodb.h90
-rw-r--r--storage/xtradb/handler/handler0alter.cc184
-rw-r--r--storage/xtradb/handler/handler0vars.h72
-rw-r--r--storage/xtradb/handler/i_s.cc440
-rw-r--r--storage/xtradb/handler/i_s.h4
-rw-r--r--storage/xtradb/handler/innodb_patch_info.h7
-rw-r--r--storage/xtradb/handler/mysql_addons.cc3
-rw-r--r--storage/xtradb/handler/win_delay_loader.cc1036
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.c679
-rw-r--r--storage/xtradb/include/btr0btr.h455
-rw-r--r--storage/xtradb/include/btr0btr.ic141
-rw-r--r--storage/xtradb/include/btr0cur.h617
-rw-r--r--storage/xtradb/include/btr0cur.ic92
-rw-r--r--storage/xtradb/include/btr0pcur.h338
-rw-r--r--storage/xtradb/include/btr0pcur.ic233
-rw-r--r--storage/xtradb/include/btr0sea.h193
-rw-r--r--storage/xtradb/include/btr0sea.ic23
-rw-r--r--storage/xtradb/include/btr0types.h10
-rw-r--r--storage/xtradb/include/buf0buddy.h21
-rw-r--r--storage/xtradb/include/buf0buddy.ic46
-rw-r--r--storage/xtradb/include/buf0buf.h1313
-rw-r--r--storage/xtradb/include/buf0buf.ic565
-rw-r--r--storage/xtradb/include/buf0flu.h117
-rw-r--r--storage/xtradb/include/buf0flu.ic27
-rw-r--r--storage/xtradb/include/buf0lru.h170
-rw-r--r--storage/xtradb/include/buf0lru.ic3
-rw-r--r--storage/xtradb/include/buf0rea.h99
-rw-r--r--storage/xtradb/include/buf0types.h36
-rw-r--r--storage/xtradb/include/data0data.h385
-rw-r--r--storage/xtradb/include/data0data.ic240
-rw-r--r--storage/xtradb/include/data0type.h269
-rw-r--r--storage/xtradb/include/data0type.ic216
-rw-r--r--storage/xtradb/include/data0types.h3
-rw-r--r--storage/xtradb/include/db0err.h4
-rw-r--r--storage/xtradb/include/dict0boot.h44
-rw-r--r--storage/xtradb/include/dict0boot.ic25
-rw-r--r--storage/xtradb/include/dict0crea.h102
-rw-r--r--storage/xtradb/include/dict0crea.ic3
-rw-r--r--storage/xtradb/include/dict0dict.h986
-rw-r--r--storage/xtradb/include/dict0dict.ic399
-rw-r--r--storage/xtradb/include/dict0load.h58
-rw-r--r--storage/xtradb/include/dict0load.ic3
-rw-r--r--storage/xtradb/include/dict0mem.h398
-rw-r--r--storage/xtradb/include/dict0mem.ic3
-rw-r--r--storage/xtradb/include/dict0types.h9
-rw-r--r--storage/xtradb/include/dyn0dyn.h128
-rw-r--r--storage/xtradb/include/dyn0dyn.ic111
-rw-r--r--storage/xtradb/include/eval0eval.h59
-rw-r--r--storage/xtradb/include/eval0eval.ic77
-rw-r--r--storage/xtradb/include/eval0proc.h67
-rw-r--r--storage/xtradb/include/eval0proc.ic19
-rw-r--r--storage/xtradb/include/fil0fil.h574
-rw-r--r--storage/xtradb/include/fsp0fsp.h336
-rw-r--r--storage/xtradb/include/fsp0fsp.ic13
-rw-r--r--storage/xtradb/include/fsp0types.h110
-rw-r--r--storage/xtradb/include/fut0fut.h21
-rw-r--r--storage/xtradb/include/fut0fut.ic21
-rw-r--r--storage/xtradb/include/fut0lst.h161
-rw-r--r--storage/xtradb/include/fut0lst.ic77
-rw-r--r--storage/xtradb/include/ha0ha.h187
-rw-r--r--storage/xtradb/include/ha0ha.ic110
-rw-r--r--storage/xtradb/include/ha0storage.h83
-rw-r--r--storage/xtradb/include/ha0storage.ic46
-rw-r--r--storage/xtradb/include/ha_prototypes.h226
-rw-r--r--storage/xtradb/include/handler0alter.h17
-rw-r--r--storage/xtradb/include/hash0hash.h175
-rw-r--r--storage/xtradb/include/hash0hash.ic87
-rw-r--r--storage/xtradb/include/ibuf0ibuf.h204
-rw-r--r--storage/xtradb/include/ibuf0ibuf.ic112
-rw-r--r--storage/xtradb/include/ibuf0types.h3
-rw-r--r--storage/xtradb/include/lock0iter.h19
-rw-r--r--storage/xtradb/include/lock0lock.h673
-rw-r--r--storage/xtradb/include/lock0lock.ic48
-rw-r--r--storage/xtradb/include/lock0priv.h58
-rw-r--r--storage/xtradb/include/lock0priv.ic11
-rw-r--r--storage/xtradb/include/lock0types.h3
-rw-r--r--storage/xtradb/include/log0log.h654
-rw-r--r--storage/xtradb/include/log0log.ic233
-rw-r--r--storage/xtradb/include/log0recv.h390
-rw-r--r--storage/xtradb/include/log0recv.ic21
-rw-r--r--storage/xtradb/include/mach0data.h310
-rw-r--r--storage/xtradb/include/mach0data.ic284
-rw-r--r--storage/xtradb/include/mem0dbg.h61
-rw-r--r--storage/xtradb/include/mem0dbg.ic47
-rw-r--r--storage/xtradb/include/mem0mem.h243
-rw-r--r--storage/xtradb/include/mem0mem.ic202
-rw-r--r--storage/xtradb/include/mem0pool.h72
-rw-r--r--storage/xtradb/include/mem0pool.ic3
-rw-r--r--storage/xtradb/include/mtr0log.h213
-rw-r--r--storage/xtradb/include/mtr0log.ic95
-rw-r--r--storage/xtradb/include/mtr0mtr.h341
-rw-r--r--storage/xtradb/include/mtr0mtr.ic108
-rw-r--r--storage/xtradb/include/mtr0types.h3
-rw-r--r--storage/xtradb/include/mysql_addons.h3
-rw-r--r--storage/xtradb/include/os0file.h563
-rw-r--r--storage/xtradb/include/os0proc.h31
-rw-r--r--storage/xtradb/include/os0proc.ic3
-rw-r--r--storage/xtradb/include/os0sync.h300
-rw-r--r--storage/xtradb/include/os0sync.ic21
-rw-r--r--storage/xtradb/include/os0thread.h76
-rw-r--r--storage/xtradb/include/os0thread.ic3
-rw-r--r--storage/xtradb/include/page0cur.h276
-rw-r--r--storage/xtradb/include/page0cur.ic137
-rw-r--r--storage/xtradb/include/page0page.h778
-rw-r--r--storage/xtradb/include/page0page.ic455
-rw-r--r--storage/xtradb/include/page0types.h68
-rw-r--r--storage/xtradb/include/page0zip.h372
-rw-r--r--storage/xtradb/include/page0zip.ic123
-rw-r--r--storage/xtradb/include/pars0opt.h23
-rw-r--r--storage/xtradb/include/pars0opt.ic3
-rw-r--r--storage/xtradb/include/pars0pars.h647
-rw-r--r--storage/xtradb/include/pars0pars.ic3
-rw-r--r--storage/xtradb/include/pars0sym.h165
-rw-r--r--storage/xtradb/include/pars0sym.ic3
-rw-r--r--storage/xtradb/include/pars0types.h3
-rw-r--r--storage/xtradb/include/que0que.h295
-rw-r--r--storage/xtradb/include/que0que.ic104
-rw-r--r--storage/xtradb/include/que0types.h9
-rw-r--r--storage/xtradb/include/read0read.h123
-rw-r--r--storage/xtradb/include/read0read.ic33
-rw-r--r--storage/xtradb/include/read0types.h3
-rw-r--r--storage/xtradb/include/rem0cmp.h177
-rw-r--r--storage/xtradb/include/rem0cmp.ic53
-rw-r--r--storage/xtradb/include/rem0rec.h648
-rw-r--r--storage/xtradb/include/rem0rec.ic625
-rw-r--r--storage/xtradb/include/rem0types.h3
-rw-r--r--storage/xtradb/include/row0ext.h61
-rw-r--r--storage/xtradb/include/row0ext.ic35
-rw-r--r--storage/xtradb/include/row0ins.h87
-rw-r--r--storage/xtradb/include/row0ins.ic3
-rw-r--r--storage/xtradb/include/row0merge.h151
-rw-r--r--storage/xtradb/include/row0mysql.h518
-rw-r--r--storage/xtradb/include/row0mysql.ic3
-rw-r--r--storage/xtradb/include/row0purge.h41
-rw-r--r--storage/xtradb/include/row0purge.ic3
-rw-r--r--storage/xtradb/include/row0row.h241
-rw-r--r--storage/xtradb/include/row0row.ic41
-rw-r--r--storage/xtradb/include/row0sel.h328
-rw-r--r--storage/xtradb/include/row0sel.ic25
-rw-r--r--storage/xtradb/include/row0types.h3
-rw-r--r--storage/xtradb/include/row0uins.h11
-rw-r--r--storage/xtradb/include/row0uins.ic3
-rw-r--r--storage/xtradb/include/row0umod.h13
-rw-r--r--storage/xtradb/include/row0umod.ic3
-rw-r--r--storage/xtradb/include/row0undo.h100
-rw-r--r--storage/xtradb/include/row0undo.ic3
-rw-r--r--storage/xtradb/include/row0upd.h338
-rw-r--r--storage/xtradb/include/row0upd.ic77
-rw-r--r--storage/xtradb/include/row0vers.h88
-rw-r--r--storage/xtradb/include/row0vers.ic3
-rw-r--r--storage/xtradb/include/srv0que.h38
-rw-r--r--storage/xtradb/include/srv0srv.h399
-rw-r--r--storage/xtradb/include/srv0srv.ic3
-rw-r--r--storage/xtradb/include/srv0start.h78
-rw-r--r--storage/xtradb/include/sync0arr.h74
-rw-r--r--storage/xtradb/include/sync0arr.ic3
-rw-r--r--storage/xtradb/include/sync0rw.h339
-rw-r--r--storage/xtradb/include/sync0rw.ic209
-rw-r--r--storage/xtradb/include/sync0sync.h245
-rw-r--r--storage/xtradb/include/sync0sync.ic130
-rw-r--r--storage/xtradb/include/sync0types.h5
-rw-r--r--storage/xtradb/include/thr0loc.h37
-rw-r--r--storage/xtradb/include/thr0loc.ic3
-rw-r--r--storage/xtradb/include/trx0i_s.h191
-rw-r--r--storage/xtradb/include/trx0purge.h132
-rw-r--r--storage/xtradb/include/trx0purge.ic11
-rw-r--r--storage/xtradb/include/trx0rec.h297
-rw-r--r--storage/xtradb/include/trx0rec.ic76
-rw-r--r--storage/xtradb/include/trx0roll.h274
-rw-r--r--storage/xtradb/include/trx0roll.ic13
-rw-r--r--storage/xtradb/include/trx0rseg.h135
-rw-r--r--storage/xtradb/include/trx0rseg.ic67
-rw-r--r--storage/xtradb/include/trx0sys.h512
-rw-r--r--storage/xtradb/include/trx0sys.ic158
-rw-r--r--storage/xtradb/include/trx0trx.h422
-rw-r--r--storage/xtradb/include/trx0trx.ic49
-rw-r--r--storage/xtradb/include/trx0types.h58
-rw-r--r--storage/xtradb/include/trx0undo.h463
-rw-r--r--storage/xtradb/include/trx0undo.ic163
-rw-r--r--storage/xtradb/include/trx0xa.h45
-rw-r--r--storage/xtradb/include/univ.i121
-rw-r--r--storage/xtradb/include/usr0sess.h29
-rw-r--r--storage/xtradb/include/usr0sess.ic3
-rw-r--r--storage/xtradb/include/usr0types.h3
-rw-r--r--storage/xtradb/include/ut0auxconf.h19
-rw-r--r--storage/xtradb/include/ut0byte.h228
-rw-r--r--storage/xtradb/include/ut0byte.ic200
-rw-r--r--storage/xtradb/include/ut0dbg.h67
-rw-r--r--storage/xtradb/include/ut0list.h103
-rw-r--r--storage/xtradb/include/ut0list.ic23
-rw-r--r--storage/xtradb/include/ut0lst.h186
-rw-r--r--storage/xtradb/include/ut0mem.h211
-rw-r--r--storage/xtradb/include/ut0mem.ic76
-rw-r--r--storage/xtradb/include/ut0rnd.h93
-rw-r--r--storage/xtradb/include/ut0rnd.ic84
-rw-r--r--storage/xtradb/include/ut0sort.h5
-rw-r--r--storage/xtradb/include/ut0ut.h327
-rw-r--r--storage/xtradb/include/ut0ut.ic77
-rw-r--r--storage/xtradb/include/ut0vec.h68
-rw-r--r--storage/xtradb/include/ut0vec.ic46
-rw-r--r--storage/xtradb/include/ut0wqueue.h42
-rw-r--r--storage/xtradb/lock/lock0iter.c19
-rw-r--r--storage/xtradb/lock/lock0lock.c1361
-rw-r--r--storage/xtradb/log/log0log.c647
-rw-r--r--storage/xtradb/log/log0recv.c1059
-rw-r--r--storage/xtradb/mach/mach0data.c29
-rw-r--r--storage/xtradb/mem/mem0dbg.c147
-rw-r--r--storage/xtradb/mem/mem0mem.c166
-rw-r--r--storage/xtradb/mem/mem0pool.c137
-rw-r--r--storage/xtradb/mtr/mtr0log.c147
-rw-r--r--storage/xtradb/mtr/mtr0mtr.c92
-rw-r--r--storage/xtradb/os/os0file.c1152
-rw-r--r--storage/xtradb/os/os0proc.c57
-rw-r--r--storage/xtradb/os/os0sync.c172
-rw-r--r--storage/xtradb/os/os0thread.c82
-rw-r--r--storage/xtradb/page/page0cur.c327
-rw-r--r--storage/xtradb/page/page0page.c486
-rw-r--r--storage/xtradb/page/page0zip.c908
-rw-r--r--storage/xtradb/pars/lexyy.c23
-rw-r--r--storage/xtradb/pars/pars0lex.l21
-rw-r--r--storage/xtradb/pars/pars0opt.c200
-rw-r--r--storage/xtradb/pars/pars0pars.c583
-rw-r--r--storage/xtradb/pars/pars0sym.c79
-rw-r--r--storage/xtradb/plug.in149
-rw-r--r--storage/xtradb/que/que0que.c223
-rw-r--r--storage/xtradb/read/read0read.c70
-rw-r--r--storage/xtradb/rem/rem0cmp.c250
-rw-r--r--storage/xtradb/rem/rem0rec.c282
-rw-r--r--storage/xtradb/row/row0ext.c29
-rw-r--r--storage/xtradb/row/row0ins.c420
-rw-r--r--storage/xtradb/row/row0merge.c932
-rw-r--r--storage/xtradb/row/row0mysql.c676
-rw-r--r--storage/xtradb/row/row0purge.c119
-rw-r--r--storage/xtradb/row/row0row.c291
-rw-r--r--storage/xtradb/row/row0sel.c544
-rw-r--r--storage/xtradb/row/row0uins.c48
-rw-r--r--storage/xtradb/row/row0umod.c155
-rw-r--r--storage/xtradb/row/row0undo.c53
-rw-r--r--storage/xtradb/row/row0upd.c459
-rw-r--r--storage/xtradb/row/row0vers.c102
-rw-r--r--storage/xtradb/scripts/install_innodb_plugins.sql1
-rw-r--r--storage/xtradb/scripts/install_innodb_plugins_win.sql8
-rw-r--r--storage/xtradb/srv/srv0que.c85
-rw-r--r--storage/xtradb/srv/srv0srv.c817
-rw-r--r--storage/xtradb/srv/srv0start.c424
-rw-r--r--storage/xtradb/sync/sync0arr.c234
-rw-r--r--storage/xtradb/sync/sync0rw.c218
-rw-r--r--storage/xtradb/sync/sync0sync.c387
-rw-r--r--storage/xtradb/thr/thr0loc.c95
-rw-r--r--storage/xtradb/trx/trx0i_s.c406
-rw-r--r--storage/xtradb/trx/trx0purge.c260
-rw-r--r--storage/xtradb/trx/trx0rec.c398
-rw-r--r--storage/xtradb/trx/trx0roll.c345
-rw-r--r--storage/xtradb/trx/trx0rseg.c106
-rw-r--r--storage/xtradb/trx/trx0sys.c563
-rw-r--r--storage/xtradb/trx/trx0trx.c306
-rw-r--r--storage/xtradb/trx/trx0undo.c586
-rw-r--r--storage/xtradb/usr/usr0sess.c50
-rw-r--r--storage/xtradb/ut/ut0auxconf.c13
-rw-r--r--storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c43
-rw-r--r--storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c54
-rw-r--r--storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c61
-rw-r--r--storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c39
-rw-r--r--storage/xtradb/ut/ut0auxconf_pause.c32
-rw-r--r--storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c35
-rw-r--r--storage/xtradb/ut/ut0byte.c17
-rw-r--r--storage/xtradb/ut/ut0dbg.c47
-rw-r--r--storage/xtradb/ut/ut0list.c69
-rw-r--r--storage/xtradb/ut/ut0mem.c179
-rw-r--r--storage/xtradb/ut/ut0rnd.c17
-rw-r--r--storage/xtradb/ut/ut0ut.c209
-rw-r--r--storage/xtradb/ut/ut0vec.c23
-rw-r--r--storage/xtradb/ut/ut0wqueue.c34
-rw-r--r--storage/xtradb/win-plugin/README25
-rw-r--r--storage/xtradb/win-plugin/win-plugin.diff297
308 files changed, 36708 insertions, 30179 deletions
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index 5b6268ce10c..38a9700df20 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -1,5 +1,5 @@
-# Copyright (C) 2006 MySQL AB
-#
+# Copyright (C) 2009 Oracle/Innobase Oy
+#
# This program is free 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.
@@ -11,61 +11,91 @@
#
# 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# This is the CMakeLists for InnoDB Plugin
+
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
-ADD_DEFINITIONS(-D_WIN32 -D_LIB -DMYSQL_SERVER)
-# Bug 19424 - InnoDB: Possibly a memory overrun of the buffer being freed (64-bit Visual C)
-# Removing Win64 compiler optimizations for all innodb/mem/* files.
-IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8)
- SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/storage/xtradb/mem/mem0mem.c
- ${CMAKE_SOURCE_DIR}/storage/xtradb/mem/mem0pool.c
- PROPERTIES COMPILE_FLAGS -Od)
-ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8)
+# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
+# CMakeLists.txt still needs to work with previous versions of MySQL.
+IF (MYSQL_VERSION_ID GREATER "50137")
+ INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+ENDIF (MYSQL_VERSION_ID GREATER "50137")
+
+IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
+ SET(WIN64 TRUE)
+ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
+
+ADD_DEFINITIONS(-D_WIN32 -D_LIB -DMYSQL_SERVER)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
- ${CMAKE_SOURCE_DIR}/storage/xtradb/include
- ${CMAKE_SOURCE_DIR}/storage/xtradb/handler
- ${CMAKE_SOURCE_DIR}/sql
- ${CMAKE_SOURCE_DIR}/regex
- ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+# Include directories under innobase
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/xtradb/include
+ ${CMAKE_SOURCE_DIR}/storage/xtradb/handler)
+
+# Include directories under mysql
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/zlib
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include)
-SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
- buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
- data/data0data.c data/data0type.c
- dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c
- dyn/dyn0dyn.c
- eval/eval0eval.c eval/eval0proc.c
- fil/fil0fil.c
- fsp/fsp0fsp.c
- fut/fut0fut.c fut/fut0lst.c
- ha/ha0ha.c ha/hash0hash.c ha/ha0storage.c
- ibuf/ibuf0ibuf.c
- pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
- lock/lock0lock.c lock/lock0iter.c
- log/log0log.c log/log0recv.c
- mach/mach0data.c
- mem/mem0mem.c mem/mem0pool.c
- mtr/mtr0log.c mtr/mtr0mtr.c
- os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c
- page/page0cur.c page/page0page.c page/page0zip.c
- que/que0que.c
- handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc
- read/read0read.c
- rem/rem0cmp.c rem/rem0rec.c
- row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c
- row/row0purge.c row/row0row.c row/row0sel.c row/row0uins.c
- row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
- srv/srv0que.c srv/srv0srv.c srv/srv0start.c
- sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
- thr/thr0loc.c
- trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
- trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
- usr/usr0sess.c
- ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c)
+# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
+# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
+IF (MSVC AND $(WIN64))
+ SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
+ PROPERTIES COMPILE_FLAGS -Od)
+ENDIF (MSVC AND $(WIN64))
-MYSQL_STORAGE_ENGINE(INNOBASE)
+SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
+ buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
+ data/data0data.c data/data0type.c
+ dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c
+ dyn/dyn0dyn.c
+ eval/eval0eval.c eval/eval0proc.c
+ fil/fil0fil.c
+ fsp/fsp0fsp.c
+ fut/fut0fut.c fut/fut0lst.c
+ ha/ha0ha.c ha/hash0hash.c ha/ha0storage.c
+ ibuf/ibuf0ibuf.c
+ pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
+ lock/lock0lock.c lock/lock0iter.c
+ log/log0log.c log/log0recv.c
+ mach/mach0data.c
+ mem/mem0mem.c mem/mem0pool.c
+ mtr/mtr0log.c mtr/mtr0mtr.c
+ os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c
+ page/page0cur.c page/page0page.c page/page0zip.c
+ que/que0que.c
+ handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc
+ read/read0read.c
+ rem/rem0cmp.c rem/rem0rec.c
+ row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c row/row0purge.c row/row0row.c
+ row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
+ srv/srv0que.c srv/srv0srv.c srv/srv0start.c
+ sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
+ thr/thr0loc.c
+ trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
+ trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
+ usr/usr0sess.c
+ ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
+ ut/ut0list.c ut/ut0wqueue.c)
+ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
+IF (MYSQL_VERSION_ID GREATER "50137")
+ MYSQL_STORAGE_ENGINE(INNOBASE)
+ # Use ha_innodb for plugin name, if plugin is built
+ GET_TARGET_PROPERTY(LIB_LOCATION ha_innobase LOCATION)
+ IF(LIB_LOCATION)
+ SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb)
+ ENDIF(LIB_LOCATION)
+ELSE (MYSQL_VERSION_ID GREATER "50137")
+ IF (NOT SOURCE_SUBLIBS)
+ ADD_DEFINITIONS(-D_WIN32 -DMYSQL_SERVER)
+ ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES})
+ # Require mysqld_error.h, which is built as part of the GenError
+ ADD_DEPENDENCIES(innobase GenError)
+ ENDIF (NOT SOURCE_SUBLIBS)
+ENDIF (MYSQL_VERSION_ID GREATER "50137")
diff --git a/storage/xtradb/COPYING.Percona b/storage/xtradb/COPYING.Percona
new file mode 100644
index 00000000000..8c786811719
--- /dev/null
+++ b/storage/xtradb/COPYING.Percona
@@ -0,0 +1,30 @@
+Portions of this software contain modifications contributed by Percona, Inc.
+These contributions are used with the following license:
+
+Copyright (c) 2008, 2009, Percona Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of the Percona Inc. nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/storage/xtradb/COPYING.Sun_Microsystems b/storage/xtradb/COPYING.Sun_Microsystems
new file mode 100644
index 00000000000..5a77ef3ab73
--- /dev/null
+++ b/storage/xtradb/COPYING.Sun_Microsystems
@@ -0,0 +1,31 @@
+Portions of this software contain modifications contributed by
+Sun Microsystems, Inc. These contributions are used with the following
+license:
+
+Copyright (c) 2009, Sun Microsystems, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of Sun Microsystems, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/storage/xtradb/ChangeLog b/storage/xtradb/ChangeLog
index f662b02eea5..1a6e07fd147 100644
--- a/storage/xtradb/ChangeLog
+++ b/storage/xtradb/ChangeLog
@@ -1,3 +1,693 @@
+2009-11-20 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Add a workaround to prevent a crash due to Bug#45961 DDL on
+ partitioned innodb tables leaves data dictionary in an inconsistent
+ state
+
+2009-11-19 The InnoDB Team
+
+ * btr/btr0btr.c:
+ Fix Bug#48469 when innodb tablespace is configured too small, crash
+ and corruption!
+
+2009-11-19 The InnoDB Team
+
+ * data/data0type.c:
+ Fix Bug#48526 Data type for float and double is incorrectly reported
+ in InnoDB table monitor
+
+2009-11-19 The InnoDB Team
+
+ * CMakeLists.txt:
+ Fix Bug#48317 cannot build innodb as static library
+
+2009-11-18 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Fix Bug#48782 On lock wait timeout, CREATE INDEX (creating primary key)
+ attempts DROP TABLE
+
+2009-11-17 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb.result,
+ mysql-test/innodb.test, mysql-test/innodb_bug44369.result,
+ mysql-test/innodb_bug44369.test, mysql-test/patches/innodb-index.diff,
+ row/row0mysql.c:
+ Report duplicate table names to the client connection, not to the
+ error log.
+
+2009-11-12 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/db0err.h, row/row0merge.c,
+ row/row0mysql.c:
+ Allow CREATE INDEX to be interrupted.
+ Also, when CHECK TABLE is interrupted, report ER_QUERY_INTERRUPTED.
+
+2009-11-11 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug47167.result,
+ mysql-test/innodb_bug47167.test, mysql-test/innodb_file_format.result:
+ Fix Bug#47167 "set global innodb_file_format_check" cannot set value
+ by User-Defined Variable
+
+2009-11-11 The InnoDB Team
+
+ * include/os0file.h, os/os0file.c:
+ Fix Bug#3139 Mysql crashes: 'windows error 995' after several selects
+ on a large DB
+
+2009-11-04 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#32430 'show innodb status' causes errors
+ Invalid (old?) table or database name in logs
+
+2009-11-02 The InnoDB Team
+
+ * btr/btr0sea.c, buf/buf0buf.c, dict/dict0dict.c, fil/fil0fil.c,
+ ibuf/ibuf0ibuf.c, include/btr0sea.h, include/dict0dict.h,
+ include/fil0fil.h, include/ibuf0ibuf.h, include/lock0lock.h,
+ include/log0log.h, include/log0recv.h, include/mem0mem.h,
+ include/mem0pool.h, include/os0file.h, include/pars0pars.h,
+ include/srv0srv.h, include/thr0loc.h, include/trx0i_s.h,
+ include/trx0purge.h, include/trx0rseg.h, include/trx0sys.h,
+ include/trx0undo.h, include/usr0sess.h, lock/lock0lock.c,
+ log/log0log.c, log/log0recv.c, mem/mem0dbg.c, mem/mem0pool.c,
+ os/os0file.c, os/os0sync.c, os/os0thread.c, pars/lexyy.c,
+ pars/pars0lex.l, que/que0que.c, srv/srv0srv.c, srv/srv0start.c,
+ sync/sync0arr.c, sync/sync0sync.c, thr/thr0loc.c, trx/trx0i_s.c,
+ trx/trx0purge.c, trx/trx0rseg.c, trx/trx0sys.c, trx/trx0undo.c,
+ usr/usr0sess.c, ut/ut0mem.c:
+ Fix Bug #45992 innodb memory not freed after shutdown
+ Fix Bug #46656 InnoDB plugin: memory leaks (Valgrind)
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
+ mysql-test/innodb-autoinc.test:
+ Fix Bug#47125 auto_increment start value is ignored if an index is
+ created and engine=innodb
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug47777.result,
+ mysql-test/innodb_bug47777.test:
+ Fix Bug#47777 innodb dies with spatial pk: Failing assertion: buf <=
+ original_buf + buf_len
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#38996 Race condition in ANALYZE TABLE
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix bug#42383: Can't create table 'test.bug39438'
+
+2009-10-29 The InnoDB Team
+
+ * os/os0proc.c:
+ Fix Bug#48237 Error handling in os_mem_alloc_large appears to
+ be incorrect
+
+2009-10-29 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0lru.c, include/buf0buf.h, include/buf0buf.ic:
+ Fix corruption of the buf_pool->LRU_old list and improve debug
+ assertions.
+
+2009-10-28 The InnoDB Team
+
+ * srv/srv0start.c:
+ Fix Bug#41490 After enlargement of InnoDB page size, the error message
+ become inaccurate
+
+2009-10-26 The InnoDB Team
+
+ * row/row0ins.c:
+ When allocating a data tuple, zero out the system fields in order
+ to avoid Valgrind warnings about uninitialized fields in
+ dtuple_validate().
+
+2009-10-22 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-zip.result,
+ mysql-test/innodb-zip.test, mysql-test/innodb_bug44369.result,
+ mysql-test/innodb_bug44369.test:
+ Fix Bug#47233 Innodb calls push_warning(MYSQL_ERROR::WARN_LEVEL_ERROR)
+
+2009-10-19 The InnoDB Team
+
+ * mysql-test/innodb_information_schema.test:
+ Fix Bug#47808 innodb_information_schema.test fails when run under
+ valgrind
+
+2009-10-15 The InnoDB Team
+
+ * include/page0page.ic:
+ Fix Bug#47058 Failure to compile innodb_plugin on solaris 10u7 + spro
+ cc/CC 5.10
+
+2009-10-13 The InnoDB Team
+
+ * buf/buf0flu.c:
+ Call fsync() on datafiles after a batch of pages is written to disk
+ even when skip_innodb_doublewrite is set.
+
+2009-10-05 The InnoDB Team
+
+ * buf/buf0buf.c:
+ Do not invalidate buffer pool while an LRU batch is active. Added code
+ to buf_pool_invalidate() to wait for the running batches to finish.
+
+2009-10-01 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#47763 typo in error message: Failed to open table %s after %lu
+ attemtps.
+
+2009-10-01 The InnoDB Team
+
+ * fsp/fsp0fsp.c, row/row0merge.c:
+ Clean up after a crash during DROP INDEX. When InnoDB crashes
+ while dropping an index, ensure that the index will be completely
+ dropped during crash recovery. The MySQL .frm file may still
+ contain the dropped index, but there is little that we can do
+ about it.
+
+2009-09-28 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ When a secondary index exists in the MySQL .frm file but not in
+ the InnoDB data dictionary, return an error instead of letting an
+ assertion fail in index_read.
+
+2009-09-28 The InnoDB Team
+
+ * btr/btr0btr.c, buf/buf0buf.c, include/page0page.h,
+ include/page0zip.h, page/page0cur.c, page/page0page.c,
+ page/page0zip.c:
+ Do not write to PAGE_INDEX_ID when restoring an uncompressed page
+ after a compression failure. The field should only be written
+ when creating a B-tree page. This fix addresses a race condition
+ in a debug assertion.
+
+2009-09-28 The InnoDB Team
+
+ * fil/fil0fil.c:
+ Try to prevent the reuse of tablespace identifiers after InnoDB
+ has crashed during table creation. Also, refuse to start if files
+ with duplicate tablespace identifiers are encountered.
+
+2009-09-25 The InnoDB Team
+
+ * include/os0file.h, os/os0file.c:
+ Fix Bug#47055 unconditional exit(1) on ERROR_WORKING_SET_QUOTA
+ 1453 (0x5AD) for InnoDB backend
+
+2009-09-19 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-consistent-master.opt,
+ mysql-test/innodb-consistent.result,
+ mysql-test/innodb-consistent.test:
+ Fix Bug#37232 Innodb might get too many read locks for DML with
+ repeatable-read
+
+2009-09-19 The InnoDB Team
+
+ * fsp/fsp0fsp.c:
+ Fix Bug#31183 Tablespace full problems not reported in error log,
+ error message unclear
+
+2009-09-17 The InnoDB Team
+
+ * mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
+ Make the test pass with zlib 1.2.3.3. Apparently, the definition
+ of compressBound() has changed between zlib versions, and the
+ maximum record size of a table with 1K compressed page size has
+ been reduced by one byte. This is an arbitrary test. In practical
+ applications, for good write performance, the compressed page size
+ should be chosen to be bigger than the absolute minimum.
+
+2009-09-16 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#46256 drop table with unknown collation crashes innodb
+
+2009-09-16 The InnoDB Team
+
+ * dict/dict0dict.c, handler/ha_innodb.cc,
+ mysql-test/innodb_bug44369.result, mysql-test/innodb_bug44369.test,
+ row/row0mysql.c:
+ Fix Bug#44369 InnoDB: Does not uniformly disallow disallowed column
+ names
+
+2009-09-16 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/db0err.h,
+ mysql-test/innodb_bug46000.result, mysql-test/innodb_bug46000.test:
+ Fix Bug#46000 using index called GEN_CLUST_INDEX crashes server
+
+2009-09-02 The InnoDB Team
+
+ * include/lock0lock.h, include/row0mysql.h, lock/lock0lock.c,
+ row/row0mysql.c:
+ Fix a regression introduced by the fix for MySQL bug#26316. We check
+ whether a transaction holds any AUTOINC locks before we acquire
+ the kernel mutex and release those locks.
+
+2009-08-27 The InnoDB Team
+
+ * dict/dict0dict.c, include/dict0dict.h,
+ mysql-test/innodb_bug44571.result, mysql-test/innodb_bug44571.test:
+ Fix Bug#44571 InnoDB Plugin crashes on ADD INDEX
+
+2009-08-27 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix a bug in the merge sort that can corrupt indexes in fast index
+ creation. Add some consistency checks. Check that the number of
+ records remains constant in every merge sort pass.
+
+2009-08-27 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
+ include/buf0buf.h, include/buf0buf.ic, include/buf0lru.h,
+ include/ut0ut.h, ut/ut0ut.c:
+ Make it possible to tune the buffer pool LRU eviction policy to be
+ more resistant against index scans. Introduce the settable global
+ variables innodb_old_blocks_pct and innodb_old_blocks_time for
+ controlling the buffer pool eviction policy. The parameter
+ innodb_old_blocks_pct (5..95) controls the desired amount of "old"
+ blocks in the LRU list. The default is 37, corresponding to the
+ old fixed ratio of 3/8. Each time a block is accessed, it will be
+ moved to the "new" blocks if its first access was at least
+ innodb_old_blocks_time milliseconds ago (default 0, meaning every
+ block). The idea is that in index scans, blocks will be accessed
+ a few times within innodb_old_blocks_time, and they will remain in
+ the "old" section of the LRU list. Thus, when innodb_old_blocks_time
+ is nonzero, blocks retrieved for one-time index scans will be more
+ likely candidates for eviction than blocks that are accessed in
+ random patterns.
+
+2009-08-26 The InnoDB Team
+
+ * handler/ha_innodb.cc, os/os0file.c:
+ Fix Bug#42885 buf_read_ahead_random, buf_read_ahead_linear counters,
+ thread wakeups
+
+2009-08-20 The InnoDB Team
+
+ * lock/lock0lock.c:
+ Fix Bug#46650 Innodb assertion autoinc_lock == lock in
+ lock_table_remove_low on INSERT SELECT
+
+2009-08-13 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Fix Bug#46657 InnoDB plugin: invalid read in index_merge_innodb test
+ (Valgrind)
+
+2009-08-11 The InnoDB Team
+
+ InnoDB Plugin 1.0.4 released
+
+2009-07-20 The InnoDB Team
+
+ * buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
+ srv/srv0srv.c:
+ Change the read ahead parameter name to innodb_read_ahead_threshold.
+ Change the meaning of this parameter to signify the number of pages
+ that must be sequentially accessed for InnoDB to trigger a readahead
+ request.
+
+2009-07-20 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#39802 On Windows, 32-bit time_t should be enforced
+
+2009-07-16 The InnoDB Team
+
+ * include/univ.i:
+ Support inlining of functions and prefetch with Sun Studio.
+ These changes are based on contribution from Sun Microsystems Inc.
+ under a BSD license.
+
+2009-07-14 The InnoDB Team
+
+ * fil/fil0fil.c:
+ Fix Bug#45814 URL reference in InnoDB server errors needs adjusting to
+ match documentation
+
+2009-07-14 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug21704.result,
+ mysql-test/innodb_bug21704.test:
+ Fix Bug#21704 Renaming column does not update FK definition
+
+2009-07-10 The InnoDB Team
+
+ * handler/ha_innodb.cc, srv/srv0srv.c:
+ Change the defaults for
+ innodb_sync_spin_loops: 20 -> 30
+ innodb_spin_wait_delay: 5 -> 6
+
+2009-07-08 The InnoDB Team
+
+ * buf/buf0flu.c, handler/ha_innodb.cc, include/buf0flu.h,
+ include/log0log.h, include/log0log.ic, include/srv0srv.h,
+ srv/srv0srv.c:
+ Implement the adaptive flushing of dirty pages, which uses
+ a heuristics based flushing rate of dirty pages to avoid IO
+ bursts at checkpoint. Expose new configure knob
+ innodb_adaptive_flushing to control whether the new flushing
+ algorithm should be used.
+
+2009-07-07 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/srv0srv.h, log/log0log.c,
+ srv/srv0srv.c:
+ Implement IO capacity tuning. Expose new configure knob
+ innodb_io_capacity to control the master threads IO rate. The
+ ibuf merge is also changed from synchronous to asynchronous.
+ These changes are based on contribution from Google Inc.
+ under a BSD license.
+
+2009-07-02 The InnoDB Team
+
+ * include/ut0ut.h, plug.in, ut/ut0ut.c:
+ Use the PAUSE instruction inside the spinloop if it is available,
+ Thanks to Mikael Ronstrom <mikael@mysql.com>.
+
+2009-06-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_file_format.test,
+ mysql-test/innodb_file_format.result:
+ Do not crash on SET GLOBAL innodb_file_format=DEFAULT
+ or SET GLOBAL innodb_file_format_check=DEFAULT.
+
+2009-06-29 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0rea.c, lock/lock0lock.c:
+ Tolerate missing tablespaces during crash recovery and when
+ printing information on locks.
+
+2009-06-29 The InnoDB Team
+
+ * buf/buf0buf.c:
+ Fix a race condition when reading buf_fix_count.
+ Currently, it is not being protected by the buffer pool mutex,
+ but by the block mutex.
+
+2009-06-29 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Start the user transaction prebuilt->trx if it was not started
+ before adding or dropping an index. Without this fix, the
+ table could be locked outside an active transaction.
+
+2009-06-25 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug42101.test,
+ mysql-test/innodb_bug42101.result,
+ mysql-test/innodb_bug42101-nonzero.test,
+ mysql-test/innodb_bug42101-nonzero.result:
+ Fix Bug#45749 Race condition in SET GLOBAL
+ innodb_commit_concurrency=DEFAULT
+
+2009-06-25 The InnoDB Team
+
+ * dict/dict0dict.c:
+ When an index column cannot be found in the table during index
+ creation, display additional diagnostic before an assertion failure.
+ This does NOT fix Bug #44571 InnoDB Plugin crashes on ADD INDEX,
+ but it helps understand the reason of the crash.
+
+2009-06-17 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix Bug#45426 UNIV_DEBUG build cause assertion error at CREATE INDEX
+
+2009-06-17 The InnoDB Team
+
+ * mysql-test/innodb_bug45357.result, mysql-test/innodb_bug45357.test,
+ row/row0mysql.c:
+ Fix Bug#45357 5.1.35 crashes with Failing assertion: index->type &
+ DICT_CLUSTERED
+
+2009-06-17 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
+ mysql-test/innodb-autoinc.test:
+ Fix Bug#44030 Error: (1500) Couldn't read the MAX(ID) autoinc value
+ from the index (PRIMARY)
+
+2009-06-11 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb.result, srv/srv0srv.c:
+ Change the following defaults:
+ max_dirty_pages_pct: from 90 to 75, max allowed from 100 to 99
+ additional_mem_pool_size: from 1 to 8 MB
+ buffer_pool_size: from 8 to 128 MB
+ log_buffer_size: from 1 to 8 MB
+ read_io_threads/write_io_threads: from 1 to 4
+
+2009-06-09 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/trx0trx.h, trx/trx0trx.c:
+ Enable Group Commit functionality that was broken in 5.0 when
+ distributed transactions were introduced.
+
+2009-06-05 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/os0file.h, include/srv0srv.h,
+ os/os0file.c, srv/srv0srv.c, srv/srv0start.c:
+ Enable functionality to have multiple background IO helper threads.
+ Expose new configure knobs innodb_read_io_threads and
+ innodb_write_io_threads and deprecate innodb_file_io_threads (this
+ parameter was relevant only on windows). Internally this allows
+ multiple segments for read and write IO request arrays where one
+ thread works on one segment.
+
+2009-06-05 The InnoDB Team
+
+ * buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
+ include/srv0srv.h, srv/srv0srv.c:
+ Fix a bug in linear read ahead:
+ 1) Take into account access pattern when deciding whether or not to
+ do linear read ahead.
+ 2) Expose a knob innodb_read_ahead_factor = [0-64] default (8),
+ dynamic, global to control linear read ahead behavior. This is the
+ value of the number of pages that InnoDB will tolerate within a
+ 64 page extent even if they are accessed out of order or have
+ not been accessed at all. This number (which varies from 0 to 64)
+ is indicative of the slack that we have when deciding about linear
+ readahead.
+ 3) Disable random read ahead. Keep the code for now.
+
+2009-06-03 The InnoDB Team
+
+ * dict/dict0dict.c, mysql-test/t/innodb_mysql.test,
+ mysql-test/r/innodb_mysql.result:
+ Fix Bug#39793 Foreign keys not constructed when column
+ has a '#' in a comment or default value
+
+2009-05-27 The InnoDB Team
+
+ * Doxyfile:
+ Allow the extraction of documentation from the code base with the
+ Doxygen tool. Convert and add many (but not yet all) comments to
+ Doxygen format.
+
+2009-05-19 The InnoDB Team
+
+ * btr/btr0btr.c, btr/btr0cur.c, lock/lock0lock.c,
+ include/page0page.ic, include/lock0lock.h, include/dict0dict.h,
+ include/page0page.h, include/dict0dict.ic, ibuf/ibuf0ibuf.c,
+ page/page0zip.c, page/page0page.c:
+ Write updates of PAGE_MAX_TRX_ID to the redo log and add debug
+ assertions for checking that PAGE_MAX_TRX_ID is valid on leaf
+ pages of secondary indexes and the insert buffer B-tree. This bug
+ could cause failures in secondary index lookups in consistent
+ reads right after crash recovery.
+
+2009-05-18 The InnoDB Team
+
+ * btr/btr0cur.c:
+ Correctly estimate the space needed on the compressed page when
+ performing an update by delete-and-insert.
+
+2009-05-14 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/srv0srv.h,
+ mysql-test/innodb_bug42101-nonzero-master.opt,
+ mysql-test/innodb_bug42101-nonzero.result,
+ mysql-test/innodb_bug42101-nonzero.test,
+ mysql-test/innodb_bug42101.result, mysql-test/innodb_bug42101.test,
+ srv/srv0srv.c:
+ Fix Bug#42101 Race condition in innodb_commit_concurrency
+
+2009-05-13 The InnoDB Team
+
+ * dict/dict0dict.c:
+ Fix Bug#44320 InnoDB: missing DB_ROLL_PTR in Table Monitor COLUMNS
+ output
+
+2009-04-23 The InnoDB Team
+
+ * row/row0mysql.c:
+ When scanning indexes, report in the error log any error codes
+ returned by the search function. These error codes will still be
+ ignored in CHECK TABLE.
+
+2009-04-23 The InnoDB Team
+
+ * include/trx0types.h:
+ Define the logical type names trx_id_t, roll_ptr_t, and undo_no_t
+ and use them in place of dulint everywhere.
+
+2009-04-18 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/pars0pars.h:
+ Fix Bug#29125 Windows Server X64: so many compiler warnings
+
+2009-04-16 The InnoDB Team
+
+ * include/univ.i:
+ Define REFMAN as the base URL of the MySQL Reference Manual and
+ use the macro in all diagnostic output.
+
+2009-04-16 The InnoDB Team
+
+ * CMakeLists.txt, include/os0sync.h, include/sync0sync.h,
+ include/sync0sync.ic, include/univ.i, srv/srv0start.c,
+ sync/sync0sync.c:
+ Use the Windows Interlocked functions for atomic memory
+ access.
+
+2009-04-15 The InnoDB Team
+
+ * mysql-test/innodb.result, mysql-test/innodb.test:
+ Fix Bug#43309 Test main.innodb can't be run twice
+
+2009-04-14 The InnoDB Team
+
+ * CMakeLists.txt, handler/win_delay_loader.cc,
+ win-plugin/win-plugin.diff:
+ Remove statically linked libraries from MySQL (zlib and strings).
+
+2009-04-11 The InnoDB Team
+
+ * CMakeLists.txt, win-plugin/README, win-plugin/win-plugin.diff:
+ Rewrite CMakeLists.txt.
+
+2009-04-07 The InnoDB Team
+
+ * include/os0sync.h, include/sync0rw.ic, include/sync0sync.h,
+ include/sync0sync.ic, include/univ.i, plug.in, srv/srv0srv.c,
+ srv/srv0start.c, sync/sync0arr.c, sync/sync0sync.c:
+ Enable atomics on Solaris (using the libc functions as defined in
+ atomic.h) if GCC atomic builtins are not present.
+
+2009-04-07 The InnoDB Team
+
+ * btr/btr0btr.c, dict/dict0dict.c, ibuf/ibuf0ibuf.c,
+ include/data0data.h, include/data0data.ic, include/data0type.h,
+ include/data0type.ic, include/dict0dict.h, include/dict0dict.ic,
+ include/rem0rec.ic, mysql-test/innodb.result, mysql-test/innodb.test,
+ pars/pars0pars.c, rem/rem0rec.c, row/row0upd.c:
+ Fix Bug#44032 In ROW_FORMAT=REDUNDANT, update UTF-8 CHAR
+ to/from NULL is not in-place
+
+2009-04-07 The InnoDB Team
+
+ * page/page0cur.c:
+ Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for
+ indexes of InnoDB table
+
+2009-04-06 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Make the parameter innodb_change_buffering settable by the
+ configuration file or mysqld command line options. Before this
+ fix, the initial value specified for this parameter was ignored.
+
+2009-04-06 The InnoDB Team
+
+ * sync/sync0rw.c:
+ Avoid a bogus failure in UNIV_SYNC_DEBUG diagnostics.
+
+2009-04-02 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/srv0srv.h, srv/srv0srv.c:
+ Add new parameter innodb_spin_wait_delay to set the maximum delay
+ between polling for a spin lock.
+
+2009-04-02 The InnoDB Team
+
+ * dict/dict0crea.c, handler/ha_innodb.cc, handler/ha_innodb.h,
+ include/dict0mem.h, include/row0merge.h, include/row0mysql.h,
+ mysql-test/innodb-index.result, mysql-test/innodb-index.test,
+ row/row0merge.c, row/row0sel.c:
+ In consistent reads, refuse to use newly created indexes that may
+ lack history.
+
+2009-03-25 The InnoDB Team
+
+ * buf/buf0buf.c, handler/ha_innodb.cc, include/buf0buf.h:
+ In SHOW ENGINE INNODB MUTEX do not show the status of block->mutex,
+ block->lock, block->lock->mutex (if applicable) and all mutexes and
+ rw-locks for which number of os-waits are zero because this can
+ be overwhelming particularly when the buffer pool is very large.
+
+2009-03-20 The InnoDB Team
+
+ * buf/buf0buf.c, include/log0recv.h, log/log0recv.c:
+ Remove the compile-time constant parameters of
+ recv_recover_page(), recv_scan_log_recs(), and recv_sys_init().
+
+2009-03-20 The InnoDB Team
+
+ * data/data0type.c, handler/ha_innodb.cc, include/ha_prototypes.h:
+ Declare innobase_get_at_most_n_mbchars() in ha_prototypes.h.
+
+2009-03-20 The InnoDB Team
+
+ * fil/fil0fil.h, fil/fil0fil.c, srv/srv0start.c:
+ Add the parameter hash_size to fil_init().
+
+2009-03-20 The InnoDB Team
+
+ * fil/fil0fil.c:
+ Refer to fil_system directly, not via local variables.
+
+2009-03-20 The InnoDB Team
+
+ * page/page0page.c:
+ In page_validate(), always report the space id, page number and
+ the name of the index when corruption is noticed.
+
+2009-03-20 The InnoDB Team
+
+ * include/log0log.h, include/log0log.ic, log/log0log.c:
+ Add in/out comments or const qualifiers to some function
+ parameters as appropriate.
+
+2009-03-20 The InnoDB Team
+
+ * dict/dict0boot.c, dict/dict0dict.c, fsp/fsp0fsp.c,
+ include/dict0dict.h, include/srv0srv.h, srv/srv0srv.c,
+ page/page0page.c:
+ Replace srv_sys->dummy_ind1 and srv_sys->dummy_ind2 with
+ dict_ind_redundant and dict_ind_compact, which are
+ initialized by dict_init().
+
+2009-03-11 The InnoDB Team
+
+ InnoDB Plugin 1.0.3 released
+
2009-03-05 The InnoDB Team
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
diff --git a/storage/xtradb/Doxyfile b/storage/xtradb/Doxyfile
new file mode 100644
index 00000000000..62aa7dd8abc
--- /dev/null
+++ b/storage/xtradb/Doxyfile
@@ -0,0 +1,1419 @@
+# Doxyfile 1.5.6
+
+# Usage: SVNVERSION=-r$(svnversion) doxygen
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "InnoDB Plugin"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.0$(SVNVERSION)
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = dox
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = . include/univ.i
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = *.c *.ic *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE = ut0auxconf_*
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature. Other possible values
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hiererachy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = DOXYGEN UNIV_DEBUG UNIV_SYNC_DEBUG __attribute__()=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED = UT_LIST_BASE_NODE_T UT_LIST_NODE_T
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = NO
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 3
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is enabled by default, which results in a transparent
+# background. Warning: Depending on the platform used, enabling this option
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they
+# become hard to read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/storage/xtradb/Makefile.am b/storage/xtradb/Makefile.am
index 3b5826f33e6..53413dfaeb8 100644
--- a/storage/xtradb/Makefile.am
+++ b/storage/xtradb/Makefile.am
@@ -22,160 +22,307 @@ MYSQLLIBdir= $(pkglibdir)
pkgplugindir= $(pkglibdir)/plugin
INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
-I$(top_srcdir)/regex \
- -I$(top_srcdir)/storage/xtradb/include \
+ -I$(srcdir)/include \
-I$(top_srcdir)/sql \
- -I$(srcdir)
+ -I$(srcdir) @ZLIB_INCLUDES@
DEFS= @DEFS@
-noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \
- include/btr0cur.h include/btr0cur.ic \
- include/btr0pcur.h include/btr0pcur.ic \
- include/btr0sea.h include/btr0sea.ic \
- include/btr0types.h include/buf0buddy.h \
- include/buf0buddy.ic include/buf0buf.h \
- include/buf0buf.ic include/buf0flu.h \
- include/buf0flu.ic include/buf0lru.h \
- include/buf0lru.ic include/buf0rea.h \
- include/buf0types.h include/data0data.h \
- include/data0data.ic include/data0type.h \
- include/data0type.ic include/data0types.h \
- include/db0err.h include/dict0boot.h \
- include/dict0boot.ic include/dict0crea.h \
- include/dict0crea.ic include/dict0dict.h \
- include/dict0dict.ic include/dict0load.h \
- include/dict0load.ic include/dict0mem.h \
- include/dict0mem.ic include/dict0types.h \
- include/dyn0dyn.h include/dyn0dyn.ic \
- include/eval0eval.h include/eval0eval.ic \
- include/eval0proc.h include/eval0proc.ic \
- include/fil0fil.h include/fsp0fsp.h \
- include/fsp0fsp.ic include/fut0fut.h \
- include/fut0fut.ic include/fut0lst.h \
- include/fut0lst.ic include/ha0ha.h \
- include/ha0ha.ic \
- include/ha0storage.h \
- include/ha0storage.ic \
- include/hash0hash.h \
- include/hash0hash.ic include/ibuf0ibuf.h \
- include/ibuf0ibuf.ic include/ibuf0types.h \
- include/lock0iter.h \
- include/lock0lock.h include/lock0lock.ic \
- include/lock0priv.h include/lock0priv.ic \
- include/lock0types.h include/log0log.h \
- include/log0log.ic include/log0recv.h \
- include/log0recv.ic include/mach0data.h \
- include/mach0data.ic include/mem0dbg.h \
- include/mem0dbg.ic mem/mem0dbg.c \
- include/mem0mem.h include/mem0mem.ic \
- include/mem0pool.h include/mem0pool.ic \
- include/mtr0log.h include/mtr0log.ic \
- include/mtr0mtr.h include/mtr0mtr.ic \
- include/mtr0types.h \
- include/mysql_addons.h \
- include/os0file.h \
- include/os0proc.h include/os0proc.ic \
- include/os0sync.h include/os0sync.ic \
- include/os0thread.h include/os0thread.ic \
- include/page0cur.h include/page0cur.ic \
- include/page0page.h include/page0page.ic \
- include/page0zip.h include/page0zip.ic \
- include/page0types.h include/pars0grm.h \
- include/pars0opt.h include/pars0opt.ic \
- include/pars0pars.h include/pars0pars.ic \
- include/pars0sym.h include/pars0sym.ic \
- include/pars0types.h include/que0que.h \
- include/que0que.ic include/que0types.h \
- include/read0read.h include/read0read.ic \
- include/read0types.h include/rem0cmp.h \
- include/rem0cmp.ic include/rem0rec.h \
- include/rem0rec.ic include/rem0types.h \
- include/row0ext.h include/row0ext.ic \
- include/row0ins.h include/row0ins.ic \
- include/row0merge.h \
- include/row0mysql.h include/row0mysql.ic \
- include/row0purge.h include/row0purge.ic \
- include/row0row.h include/row0row.ic \
- include/row0sel.h include/row0sel.ic \
- include/row0types.h include/row0uins.h \
- include/row0uins.ic include/row0umod.h \
- include/row0umod.ic include/row0undo.h \
- include/row0undo.ic include/row0upd.h \
- include/row0upd.ic include/row0vers.h \
- include/row0vers.ic include/srv0que.h \
- include/srv0srv.h include/srv0srv.ic \
- include/srv0start.h include/sync0arr.h \
- include/sync0arr.ic include/sync0rw.h \
- include/sync0rw.ic include/sync0sync.h \
- include/sync0sync.ic include/sync0types.h \
- include/thr0loc.h include/thr0loc.ic \
- include/trx0i_s.h \
- include/trx0purge.h include/trx0purge.ic \
- include/trx0rec.h include/trx0rec.ic \
- include/trx0roll.h include/trx0roll.ic \
- include/trx0rseg.h include/trx0rseg.ic \
- include/trx0sys.h include/trx0sys.ic \
- include/trx0trx.h include/trx0trx.ic \
- include/trx0types.h include/trx0undo.h \
- include/trx0undo.ic include/trx0xa.h \
- include/univ.i include/usr0sess.h \
- include/usr0sess.ic include/usr0types.h \
- include/ut0byte.h include/ut0byte.ic \
- include/ut0dbg.h include/ut0lst.h \
- include/ut0mem.h include/ut0mem.ic \
- include/ut0rnd.h include/ut0rnd.ic \
- include/ut0sort.h include/ut0ut.h \
- include/ut0ut.ic include/ut0vec.h \
- include/ut0vec.ic include/ut0list.h \
- include/ut0list.ic include/ut0wqueue.h \
- include/ha_prototypes.h handler/ha_innodb.h \
- include/handler0alter.h \
- handler/i_s.h handler/innodb_patch_info.h \
- handler/handler0vars.h
+noinst_HEADERS= \
+ handler/ha_innodb.h \
+ handler/i_s.h \
+ include/btr0btr.h \
+ include/btr0btr.ic \
+ include/btr0cur.h \
+ include/btr0cur.ic \
+ include/btr0pcur.h \
+ include/btr0pcur.ic \
+ include/btr0sea.h \
+ include/btr0sea.ic \
+ include/btr0types.h \
+ include/buf0buddy.h \
+ include/buf0buddy.ic \
+ include/buf0buf.h \
+ include/buf0buf.ic \
+ include/buf0flu.h \
+ include/buf0flu.ic \
+ include/buf0lru.h \
+ include/buf0lru.ic \
+ include/buf0rea.h \
+ include/buf0types.h \
+ include/data0data.h \
+ include/data0data.ic \
+ include/data0type.h \
+ include/data0type.ic \
+ include/data0types.h \
+ include/db0err.h \
+ include/dict0boot.h \
+ include/dict0boot.ic \
+ include/dict0crea.h \
+ include/dict0crea.ic \
+ include/dict0dict.h \
+ include/dict0dict.ic \
+ include/dict0load.h \
+ include/dict0load.ic \
+ include/dict0mem.h \
+ include/dict0mem.ic \
+ include/dict0types.h \
+ include/dyn0dyn.h \
+ include/dyn0dyn.ic \
+ include/eval0eval.h \
+ include/eval0eval.ic \
+ include/eval0proc.h \
+ include/eval0proc.ic \
+ include/fil0fil.h \
+ include/fsp0fsp.h \
+ include/fsp0fsp.ic \
+ include/fsp0types.h \
+ include/fut0fut.h \
+ include/fut0fut.ic \
+ include/fut0lst.h \
+ include/fut0lst.ic \
+ include/ha0ha.h \
+ include/ha0ha.ic \
+ include/ha0storage.h \
+ include/ha0storage.ic \
+ include/ha_prototypes.h \
+ include/handler0alter.h \
+ include/hash0hash.h \
+ include/hash0hash.ic \
+ include/ibuf0ibuf.h \
+ include/ibuf0ibuf.ic \
+ include/ibuf0types.h \
+ include/lock0iter.h \
+ include/lock0lock.h \
+ include/lock0lock.ic \
+ include/lock0priv.h \
+ include/lock0priv.ic \
+ include/lock0types.h \
+ include/log0log.h \
+ include/log0log.ic \
+ include/log0recv.h \
+ include/log0recv.ic \
+ include/mach0data.h \
+ include/mach0data.ic \
+ include/mem0dbg.h \
+ include/mem0dbg.ic \
+ include/mem0mem.h \
+ include/mem0mem.ic \
+ include/mem0pool.h \
+ include/mem0pool.ic \
+ include/mtr0log.h \
+ include/mtr0log.ic \
+ include/mtr0mtr.h \
+ include/mtr0mtr.ic \
+ include/mtr0types.h \
+ include/mysql_addons.h \
+ include/os0file.h \
+ include/os0proc.h \
+ include/os0proc.ic \
+ include/os0sync.h \
+ include/os0sync.ic \
+ include/os0thread.h \
+ include/os0thread.ic \
+ include/page0cur.h \
+ include/page0cur.ic \
+ include/page0page.h \
+ include/page0page.ic \
+ include/page0types.h \
+ include/page0zip.h \
+ include/page0zip.ic \
+ include/pars0grm.h \
+ include/pars0opt.h \
+ include/pars0opt.ic \
+ include/pars0pars.h \
+ include/pars0pars.ic \
+ include/pars0sym.h \
+ include/pars0sym.ic \
+ include/pars0types.h \
+ include/que0que.h \
+ include/que0que.ic \
+ include/que0types.h \
+ include/read0read.h \
+ include/read0read.ic \
+ include/read0types.h \
+ include/rem0cmp.h \
+ include/rem0cmp.ic \
+ include/rem0rec.h \
+ include/rem0rec.ic \
+ include/rem0types.h \
+ include/row0ext.h \
+ include/row0ext.ic \
+ include/row0ins.h \
+ include/row0ins.ic \
+ include/row0merge.h \
+ include/row0mysql.h \
+ include/row0mysql.ic \
+ include/row0purge.h \
+ include/row0purge.ic \
+ include/row0row.h \
+ include/row0row.ic \
+ include/row0sel.h \
+ include/row0sel.ic \
+ include/row0types.h \
+ include/row0uins.h \
+ include/row0uins.ic \
+ include/row0umod.h \
+ include/row0umod.ic \
+ include/row0undo.h \
+ include/row0undo.ic \
+ include/row0upd.h \
+ include/row0upd.ic \
+ include/row0vers.h \
+ include/row0vers.ic \
+ include/srv0que.h \
+ include/srv0srv.h \
+ include/srv0srv.ic \
+ include/srv0start.h \
+ include/sync0arr.h \
+ include/sync0arr.ic \
+ include/sync0rw.h \
+ include/sync0rw.ic \
+ include/sync0sync.h \
+ include/sync0sync.ic \
+ include/sync0types.h \
+ include/thr0loc.h \
+ include/thr0loc.ic \
+ include/trx0i_s.h \
+ include/trx0purge.h \
+ include/trx0purge.ic \
+ include/trx0rec.h \
+ include/trx0rec.ic \
+ include/trx0roll.h \
+ include/trx0roll.ic \
+ include/trx0rseg.h \
+ include/trx0rseg.ic \
+ include/trx0sys.h \
+ include/trx0sys.ic \
+ include/trx0trx.h \
+ include/trx0trx.ic \
+ include/trx0types.h \
+ include/trx0undo.h \
+ include/trx0undo.ic \
+ include/trx0xa.h \
+ include/univ.i \
+ include/usr0sess.h \
+ include/usr0sess.ic \
+ include/usr0types.h \
+ include/ut0auxconf.h \
+ include/ut0byte.h \
+ include/ut0byte.ic \
+ include/ut0dbg.h \
+ include/ut0list.h \
+ include/ut0list.ic \
+ include/ut0lst.h \
+ include/ut0mem.h \
+ include/ut0mem.ic \
+ include/ut0rnd.h \
+ include/ut0rnd.ic \
+ include/ut0sort.h \
+ include/ut0ut.h \
+ include/ut0ut.ic \
+ include/ut0vec.h \
+ include/ut0vec.ic \
+ include/ut0wqueue.h \
+ handler/innodb_patch_info.h \
+ mem/mem0dbg.c
EXTRA_LIBRARIES= libinnobase.a
noinst_LIBRARIES= @plugin_innobase_static_target@
-libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
- btr/btr0sea.c buf/buf0buddy.c \
- buf/buf0buf.c buf/buf0flu.c \
- buf/buf0lru.c buf/buf0rea.c data/data0data.c \
- data/data0type.c dict/dict0boot.c \
- dict/dict0crea.c dict/dict0dict.c \
- dict/dict0load.c dict/dict0mem.c dyn/dyn0dyn.c \
- eval/eval0eval.c eval/eval0proc.c \
- fil/fil0fil.c fsp/fsp0fsp.c fut/fut0fut.c \
- fut/fut0lst.c ha/ha0ha.c \
- ha/ha0storage.c \
- ha/hash0hash.c \
- ibuf/ibuf0ibuf.c lock/lock0iter.c \
- lock/lock0lock.c \
- log/log0log.c log/log0recv.c mach/mach0data.c \
- mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c \
- mtr/mtr0mtr.c os/os0file.c os/os0proc.c \
- os/os0sync.c os/os0thread.c page/page0cur.c \
- page/page0page.c page/page0zip.c \
- pars/lexyy.c pars/pars0grm.c \
- pars/pars0opt.c pars/pars0pars.c \
- pars/pars0sym.c que/que0que.c read/read0read.c \
- rem/rem0cmp.c rem/rem0rec.c row/row0ext.c \
- row/row0ins.c row/row0merge.c \
- row/row0mysql.c row/row0purge.c row/row0row.c \
- row/row0sel.c row/row0uins.c row/row0umod.c \
- row/row0undo.c row/row0upd.c row/row0vers.c \
- srv/srv0que.c srv/srv0srv.c srv/srv0start.c \
- sync/sync0arr.c sync/sync0rw.c \
- sync/sync0sync.c thr/thr0loc.c \
- trx/trx0i_s.c \
- trx/trx0purge.c \
- trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c \
- trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c \
- usr/usr0sess.c ut/ut0byte.c ut/ut0dbg.c \
- ut/ut0list.c ut/ut0mem.c ut/ut0rnd.c \
- ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \
- handler/ha_innodb.cc handler/handler0alter.cc \
- handler/i_s.cc \
- handler/mysql_addons.cc
+libinnobase_a_SOURCES= \
+ btr/btr0btr.c \
+ btr/btr0cur.c \
+ btr/btr0pcur.c \
+ btr/btr0sea.c \
+ buf/buf0buddy.c \
+ buf/buf0buf.c \
+ buf/buf0flu.c \
+ buf/buf0lru.c \
+ buf/buf0rea.c \
+ data/data0data.c \
+ data/data0type.c \
+ dict/dict0boot.c \
+ dict/dict0crea.c \
+ dict/dict0dict.c \
+ dict/dict0load.c \
+ dict/dict0mem.c \
+ dyn/dyn0dyn.c \
+ eval/eval0eval.c \
+ eval/eval0proc.c \
+ fil/fil0fil.c \
+ fsp/fsp0fsp.c \
+ fut/fut0fut.c \
+ fut/fut0lst.c \
+ ha/ha0ha.c \
+ ha/ha0storage.c \
+ ha/hash0hash.c \
+ handler/ha_innodb.cc \
+ handler/handler0alter.cc \
+ handler/i_s.cc \
+ handler/mysql_addons.cc \
+ ibuf/ibuf0ibuf.c \
+ lock/lock0iter.c \
+ lock/lock0lock.c \
+ log/log0log.c \
+ log/log0recv.c \
+ mach/mach0data.c \
+ mem/mem0mem.c \
+ mem/mem0pool.c \
+ mtr/mtr0log.c \
+ mtr/mtr0mtr.c \
+ os/os0file.c \
+ os/os0proc.c \
+ os/os0sync.c \
+ os/os0thread.c \
+ page/page0cur.c \
+ page/page0page.c \
+ page/page0zip.c \
+ pars/lexyy.c \
+ pars/pars0grm.c \
+ pars/pars0opt.c \
+ pars/pars0pars.c \
+ pars/pars0sym.c \
+ que/que0que.c \
+ read/read0read.c \
+ rem/rem0cmp.c \
+ rem/rem0rec.c \
+ row/row0ext.c \
+ row/row0ins.c \
+ row/row0merge.c \
+ row/row0mysql.c \
+ row/row0purge.c \
+ row/row0row.c \
+ row/row0sel.c \
+ row/row0uins.c \
+ row/row0umod.c \
+ row/row0undo.c \
+ row/row0upd.c \
+ row/row0vers.c \
+ srv/srv0que.c \
+ srv/srv0srv.c \
+ srv/srv0start.c \
+ sync/sync0arr.c \
+ sync/sync0rw.c \
+ sync/sync0sync.c \
+ thr/thr0loc.c \
+ trx/trx0i_s.c \
+ trx/trx0purge.c \
+ trx/trx0rec.c \
+ trx/trx0roll.c \
+ trx/trx0rseg.c \
+ trx/trx0sys.c \
+ trx/trx0trx.c \
+ trx/trx0undo.c \
+ usr/usr0sess.c \
+ ut/ut0byte.c \
+ ut/ut0dbg.c \
+ ut/ut0list.c \
+ ut/ut0mem.c \
+ ut/ut0rnd.c \
+ ut/ut0ut.c \
+ ut/ut0vec.c \
+ ut/ut0wqueue.c
libinnobase_a_CXXFLAGS= $(AM_CFLAGS)
libinnobase_a_CFLAGS= $(AM_CFLAGS)
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index 2029a95cc19..086b3a0a599 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file btr/btr0btr.c
The B-tree
Created 6/2/1994 Heikki Tuuri
@@ -31,6 +32,8 @@ Created 6/2/1994 Heikki Tuuri
#include "fsp0fsp.h"
#include "page0page.h"
#include "page0zip.h"
+
+#ifndef UNIV_HOTBACKUP
#include "btr0cur.h"
#include "btr0sea.h"
#include "btr0pcur.h"
@@ -95,15 +98,15 @@ we allocate pages for the non-leaf levels of the tree.
*/
#ifdef UNIV_BTR_DEBUG
-/******************************************************************
-Checks a file segment header within a B-tree root page. */
+/**************************************************************//**
+Checks a file segment header within a B-tree root page.
+@return TRUE if valid */
static
ibool
btr_root_fseg_validate(
/*===================*/
- /* out: TRUE if valid */
- const fseg_header_t* seg_header, /* in: segment header */
- ulint space) /* in: tablespace identifier */
+ const fseg_header_t* seg_header, /*!< in: segment header */
+ ulint space) /*!< in: tablespace identifier */
{
ulint offset = mach_read_from_2(seg_header + FSEG_HDR_OFFSET);
@@ -114,15 +117,15 @@ btr_root_fseg_validate(
}
#endif /* UNIV_BTR_DEBUG */
-/******************************************************************
-Gets the root node of a tree and x-latches it. */
+/**************************************************************//**
+Gets the root node of a tree and x-latches it.
+@return root page, x-latched */
static
buf_block_t*
btr_root_block_get(
/*===============*/
- /* out: root page, x-latched */
- dict_index_t* index, /* in: index tree */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -150,29 +153,29 @@ btr_root_block_get(
return(block);
}
-/******************************************************************
-Gets the root node of a tree and x-latches it. */
+/**************************************************************//**
+Gets the root node of a tree and x-latches it.
+@return root page, x-latched */
UNIV_INTERN
page_t*
btr_root_get(
/*=========*/
- /* out: root page, x-latched */
- dict_index_t* index, /* in: index tree */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ mtr_t* mtr) /*!< in: mtr */
{
return(buf_block_get_frame(btr_root_block_get(index, mtr)));
}
-/*****************************************************************
+/*************************************************************//**
Gets pointer to the previous user record in the tree. It is assumed that
-the caller has appropriate latches on the page and its neighbor. */
+the caller has appropriate latches on the page and its neighbor.
+@return previous user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_prev_user_rec(
/*==================*/
- /* out: previous user record, NULL if there is none */
- rec_t* rec, /* in: record on leaf level */
- mtr_t* mtr) /* in: mtr holding a latch on the page, and if
+ rec_t* rec, /*!< in: record on leaf level */
+ mtr_t* mtr) /*!< in: mtr holding a latch on the page, and if
needed, also to the previous page */
{
page_t* page;
@@ -221,16 +224,16 @@ btr_get_prev_user_rec(
return(NULL);
}
-/*****************************************************************
+/*************************************************************//**
Gets pointer to the next user record in the tree. It is assumed that the
-caller has appropriate latches on the page and its neighbor. */
+caller has appropriate latches on the page and its neighbor.
+@return next user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_next_user_rec(
/*==================*/
- /* out: next user record, NULL if there is none */
- rec_t* rec, /* in: record on leaf level */
- mtr_t* mtr) /* in: mtr holding a latch on the page, and if
+ rec_t* rec, /*!< in: record on leaf level */
+ mtr_t* mtr) /*!< in: mtr holding a latch on the page, and if
needed, also to the next page */
{
page_t* page;
@@ -277,18 +280,18 @@ btr_get_next_user_rec(
return(NULL);
}
-/******************************************************************
+/**************************************************************//**
Creates a new index page (not the root, and also not
used in page reorganization). @see btr_page_empty(). */
static
void
btr_page_create(
/*============*/
- buf_block_t* block, /* in/out: page to be created */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index, /* in: index */
- ulint level, /* in: the B-tree level of the page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in/out: page to be created */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: the B-tree level of the page */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page = buf_block_get_frame(block);
@@ -307,16 +310,16 @@ btr_page_create(
btr_page_set_index_id(page, page_zip, index->id, mtr);
}
-/******************************************************************
+/**************************************************************//**
Allocates a new file page to be used in an ibuf tree. Takes the page from
-the free list of the tree, which must contain pages! */
+the free list of the tree, which must contain pages!
+@return new allocated block, x-latched */
static
buf_block_t*
btr_page_alloc_for_ibuf(
/*====================*/
- /* out: new allocated block, x-latched */
- dict_index_t* index, /* in: index tree */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ mtr_t* mtr) /*!< in: mtr */
{
fil_addr_t node_addr;
page_t* root;
@@ -344,22 +347,21 @@ btr_page_alloc_for_ibuf(
return(new_block);
}
-/******************************************************************
+/**************************************************************//**
Allocates a new file page to be used in an index tree. NOTE: we assume
-that the caller has made the reservation for free extents! */
+that the caller has made the reservation for free extents!
+@return new allocated block, x-latched; NULL if out of space */
UNIV_INTERN
buf_block_t*
btr_page_alloc(
/*===========*/
- /* out: new allocated block, x-latched;
- NULL if out of space */
- dict_index_t* index, /* in: index */
- ulint hint_page_no, /* in: hint of a good page */
- byte file_direction, /* in: direction where a possible
+ dict_index_t* index, /*!< in: index */
+ ulint hint_page_no, /*!< in: hint of a good page */
+ byte file_direction, /*!< in: direction where a possible
page split is made */
- ulint level, /* in: level where the page is placed
+ ulint level, /*!< in: level where the page is placed
in the tree */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
fseg_header_t* seg_header;
page_t* root;
@@ -398,15 +400,15 @@ btr_page_alloc(
return(new_block);
}
-/******************************************************************
-Gets the number of pages in a B-tree. */
+/**************************************************************//**
+Gets the number of pages in a B-tree.
+@return number of pages */
UNIV_INTERN
ulint
btr_get_size(
/*=========*/
- /* out: number of pages */
- dict_index_t* index, /* in: index */
- ulint flag) /* in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
+ dict_index_t* index, /*!< in: index */
+ ulint flag) /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
{
fseg_header_t* seg_header;
page_t* root;
@@ -442,16 +444,16 @@ btr_get_size(
return(n);
}
-/******************************************************************
+/**************************************************************//**
Frees a page used in an ibuf tree. Puts the page to the free list of the
ibuf tree. */
static
void
btr_page_free_for_ibuf(
/*===================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* root;
@@ -466,7 +468,7 @@ btr_page_free_for_ibuf(
mtr));
}
-/******************************************************************
+/**************************************************************//**
Frees a file page used in an index tree. Can be used also to (BLOB)
external storage pages, because the page level 0 can be given as an
argument. */
@@ -474,10 +476,10 @@ UNIV_INTERN
void
btr_page_free_low(
/*==============*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- ulint level, /* in: page level */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ ulint level, /*!< in: page level */
+ mtr_t* mtr) /*!< in: mtr */
{
fseg_header_t* seg_header;
page_t* root;
@@ -508,16 +510,16 @@ btr_page_free_low(
buf_block_get_page_no(block), mtr);
}
-/******************************************************************
+/**************************************************************//**
Frees a file page used in an index tree. NOTE: cannot free field external
storage pages because the page must contain info on its level. */
UNIV_INTERN
void
btr_page_free(
/*==========*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint level;
@@ -526,18 +528,18 @@ btr_page_free(
btr_page_free_low(index, block, level, mtr);
}
-/******************************************************************
+/**************************************************************//**
Sets the child node file address in a node pointer. */
UNIV_INLINE
void
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
+ 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() */
- ulint page_no,/* in: child node address */
- mtr_t* mtr) /* in: mtr */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint page_no,/*!< in: child node address */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* field;
ulint len;
@@ -561,17 +563,17 @@ btr_node_ptr_set_child_page_no(
}
}
-/****************************************************************
-Returns the child page of a node pointer and x-latches it. */
+/************************************************************//**
+Returns the child page of a node pointer and x-latches it.
+@return child page, x-latched */
static
buf_block_t*
btr_node_ptr_get_child(
/*===================*/
- /* out: child page, x-latched */
- const rec_t* node_ptr,/* in: node pointer */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- mtr_t* mtr) /* in: mtr */
+ const rec_t* node_ptr,/*!< in: node pointer */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint page_no;
ulint space;
@@ -584,21 +586,20 @@ btr_node_ptr_get_child(
page_no, RW_X_LATCH, mtr));
}
-/****************************************************************
+/************************************************************//**
Returns the upper level node pointer to a page. It is assumed that mtr holds
-an x-latch on the tree. */
+an x-latch on the tree.
+@return rec_get_offsets() of the node pointer record */
static
ulint*
btr_page_get_father_node_ptr(
/*=========================*/
- /* out: rec_get_offsets() of the
- node pointer record */
- ulint* 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,
+ ulint* 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,
its page x-latched */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dtuple_t* tuple;
rec_t* user_rec;
@@ -659,8 +660,7 @@ btr_page_get_father_node_ptr(
" to fix the\n"
"InnoDB: corruption. If the crash happens at "
"the database startup, see\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html about\n"
+ "InnoDB: " REFMAN "forcing-recovery.html about\n"
"InnoDB: forcing recovery. "
"Then dump + drop + reimport.\n", stderr);
@@ -670,21 +670,20 @@ btr_page_get_father_node_ptr(
return(offsets);
}
-/****************************************************************
+/************************************************************//**
Returns the upper level node pointer to a page. It is assumed that mtr holds
-an x-latch on the tree. */
+an x-latch on the tree.
+@return rec_get_offsets() of the node pointer record */
static
ulint*
btr_page_get_father_block(
/*======================*/
- /* out: rec_get_offsets() of the
- node pointer record */
- ulint* 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 */
- mtr_t* mtr, /* in: mtr */
- btr_cur_t* cursor) /* out: cursor on node pointer record,
+ ulint* 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 */
+ mtr_t* mtr, /*!< in: mtr */
+ btr_cur_t* cursor) /*!< out: cursor on node pointer record,
its page x-latched */
{
rec_t* rec
@@ -694,17 +693,17 @@ btr_page_get_father_block(
return(btr_page_get_father_node_ptr(offsets, heap, cursor, mtr));
}
-/****************************************************************
+/************************************************************//**
Seeks to the upper level node pointer to a page.
It is assumed that mtr holds an x-latch on the tree. */
static
void
btr_page_get_father(
/*================*/
- dict_index_t* index, /* in: b-tree index */
- buf_block_t* block, /* in: child page in the index */
- mtr_t* mtr, /* in: mtr */
- btr_cur_t* cursor) /* out: cursor on node pointer record,
+ dict_index_t* index, /*!< in: b-tree index */
+ buf_block_t* block, /*!< in: child page in the index */
+ mtr_t* mtr, /*!< in: mtr */
+ btr_cur_t* cursor) /*!< out: cursor on node pointer record,
its page x-latched */
{
mem_heap_t* heap;
@@ -718,21 +717,20 @@ btr_page_get_father(
mem_heap_free(heap);
}
-/****************************************************************
-Creates the root node for a new index tree. */
+/************************************************************//**
+Creates the root node for a new index tree.
+@return page number of the created root, FIL_NULL if did not succeed */
UNIV_INTERN
ulint
btr_create(
/*=======*/
- /* out: page number of the created root,
- FIL_NULL if did not succeed */
- ulint type, /* in: type of the index */
- ulint space, /* in: space where created */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint type, /*!< in: type of the index */
+ ulint space, /*!< in: space where created */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- dulint index_id,/* in: index id */
- dict_index_t* index, /* in: index */
- mtr_t* mtr) /* in: mini-transaction handle */
+ dulint index_id,/*!< in: index id */
+ dict_index_t* index, /*!< in: index */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint page_no;
buf_block_t* block;
@@ -792,14 +790,21 @@ btr_create(
} else {
/* It is a non-ibuf tree: create a file segment for leaf
pages */
- fseg_create(space, page_no,
- PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr);
+ if (!fseg_create(space, page_no,
+ PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
+ /* Not enough space for new segment, free root
+ segment before return. */
+ btr_free_root(space, zip_size, page_no, mtr);
+
+ return(FIL_NULL);
+ }
+
/* The fseg create acquires a second latch on the page,
therefore we must declare it: */
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
}
- /* Create a new index page on the the allocated segment page */
+ /* Create a new index page on the allocated segment page */
page_zip = buf_block_get_page_zip(block);
if (UNIV_LIKELY_NULL(page_zip)) {
@@ -837,17 +842,17 @@ btr_create(
return(page_no);
}
-/****************************************************************
+/************************************************************//**
Frees a B-tree except the root page, which MUST be freed after this
by calling btr_free_root. */
UNIV_INTERN
void
btr_free_but_not_root(
/*==================*/
- ulint space, /* in: space where created */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where created */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint root_page_no) /* in: root page number */
+ ulint root_page_no) /*!< in: root page number */
{
ibool finished;
page_t* root;
@@ -894,17 +899,17 @@ top_loop:
}
}
-/****************************************************************
+/************************************************************//**
Frees the B-tree root page. Other tree MUST already have been freed. */
UNIV_INTERN
void
btr_free_root(
/*==========*/
- ulint space, /* in: space where created */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where created */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint root_page_no, /* in: root page number */
- mtr_t* mtr) /* in: a mini-transaction which has already
+ ulint root_page_no, /*!< in: root page number */
+ mtr_t* mtr) /*!< in: a mini-transaction which has already
been started */
{
buf_block_t* block;
@@ -921,21 +926,22 @@ btr_free_root(
while (!fseg_free_step(header, mtr));
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Reorganizes an index page. */
static
ibool
btr_page_reorganize_low(
/*====================*/
- ibool recovery,/* in: TRUE if called in recovery:
+ ibool recovery,/*!< in: TRUE if called in recovery:
locks should not be updated, i.e.,
there cannot exist locks on the
page, and a hash index should not be
dropped: it cannot exist */
- buf_block_t* block, /* in: page to be reorganized */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: page to be reorganized */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
@@ -956,29 +962,39 @@ btr_page_reorganize_low(
data_size1 = page_get_data_size(page);
max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
+#ifndef UNIV_HOTBACKUP
/* Write the log record */
mlog_open_and_write_index(mtr, page, index, page_is_comp(page)
? MLOG_COMP_PAGE_REORGANIZE
: MLOG_PAGE_REORGANIZE, 0);
+#endif /* !UNIV_HOTBACKUP */
/* Turn logging off */
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
+#ifndef UNIV_HOTBACKUP
temp_block = buf_block_alloc(0);
+#else /* !UNIV_HOTBACKUP */
+ ut_ad(block == back_block1);
+ temp_block = back_block2;
+#endif /* !UNIV_HOTBACKUP */
temp_page = temp_block->frame;
/* Copy the old page to temporary space */
buf_frame_copy(temp_page, page);
+#ifndef UNIV_HOTBACKUP
if (UNIV_LIKELY(!recovery)) {
btr_search_drop_page_hash_index(block);
}
+ block->check_index_page_at_flush = TRUE;
+#endif /* !UNIV_HOTBACKUP */
+
/* Recreate the page: note that global data on page (possible
segment headers, next page-field, etc.) is preserved intact */
page_create(block, mtr, dict_table_is_comp(index->table));
- block->check_index_page_at_flush = TRUE;
/* Copy the records from the temporary space to the recreated page;
do not copy the lock bits yet */
@@ -986,23 +1002,52 @@ btr_page_reorganize_low(
page_copy_rec_list_end_no_locks(block, temp_block,
page_get_infimum_rec(temp_page),
index, mtr);
- /* Copy max trx id to recreated page */
- page_set_max_trx_id(block, NULL, page_get_max_trx_id(temp_page));
+
+ if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
+ /* Copy max trx id to recreated page */
+ trx_id_t max_trx_id = page_get_max_trx_id(temp_page);
+ page_set_max_trx_id(block, NULL, max_trx_id, mtr);
+ /* In crash recovery, dict_index_is_sec_or_ibuf() always
+ returns TRUE, even for clustered indexes. max_trx_id is
+ unused in clustered index pages. */
+ ut_ad(!ut_dulint_is_zero(max_trx_id) || recovery);
+ }
if (UNIV_LIKELY_NULL(page_zip)
&& UNIV_UNLIKELY
(!page_zip_compress(page_zip, page, index, NULL))) {
/* Restore the old page and exit. */
- buf_frame_copy(page, temp_page);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ /* Check that the bytes that we skip are identical. */
+ ut_a(!memcmp(page, temp_page, PAGE_HEADER));
+ ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
+ PAGE_HEADER + PAGE_N_RECS + temp_page,
+ PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
+ ut_a(!memcmp(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page,
+ UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + temp_page,
+ FIL_PAGE_DATA_END));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+
+ memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
+ PAGE_N_RECS - PAGE_N_DIR_SLOTS);
+ memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
+ UNIV_PAGE_SIZE - PAGE_DATA - FIL_PAGE_DATA_END);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
goto func_exit;
}
+#ifndef UNIV_HOTBACKUP
if (UNIV_LIKELY(!recovery)) {
/* Update the record lock bitmaps */
lock_move_reorganize_page(block, temp_block);
}
+#endif /* !UNIV_HOTBACKUP */
data_size2 = page_get_data_size(page);
max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1);
@@ -1029,7 +1074,9 @@ func_exit:
#ifdef UNIV_ZIP_DEBUG
ut_a(!page_zip || page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
+#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
+#endif /* !UNIV_HOTBACKUP */
/* Restore logging mode */
mtr_set_log_mode(mtr, log_mode);
@@ -1037,37 +1084,39 @@ func_exit:
return(success);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Reorganizes an index page.
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
page of a non-clustered index, the caller must update the insert
buffer free bits in the same mini-transaction in such a way that the
-modification will be redo-logged. */
+modification will be redo-logged.
+@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
btr_page_reorganize(
/*================*/
- /* out: TRUE on success, FALSE on failure */
- buf_block_t* block, /* in: page to be reorganized */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: page to be reorganized */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
return(btr_page_reorganize_low(FALSE, block, index, mtr));
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of reorganizing a page. */
+/***********************************************************//**
+Parses a redo log record of reorganizing a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_page_reorganize(
/*======================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
+ byte* ptr, /*!< in: buffer */
byte* end_ptr __attribute__((unused)),
- /* in: buffer end */
- dict_index_t* index, /* in: record descriptor */
- buf_block_t* block, /* in: page to be reorganized, or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ /*!< in: buffer end */
+ dict_index_t* index, /*!< in: record descriptor */
+ buf_block_t* block, /*!< in: page to be reorganized, or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(ptr && end_ptr);
@@ -1080,17 +1129,18 @@ btr_parse_page_reorganize(
return(ptr);
}
-/*****************************************************************
-Empties an index page. @see btr_page_create().*/
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
+Empties an index page. @see btr_page_create(). */
static
void
btr_page_empty(
/*===========*/
- buf_block_t* block, /* in: page to be emptied */
- page_zip_des_t* page_zip,/* out: compressed page, or NULL */
- dict_index_t* index, /* in: index of the page */
- ulint level, /* in: the B-tree level of the page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: page to be emptied */
+ page_zip_des_t* page_zip,/*!< out: compressed page, or NULL */
+ dict_index_t* index, /*!< in: index of the page */
+ ulint level, /*!< in: the B-tree level of the page */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page = buf_block_get_frame(block);
@@ -1115,24 +1165,24 @@ btr_page_empty(
block->check_index_page_at_flush = TRUE;
}
-/*****************************************************************
+/*************************************************************//**
Makes tree one level higher by splitting the root, and inserts
the tuple. It is assumed that mtr contains an x-latch on the tree.
NOTE that the operation of this function must always succeed,
we cannot reverse it: therefore enough free disk space must be
-guaranteed to be available before this function is called. */
+guaranteed to be available before this function is called.
+@return inserted record */
UNIV_INTERN
rec_t*
btr_root_raise_and_insert(
/*======================*/
- /* out: inserted record */
- btr_cur_t* cursor, /* in: cursor at which to insert: must be
+ btr_cur_t* cursor, /*!< in: cursor at which to insert: must be
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr) /* in: mtr */
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
page_t* root;
@@ -1287,16 +1337,16 @@ btr_root_raise_and_insert(
return(btr_page_split_and_insert(cursor, tuple, n_ext, mtr));
}
-/*****************************************************************
+/*************************************************************//**
Decides if the page should be split at the convergence point of inserts
-converging to the left. */
+converging to the left.
+@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_left(
/*===========================*/
- /* out: TRUE if split recommended */
- btr_cur_t* cursor, /* in: cursor at which to insert */
- rec_t** split_rec) /* out: if split recommended,
+ btr_cur_t* cursor, /*!< in: cursor at which to insert */
+ rec_t** split_rec) /*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple to be inserted should
be first */
@@ -1332,16 +1382,16 @@ btr_page_get_split_rec_to_left(
return(FALSE);
}
-/*****************************************************************
+/*************************************************************//**
Decides if the page should be split at the convergence point of inserts
-converging to the right. */
+converging to the right.
+@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_right(
/*============================*/
- /* out: TRUE if split recommended */
- btr_cur_t* cursor, /* in: cursor at which to insert */
- rec_t** split_rec) /* out: if split recommended,
+ btr_cur_t* cursor, /*!< in: cursor at which to insert */
+ rec_t** split_rec) /*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple to be inserted should
be first */
@@ -1390,19 +1440,19 @@ split_at_new:
return(FALSE);
}
-/*****************************************************************
+/*************************************************************//**
Calculates a split record such that the tuple will certainly fit on
its half-page when the split is performed. We assume in this function
-only that the cursor page has at least one user record. */
+only that the cursor page has at least one user record.
+@return split record, or NULL if tuple will be the first record on
+upper half-page */
static
rec_t*
btr_page_get_sure_split_rec(
/*========================*/
- /* out: split record, or NULL if tuple
- will be the first record on upper half-page */
- btr_cur_t* cursor, /* in: cursor at which insert should be made */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext) /* in: number of externally stored columns */
+ btr_cur_t* cursor, /*!< in: cursor at which insert should be made */
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext) /*!< in: number of externally stored columns */
{
page_t* page;
page_zip_des_t* page_zip;
@@ -1510,24 +1560,24 @@ func_exit:
return(rec);
}
-/*****************************************************************
+/*************************************************************//**
Returns TRUE if the insert fits on the appropriate half-page with the
-chosen split_rec. */
+chosen split_rec.
+@return TRUE if fits */
static
ibool
btr_page_insert_fits(
/*=================*/
- /* out: TRUE if fits */
- btr_cur_t* cursor, /* in: cursor at which insert
+ btr_cur_t* cursor, /*!< in: cursor at which insert
should be made */
- const rec_t* split_rec,/* in: suggestion for first record
+ const rec_t* split_rec,/*!< in: suggestion for first record
on upper half-page, or NULL if
tuple to be inserted should be first */
- const ulint* offsets,/* in: rec_get_offsets(
+ const ulint* offsets,/*!< in: rec_get_offsets(
split_rec, cursor->index) */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mem_heap_t* heap) /* in: temporary memory heap */
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
page_t* page;
ulint insert_size;
@@ -1607,17 +1657,17 @@ btr_page_insert_fits(
return(FALSE);
}
-/***********************************************************
+/*******************************************************//**
Inserts a data tuple to a tree on a non-leaf level. It is assumed
that mtr holds an x-latch on the tree. */
UNIV_INTERN
void
btr_insert_on_non_leaf_level(
/*=========================*/
- dict_index_t* index, /* in: index */
- ulint level, /* in: level, must be > 0 */
- dtuple_t* tuple, /* in: the record to be inserted */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: level, must be > 0 */
+ dtuple_t* tuple, /*!< in: the record to be inserted */
+ mtr_t* mtr) /*!< in: mtr */
{
big_rec_t* dummy_big_rec;
btr_cur_t cursor;
@@ -1638,20 +1688,20 @@ btr_insert_on_non_leaf_level(
ut_a(err == DB_SUCCESS);
}
-/******************************************************************
+/**************************************************************//**
Attaches the halves of an index page on the appropriate level in an
index tree. */
static
void
btr_attach_half_pages(
/*==================*/
- dict_index_t* index, /* in: the index tree */
- buf_block_t* block, /* in/out: page to be split */
- rec_t* split_rec, /* in: first record on upper
+ dict_index_t* index, /*!< in: the index tree */
+ buf_block_t* block, /*!< in/out: page to be split */
+ rec_t* split_rec, /*!< in: first record on upper
half page */
- buf_block_t* new_block, /* in/out: the new half page */
- ulint direction, /* in: FSP_UP or FSP_DOWN */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: the new half page */
+ ulint direction, /*!< in: FSP_UP or FSP_DOWN */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -1773,26 +1823,25 @@ btr_attach_half_pages(
btr_page_set_next(upper_page, upper_page_zip, next_page_no, mtr);
}
-/*****************************************************************
+/*************************************************************//**
Splits an index page to halves and inserts the tuple. It is assumed
-that mtr holds an x-latch to the index tree. NOTE: the tree x-latch
-is released within this function! NOTE that the operation of this
-function must always succeed, we cannot reverse it: therefore
-enough free disk space must be guaranteed to be available before
-this function is called. */
+that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
+released within this function! NOTE that the operation of this
+function must always succeed, we cannot reverse it: therefore enough
+free disk space (2 pages) must be guaranteed to be available before
+this function is called.
+
+@return inserted record */
UNIV_INTERN
rec_t*
btr_page_split_and_insert(
/*======================*/
- /* out: inserted record; NOTE: the tree
- x-latch is released! NOTE: 2 free disk
- pages must be available! */
- btr_cur_t* cursor, /* in: cursor at which to insert; when the
+ 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 */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr) /* in: mtr */
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
page_t* page;
@@ -1879,7 +1928,7 @@ func_start:
n_uniq, &heap);
/* If the new record is less than the existing record
- the the split in the middle will copy the existing
+ the split in the middle will copy the existing
record to the new node. */
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
split_rec = page_get_middle_rec(page);
@@ -2144,17 +2193,17 @@ func_exit:
return(rec);
}
-/*****************************************************************
+/*************************************************************//**
Removes a page from the level list of pages. */
static
void
btr_level_list_remove(
/*==================*/
- ulint space, /* in: space where removed */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space where removed */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- page_t* page, /* in: page to remove */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /*!< in: page to remove */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint prev_page_no;
ulint next_page_no;
@@ -2204,36 +2253,39 @@ btr_level_list_remove(
}
}
-/********************************************************************
+/****************************************************************//**
Writes the redo log record for setting an index record as the predefined
minimum record. */
UNIV_INLINE
void
btr_set_min_rec_mark_log(
/*=====================*/
- rec_t* rec, /* in: record */
- byte type, /* in: MLOG_COMP_REC_MIN_MARK or MLOG_REC_MIN_MARK */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record */
+ byte type, /*!< in: MLOG_COMP_REC_MIN_MARK or MLOG_REC_MIN_MARK */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(rec, type, mtr);
/* Write rec offset as a 2-byte ulint */
mlog_catenate_ulint(mtr, page_offset(rec), MLOG_2BYTES);
}
+#else /* !UNIV_HOTBACKUP */
+# define btr_set_min_rec_mark_log(rec,comp,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/********************************************************************
+/****************************************************************//**
Parses the redo log record for setting an index record as the predefined
-minimum record. */
+minimum record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_set_min_rec_mark(
/*=======================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint comp, /* in: nonzero=compact page format */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint comp, /*!< in: nonzero=compact page format */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
rec_t* rec;
@@ -2253,14 +2305,14 @@ btr_parse_set_min_rec_mark(
return(ptr + 2);
}
-/********************************************************************
+/****************************************************************//**
Sets a record as the predefined minimum record. */
UNIV_INTERN
void
btr_set_min_rec_mark(
/*=================*/
- rec_t* rec, /* in: record */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint info_bits;
@@ -2279,15 +2331,16 @@ btr_set_min_rec_mark(
}
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Deletes on the upper level the node pointer to a page. */
UNIV_INTERN
void
btr_node_ptr_delete(
/*================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: page whose node pointer is deleted */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: page whose node pointer is deleted */
+ mtr_t* mtr) /*!< in: mtr */
{
btr_cur_t cursor;
ibool compressed;
@@ -2307,19 +2360,19 @@ btr_node_ptr_delete(
}
}
-/*****************************************************************
+/*************************************************************//**
If page is the only on its level, this function moves its records to the
father page, thus reducing the tree height. */
static
void
btr_lift_page_up(
/*=============*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: page which is the only on its level;
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: page which is the only on its level;
must not be empty: use
btr_discard_only_page_on_level if the last
record from the page should be removed */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* father_block;
page_t* father_page;
@@ -2328,7 +2381,7 @@ btr_lift_page_up(
page_t* page = buf_block_get_frame(block);
ulint root_page_no;
buf_block_t* blocks[BTR_MAX_LEVELS];
- ulint n_blocks; /* last used index in blocks[] */
+ ulint n_blocks; /*!< last used index in blocks[] */
ulint i;
ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
@@ -2429,7 +2482,7 @@ btr_lift_page_up(
ut_ad(btr_check_node_ptr(index, father_block, mtr));
}
-/*****************************************************************
+/*************************************************************//**
Tries to merge the page first to the left immediate brother if such a
brother exists, and the node pointers to the current page and to the brother
reside on the same page. If the left brother does not satisfy these
@@ -2437,17 +2490,17 @@ conditions, looks at the right brother. If the page is the only one on that
level lifts the records of the page to the father page, thus reducing the
tree height. It is assumed that mtr holds an x-latch on the tree and on the
page. If cursor is on the leaf level, mtr must also hold x-latches to the
-brothers, if they exist. */
+brothers, if they exist.
+@return TRUE on success */
UNIV_INTERN
ibool
btr_compress(
/*=========*/
- /* out: TRUE on success */
- btr_cur_t* cursor, /* in: cursor on the page to merge or lift;
+ btr_cur_t* cursor, /*!< in: cursor on the page to merge or lift;
the page must not be empty: in record delete
use btr_discard_page if the page would become
empty */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
ulint space;
@@ -2721,7 +2774,7 @@ err_exit:
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Discards a page that is the only page on its level. This will empty
the whole B-tree, leaving just an empty root page. This function
should never be reached, because btr_compress(), which is invoked in
@@ -2730,11 +2783,15 @@ static
void
btr_discard_only_page_on_level(
/*===========================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: page which is the only on its level */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: page which is the only on its level */
+ mtr_t* mtr) /*!< in: mtr */
{
- ulint page_level = 0;
+ ulint page_level = 0;
+ trx_id_t max_trx_id;
+
+ /* Save the PAGE_MAX_TRX_ID from the leaf page. */
+ max_trx_id = page_get_max_trx_id(buf_block_get_frame(block));
while (buf_block_get_page_no(block) != dict_index_get_page(index)) {
btr_cur_t cursor;
@@ -2777,13 +2834,20 @@ btr_discard_only_page_on_level(
btr_page_empty(block, buf_block_get_page_zip(block), index, 0, mtr);
- /* We play it safe and reset the free bits for the root */
if (!dict_index_is_clust(index)) {
+ /* We play it safe and reset the free bits for the root */
ibuf_reset_free_bits(block);
+
+ if (page_is_leaf(buf_block_get_frame(block))) {
+ ut_a(!ut_dulint_is_zero(max_trx_id));
+ page_set_max_trx_id(block,
+ buf_block_get_page_zip(block),
+ max_trx_id, mtr);
+ }
}
}
-/*****************************************************************
+/*************************************************************//**
Discards a page from a B-tree. This is used to remove the last record from
a B-tree page: the whole page must be removed at the same time. This cannot
be used for the root page, which is allowed to be empty. */
@@ -2791,9 +2855,9 @@ UNIV_INTERN
void
btr_discard_page(
/*=============*/
- btr_cur_t* cursor, /* in: cursor on the page to discard: not on
+ btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
the root page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
ulint space;
@@ -2892,13 +2956,13 @@ btr_discard_page(
}
#ifdef UNIV_BTR_PRINT
-/*****************************************************************
+/*************************************************************//**
Prints size info of a B-tree. */
UNIV_INTERN
void
btr_print_size(
/*===========*/
- dict_index_t* index) /* in: index tree */
+ dict_index_t* index) /*!< in: index tree */
{
page_t* root;
fseg_header_t* seg;
@@ -2931,19 +2995,19 @@ btr_print_size(
mtr_commit(&mtr);
}
-/****************************************************************
+/************************************************************//**
Prints recursively index tree pages. */
static
void
btr_print_recursive(
/*================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: index page */
- ulint width, /* in: print this many entries from start
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: index page */
+ 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() */
- mtr_t* mtr) /* in: mtr */
+ mem_heap_t** heap, /*!< in/out: heap for rec_get_offsets() */
+ ulint** offsets,/*!< in/out: buffer for rec_get_offsets() */
+ mtr_t* mtr) /*!< in: mtr */
{
const page_t* page = buf_block_get_frame(block);
page_cur_t cursor;
@@ -2993,14 +3057,14 @@ btr_print_recursive(
}
}
-/******************************************************************
+/**************************************************************//**
Prints directories and other info of all nodes in the tree. */
UNIV_INTERN
void
btr_print_index(
/*============*/
- dict_index_t* index, /* in: index */
- ulint width) /* in: print this many entries from start
+ dict_index_t* index, /*!< in: index */
+ ulint width) /*!< in: print this many entries from start
and end */
{
mtr_t mtr;
@@ -3029,16 +3093,16 @@ btr_print_index(
#endif /* UNIV_BTR_PRINT */
#ifdef UNIV_DEBUG
-/****************************************************************
-Checks that the node pointer to a page is appropriate. */
+/************************************************************//**
+Checks that the node pointer to a page is appropriate.
+@return TRUE */
UNIV_INTERN
ibool
btr_check_node_ptr(
/*===============*/
- /* out: TRUE */
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: index page */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: index page */
+ mtr_t* mtr) /*!< in: mtr */
{
mem_heap_t* heap;
dtuple_t* tuple;
@@ -3073,15 +3137,15 @@ func_exit:
}
#endif /* UNIV_DEBUG */
-/****************************************************************
+/************************************************************//**
Display identification information for a record. */
static
void
btr_index_rec_validate_report(
/*==========================*/
- const page_t* page, /* in: index page */
- const rec_t* rec, /* in: index record */
- const dict_index_t* index) /* in: index */
+ const page_t* page, /*!< in: index page */
+ const rec_t* rec, /*!< in: index record */
+ const dict_index_t* index) /*!< in: index */
{
fputs("InnoDB: Record in ", stderr);
dict_index_name_print(stderr, NULL, index);
@@ -3089,17 +3153,17 @@ btr_index_rec_validate_report(
page_get_page_no(page), (ulint) page_offset(rec));
}
-/****************************************************************
+/************************************************************//**
Checks the size and number of fields in a record based on the definition of
-the index. */
+the index.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_index_rec_validate(
/*===================*/
- /* out: TRUE if ok */
- const rec_t* rec, /* in: index record */
- const dict_index_t* index, /* in: index */
- ibool dump_on_error) /* in: TRUE if the function
+ const rec_t* rec, /*!< in: index record */
+ const dict_index_t* index, /*!< in: index */
+ ibool dump_on_error) /*!< in: TRUE if the function
should print hex dump of record
and page on error */
{
@@ -3154,7 +3218,7 @@ btr_index_rec_validate(
for (i = 0; i < n; i++) {
ulint fixed_size = dict_col_get_fixed_size(
- dict_index_get_nth_col(index, i));
+ dict_index_get_nth_col(index, i), page_is_comp(page));
rec_get_nth_field_offs(offsets, i, &len);
@@ -3198,16 +3262,16 @@ btr_index_rec_validate(
return(TRUE);
}
-/****************************************************************
+/************************************************************//**
Checks the size and number of fields in records based on the definition of
-the index. */
+the index.
+@return TRUE if ok */
static
ibool
btr_index_page_validate(
/*====================*/
- /* out: TRUE if ok */
- buf_block_t* block, /* in: index page */
- dict_index_t* index) /* in: index */
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index) /*!< in: index */
{
page_cur_t cur;
ibool ret = TRUE;
@@ -3232,16 +3296,15 @@ btr_index_page_validate(
return(ret);
}
-/****************************************************************
+/************************************************************//**
Report an error on one page of an index tree. */
static
void
btr_validate_report1(
/*=================*/
- /* out: TRUE if ok */
- dict_index_t* index, /* in: index */
- ulint level, /* in: B-tree level */
- const buf_block_t* block) /* in: index page */
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: B-tree level */
+ const buf_block_t* block) /*!< in: index page */
{
fprintf(stderr, "InnoDB: Error in page %lu of ",
buf_block_get_page_no(block));
@@ -3252,17 +3315,16 @@ btr_validate_report1(
putc('\n', stderr);
}
-/****************************************************************
+/************************************************************//**
Report an error on two pages of an index tree. */
static
void
btr_validate_report2(
/*=================*/
- /* out: TRUE if ok */
- const dict_index_t* index, /* in: index */
- ulint level, /* in: B-tree level */
- const buf_block_t* block1, /* in: first index page */
- const buf_block_t* block2) /* in: second index page */
+ const dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: B-tree level */
+ const buf_block_t* block1, /*!< in: first index page */
+ const buf_block_t* block2) /*!< in: second index page */
{
fprintf(stderr, "InnoDB: Error in pages %lu and %lu of ",
buf_block_get_page_no(block1),
@@ -3274,16 +3336,16 @@ btr_validate_report2(
putc('\n', stderr);
}
-/****************************************************************
-Validates index tree level. */
+/************************************************************//**
+Validates index tree level.
+@return TRUE if ok */
static
ibool
btr_validate_level(
/*===============*/
- /* out: TRUE if ok */
- dict_index_t* index, /* in: index tree */
- trx_t* trx, /* in: transaction or NULL */
- ulint level) /* in: level number */
+ dict_index_t* index, /*!< in: index tree */
+ trx_t* trx, /*!< in: transaction or NULL */
+ ulint level) /*!< in: level number */
{
ulint space;
ulint zip_size;
@@ -3620,15 +3682,15 @@ node_ptr_fails:
return(ret);
}
-/******************************************************************
-Checks the consistency of an index tree. */
+/**************************************************************//**
+Checks the consistency of an index tree.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_validate_index(
/*===============*/
- /* out: TRUE if ok */
- dict_index_t* index, /* in: index */
- trx_t* trx) /* in: transaction or NULL */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx) /*!< in: transaction or NULL */
{
mtr_t mtr;
page_t* root;
@@ -3654,3 +3716,4 @@ btr_validate_index(
return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index ee5b2fc5701..ce07b99c611 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file btr/btr0cur.c
The index tree cursor
All changes that row operations make to a B-tree or the records
@@ -46,6 +47,9 @@ Created 10/16/1994 Heikki Tuuri
#include "btr0cur.ic"
#endif
+#include "row0upd.h"
+#ifndef UNIV_HOTBACKUP
+#include "mtr0log.h"
#include "page0page.h"
#include "page0zip.h"
#include "rem0rec.h"
@@ -53,7 +57,6 @@ Created 10/16/1994 Heikki Tuuri
#include "buf0lru.h"
#include "btr0btr.h"
#include "btr0sea.h"
-#include "row0upd.h"
#include "trx0rec.h"
#include "trx0roll.h" /* trx_is_recv() */
#include "que0que.h"
@@ -64,36 +67,49 @@ Created 10/16/1994 Heikki Tuuri
#include "zlib.h"
#ifdef UNIV_DEBUG
-/* If the following is set to TRUE, this module prints a lot of
+/** If the following is set to TRUE, this module prints a lot of
trace information of individual record operations */
UNIV_INTERN ibool btr_cur_print_record_ops = FALSE;
#endif /* UNIV_DEBUG */
+/** Number of searches down the B-tree in btr_cur_search_to_nth_level(). */
UNIV_INTERN ulint btr_cur_n_non_sea = 0;
+/** Number of successful adaptive hash index lookups in
+btr_cur_search_to_nth_level(). */
UNIV_INTERN ulint btr_cur_n_sea = 0;
+/** Old value of btr_cur_n_non_sea. Copied by
+srv_refresh_innodb_monitor_stats(). Referenced by
+srv_printf_innodb_monitor(). */
UNIV_INTERN ulint btr_cur_n_non_sea_old = 0;
+/** Old value of btr_cur_n_sea. Copied by
+srv_refresh_innodb_monitor_stats(). Referenced by
+srv_printf_innodb_monitor(). */
UNIV_INTERN ulint btr_cur_n_sea_old = 0;
-/* In the optimistic insert, if the insert does not fit, but this much space
+/** In the optimistic insert, if the insert does not fit, but this much space
can be released by page reorganize, then it is reorganized */
-
#define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
-/* The structure of a BLOB part header */
+/** The structure of a BLOB part header */
+/* @{ */
/*--------------------------------------*/
-#define BTR_BLOB_HDR_PART_LEN 0 /* BLOB part len on this
+#define BTR_BLOB_HDR_PART_LEN 0 /*!< BLOB part len on this
page */
-#define BTR_BLOB_HDR_NEXT_PAGE_NO 4 /* next BLOB part page no,
+#define BTR_BLOB_HDR_NEXT_PAGE_NO 4 /*!< next BLOB part page no,
FIL_NULL if none */
/*--------------------------------------*/
-#define BTR_BLOB_HDR_SIZE 8
+#define BTR_BLOB_HDR_SIZE 8 /*!< Size of a BLOB
+ part header, in bytes */
+/* @} */
+#endif /* !UNIV_HOTBACKUP */
-/* A BLOB field reference full of zero, for use in assertions and tests.
+/** 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(). */
UNIV_INTERN const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE];
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Marks all extern fields in a record as owned by the record. This function
should be called if the delete mark of a record is removed: a not delete
marked record always owns all its extern fields. */
@@ -101,78 +117,76 @@ static
void
btr_cur_unmark_extern_fields(
/*=========================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
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() */
- mtr_t* mtr); /* in: mtr, or NULL if not logged */
-/***********************************************************************
+ 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() */
+ mtr_t* mtr); /*!< in: mtr, or NULL if not logged */
+/*******************************************************************//**
Adds path information to the cursor for the current page, for which
the binary search has been performed. */
static
void
btr_cur_add_path_info(
/*==================*/
- btr_cur_t* cursor, /* in: cursor positioned on a page */
- ulint height, /* in: height of the page in tree;
+ btr_cur_t* cursor, /*!< in: cursor positioned on a page */
+ ulint height, /*!< in: height of the page in tree;
0 means leaf node */
- ulint root_height); /* in: root node height in tree */
-/***************************************************************
+ ulint root_height); /*!< in: root node height in tree */
+/***********************************************************//**
Frees the externally stored fields for a record, if the field is mentioned
in the update vector. */
static
void
btr_rec_free_updated_extern_fields(
/*===============================*/
- dict_index_t* index, /* in: index of rec; the index tree MUST be
+ dict_index_t* index, /*!< in: index of rec; the index tree MUST be
X-latched */
- rec_t* rec, /* in: record */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ 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 upd_t* update, /* in: update vector */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr); /* in: mini-transaction handle which contains
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update, /*!< in: update vector */
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr); /*!< in: mini-transaction handle which contains
an X-latch to record page and to the tree */
-/***************************************************************
+/***********************************************************//**
Frees the externally stored fields for a record. */
static
void
btr_rec_free_externally_stored_fields(
/*==================================*/
- dict_index_t* index, /* in: index of the data, the index
+ 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) */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr); /* in: mini-transaction handle which contains
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr); /*!< in: mini-transaction handle which contains
an X-latch to record page and to the index
tree */
-/***************************************************************
-Gets the externally stored size of a record, in units of a database page. */
+/***********************************************************//**
+Gets the externally stored size of a record, in units of a database page.
+@return externally stored part, in units of a database page */
static
ulint
btr_rec_get_externally_stored_len(
/*==============================*/
- /* out: externally stored part,
- in units of a database page */
- rec_t* rec, /* in: record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+#endif /* !UNIV_HOTBACKUP */
-/**********************************************************
+/******************************************************//**
The following function is used to set the deleted bit of a record. */
UNIV_INLINE
void
btr_rec_set_deleted_flag(
/*=====================*/
- /* out: TRUE on success;
- FALSE on page_zip overflow */
- rec_t* rec, /* in/out: physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page (or NULL) */
- ulint flag) /* in: nonzero if delete marked */
+ rec_t* rec, /*!< in/out: physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page (or NULL) */
+ ulint flag) /*!< in: nonzero if delete marked */
{
if (page_rec_is_comp(rec)) {
rec_set_deleted_flag_new(rec, page_zip, flag);
@@ -182,23 +196,24 @@ btr_rec_set_deleted_flag(
}
}
+#ifndef UNIV_HOTBACKUP
/*==================== B-TREE SEARCH =========================*/
-/************************************************************************
+/********************************************************************//**
Latches the leaf page or pages requested. */
static
void
btr_cur_latch_leaves(
/*=================*/
- page_t* page, /* in: leaf page where the search
+ page_t* page, /*!< in: leaf page where the search
converged */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the leaf */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_cur_t* cursor, /* in: cursor */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number of the leaf */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_cur_t* cursor, /*!< in: cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint mode;
ulint left_page_no;
@@ -288,7 +303,7 @@ btr_cur_latch_leaves(
ut_error;
}
-/************************************************************************
+/********************************************************************//**
Searches an index tree and positions a tree cursor on a given level.
NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
to node pointer page number fields on the upper levels of the tree!
@@ -304,15 +319,15 @@ UNIV_INTERN
void
btr_cur_search_to_nth_level(
/*========================*/
- 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
+ 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! */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
Inserts should always be made using
PAGE_CUR_LE to search the position! */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
BTR_INSERT and BTR_ESTIMATE;
cursor->left_block is used to store a pointer
to the left neighbor page, in the cases
@@ -322,12 +337,12 @@ btr_cur_search_to_nth_level(
on the cursor page, we assume
the caller uses his search latch
to protect the record! */
- btr_cur_t* cursor, /* in/out: tree cursor; the cursor page is
+ btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
- ulint has_search_latch,/* in: info on the latch mode the
+ ulint has_search_latch,/*!< in: info on the latch mode the
caller currently has on btr_search_latch:
RW_S_LATCH, or 0 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
page_t* page;
@@ -658,18 +673,18 @@ func_exit:
}
}
-/*********************************************************************
+/*****************************************************************//**
Opens a cursor at either end of an index. */
UNIV_INTERN
void
btr_cur_open_at_index_side(
/*=======================*/
- ibool from_left, /* in: TRUE if open to the low end,
+ ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: latch mode */
- btr_cur_t* cursor, /* in: cursor */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: latch mode */
+ btr_cur_t* cursor, /*!< in: cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
ulint page_no;
@@ -789,16 +804,16 @@ btr_cur_open_at_index_side(
}
}
-/**************************************************************************
+/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INTERN
void
btr_cur_open_at_rnd_pos(
/*====================*/
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_cur_t* cursor, /* in/out: B-tree cursor */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_cur_t* cursor, /*!< in/out: B-tree cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
ulint page_no;
@@ -873,23 +888,22 @@ btr_cur_open_at_rnd_pos(
/*==================== B-TREE INSERT =========================*/
-/*****************************************************************
+/*************************************************************//**
Inserts a record if there is enough space, or if enough space can
be freed by reorganizing. Differs from btr_cur_optimistic_insert because
no heuristics is applied to whether it pays to use CPU time for
-reorganizing the page or not. */
+reorganizing the page or not.
+@return pointer to inserted record if succeed, else NULL */
static
rec_t*
btr_cur_insert_if_possible(
/*=======================*/
- /* out: pointer to inserted record if succeed,
- else NULL */
- btr_cur_t* cursor, /* in: cursor on page after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
- const dtuple_t* tuple, /* in: tuple to insert; the size info need not
+ const dtuple_t* tuple, /*!< in: tuple to insert; the size info need not
have been stored to tuple */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr) /* in: mtr */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
buf_block_t* block;
@@ -922,28 +936,28 @@ btr_cur_insert_if_possible(
return(rec);
}
-/*****************************************************************
-For an insert, checks the locks and does the undo logging if desired. */
+/*************************************************************//**
+For an insert, checks the locks and does the undo logging if desired.
+@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
UNIV_INLINE
ulint
btr_cur_ins_lock_and_undo(
/*======================*/
- /* out: DB_SUCCESS, DB_WAIT_LOCK,
- DB_FAIL, or error number */
- ulint flags, /* in: undo logging and locking flags: if
+ ulint flags, /*!< in: undo logging and locking flags: if
not zero, the parameters index and thr
should be specified */
- btr_cur_t* cursor, /* in: cursor on page after which to insert */
- const dtuple_t* entry, /* in: entry to insert */
- que_thr_t* thr, /* in: query thread or NULL */
- ibool* inherit)/* out: TRUE if the inserted new record maybe
+ btr_cur_t* cursor, /*!< in: cursor on page after which to insert */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+ ibool* inherit)/*!< out: TRUE if the inserted new record maybe
should inherit LOCK_GAP type locks from the
successor record */
{
dict_index_t* index;
ulint err;
rec_t* rec;
- dulint roll_ptr;
+ roll_ptr_t roll_ptr;
/* Check if we have to wait for a lock: enqueue an explicit lock
request if yes */
@@ -953,7 +967,7 @@ btr_cur_ins_lock_and_undo(
err = lock_rec_insert_check_and_lock(flags, rec,
btr_cur_get_block(cursor),
- index, thr, inherit);
+ index, thr, mtr, inherit);
if (err != DB_SUCCESS) {
@@ -984,15 +998,15 @@ btr_cur_ins_lock_and_undo(
}
#ifdef UNIV_DEBUG
-/*****************************************************************
+/*************************************************************//**
Report information about a transaction. */
static
void
btr_cur_trx_report(
/*===============*/
- trx_t* trx, /* in: transaction */
- const dict_index_t* index, /* in: index */
- const char* op) /* in: operation */
+ trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index, /*!< in: index */
+ const char* op) /*!< in: operation */
{
fprintf(stderr, "Trx with id " TRX_ID_FMT " going to ",
TRX_ID_PREP_PRINTF(trx->id));
@@ -1002,32 +1016,31 @@ btr_cur_trx_report(
}
#endif /* UNIV_DEBUG */
-/*****************************************************************
+/*************************************************************//**
Tries to perform an insert to a page in an index tree, next to cursor.
It is assumed that mtr holds an x-latch on the page. The operation does
not succeed if there is too little space on the page. If there is just
one record on the page, the insert will always succeed; this is to
-prevent trying to split a page with just one record. */
+prevent trying to split a page with just one record.
+@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
UNIV_INTERN
ulint
btr_cur_optimistic_insert(
/*======================*/
- /* out: DB_SUCCESS, DB_WAIT_LOCK,
- DB_FAIL, or error number */
- ulint flags, /* in: undo logging and locking flags: if not
+ ulint flags, /*!< in: undo logging and locking flags: if not
zero, the parameters index and thr should be
specified */
- btr_cur_t* cursor, /* in: cursor on page after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
- dtuple_t* entry, /* in/out: entry to insert */
- rec_t** rec, /* out: pointer to inserted record if
+ dtuple_t* entry, /*!< in/out: entry to insert */
+ rec_t** rec, /*!< out: pointer to inserted record if
succeed */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or
NULL */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr, /* in: query thread or NULL */
- mtr_t* mtr) /* in: mtr; if this function returns
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr) /*!< in: mtr; if this function returns
DB_SUCCESS on a leaf page of a secondary
index in a compressed tablespace, the
mtr must be committed before latching
@@ -1167,7 +1180,8 @@ fail_err:
}
/* Check locks and write to the undo log, if specified */
- err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &inherit);
+ err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
+ thr, mtr, &inherit);
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
@@ -1247,9 +1261,7 @@ fail_err:
buf_block_get_page_no(block), max_size,
rec_size + PAGE_DIR_SLOT_SIZE, index->type);
#endif
- if (leaf
- && !dict_index_is_clust(index)
- && !dict_index_is_ibuf(index)) {
+ if (leaf && !dict_index_is_clust(index)) {
/* Update the free bits of the B-tree page in the
insert buffer bitmap. */
@@ -1280,33 +1292,33 @@ fail_err:
return(DB_SUCCESS);
}
-/*****************************************************************
+/*************************************************************//**
Performs an insert on a page of an index tree. It is assumed that mtr
holds an x-latch on the tree and on the cursor page. If the insert is
made on the leaf level, to avoid deadlocks, mtr must also own x-latches
-to brothers of page, if those brothers exist. */
+to brothers of page, if those brothers exist.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
btr_cur_pessimistic_insert(
/*=======================*/
- /* out: DB_SUCCESS or error number */
- ulint flags, /* in: undo logging and locking flags: if not
+ ulint flags, /*!< in: undo logging and locking flags: if not
zero, the parameter thr should be
specified; if no undo logging is specified,
then the caller must have reserved enough
free extents in the file space so that the
insertion will certainly succeed */
- btr_cur_t* cursor, /* in: cursor after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor after which to insert;
cursor stays valid */
- dtuple_t* entry, /* in/out: entry to insert */
- rec_t** rec, /* out: pointer to inserted record if
+ dtuple_t* entry, /*!< in/out: entry to insert */
+ rec_t** rec, /*!< out: pointer to inserted record if
succeed */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or
NULL */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr, /* in: query thread or NULL */
- mtr_t* mtr) /* in: mtr */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index = cursor->index;
ulint zip_size = dict_table_zip_size(index->table);
@@ -1343,7 +1355,8 @@ btr_cur_pessimistic_insert(
/* Retry with a pessimistic insert. Check locks and write to undo log,
if specified */
- err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &dummy_inh);
+ err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
+ thr, mtr, &dummy_inh);
if (err != DB_SUCCESS) {
@@ -1424,21 +1437,21 @@ btr_cur_pessimistic_insert(
/*==================== B-TREE UPDATE =========================*/
-/*****************************************************************
-For an update, checks the locks and does the undo logging. */
+/*************************************************************//**
+For an update, checks the locks and does the undo logging.
+@return DB_SUCCESS, DB_WAIT_LOCK, or error number */
UNIV_INLINE
ulint
btr_cur_upd_lock_and_undo(
/*======================*/
- /* out: DB_SUCCESS, DB_WAIT_LOCK, or error
- number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on record to update */
- const upd_t* update, /* in: update vector */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on record to update */
+ const upd_t* update, /*!< in: update vector */
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- dulint* roll_ptr)/* out: roll pointer */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+ roll_ptr_t* roll_ptr)/*!< out: roll pointer */
{
dict_index_t* index;
rec_t* rec;
@@ -1454,7 +1467,7 @@ btr_cur_upd_lock_and_undo(
record */
return(lock_sec_rec_modify_check_and_lock(
flags, btr_cur_get_block(cursor), rec,
- index, thr));
+ index, thr, mtr));
}
/* Check if we have to wait for a lock: enqueue an explicit lock
@@ -1488,19 +1501,19 @@ btr_cur_upd_lock_and_undo(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Writes a redo log record of updating a record in-place. */
UNIV_INLINE
void
btr_cur_update_in_place_log(
/*========================*/
- ulint flags, /* in: flags */
- rec_t* rec, /* in: record */
- dict_index_t* index, /* in: index where cursor positioned */
- const upd_t* update, /* in: update vector */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr, /* in: roll ptr */
- mtr_t* mtr) /* in: mtr */
+ ulint flags, /*!< in: flags */
+ rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: index where cursor positioned */
+ const upd_t* update, /*!< in: update vector */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr, /*!< in: roll ptr */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
page_t* page = page_align(rec);
@@ -1535,29 +1548,30 @@ btr_cur_update_in_place_log(
row_upd_index_write_log(update, log_ptr, mtr);
}
+#endif /* UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of updating a record in-place. */
+/***********************************************************//**
+Parses a redo log record of updating a record in-place.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_update_in_place(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index) /* in: index corresponding to page */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index) /*!< in: index corresponding to page */
{
- ulint flags;
- rec_t* rec;
- upd_t* update;
- ulint pos;
- dulint trx_id;
- dulint roll_ptr;
- ulint rec_offset;
- mem_heap_t* heap;
- ulint* offsets;
+ ulint flags;
+ rec_t* rec;
+ upd_t* update;
+ ulint pos;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
+ ulint rec_offset;
+ mem_heap_t* heap;
+ ulint* offsets;
if (end_ptr < ptr + 1) {
@@ -1614,26 +1628,29 @@ func_exit:
return(ptr);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
See if there is enough place in the page modification log to log
-an update-in-place. */
+an update-in-place.
+@return TRUE if enough place */
static
ibool
btr_cur_update_alloc_zip(
/*=====================*/
- /* out: TRUE if enough place */
- page_zip_des_t* page_zip,/* in/out: compressed page */
- buf_block_t* block, /* in/out: buffer page */
- dict_index_t* index, /* in: the index corresponding to the block */
- ulint length, /* in: size needed */
- mtr_t* mtr) /* in: mini-transaction */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ buf_block_t* block, /*!< in/out: buffer page */
+ dict_index_t* index, /*!< in: the index corresponding to the block */
+ ulint length, /*!< in: size needed */
+ ibool create, /*!< in: TRUE=delete-and-insert,
+ FALSE=update-in-place */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ut_a(page_zip == buf_block_get_page_zip(block));
ut_ad(page_zip);
ut_ad(!dict_index_is_ibuf(index));
if (page_zip_available(page_zip, dict_index_is_clust(index),
- length, 0)) {
+ length, create)) {
return(TRUE);
}
@@ -1660,7 +1677,7 @@ btr_cur_update_alloc_zip(
the free space available on the page. */
if (!page_zip_available(page_zip, dict_index_is_clust(index),
- length, 0)) {
+ length, create)) {
/* Out of space: reset the free bits. */
if (!dict_index_is_clust(index)
&& page_is_leaf(buf_block_get_frame(block))) {
@@ -1672,23 +1689,23 @@ btr_cur_update_alloc_zip(
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Updates a record when the update causes no size changes in its fields.
-We assume here that the ordering fields of the record do not change. */
+We assume here that the ordering fields of the record do not change.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
btr_cur_update_in_place(
/*====================*/
- /* out: DB_SUCCESS or error number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on the record to update;
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- const upd_t* update, /* in: update vector */
- ulint cmpl_info,/* in: compiler info on secondary index
+ const upd_t* update, /*!< in: update vector */
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
dict_index_t* index;
@@ -1696,7 +1713,7 @@ btr_cur_update_in_place(
page_zip_des_t* page_zip;
ulint err;
rec_t* rec;
- dulint roll_ptr = ut_dulint_zero;
+ roll_ptr_t roll_ptr = ut_dulint_zero;
trx_t* trx;
ulint was_delete_marked;
mem_heap_t* heap = NULL;
@@ -1725,13 +1742,13 @@ btr_cur_update_in_place(
/* Check that enough space is available on the compressed page. */
if (UNIV_LIKELY_NULL(page_zip)
&& !btr_cur_update_alloc_zip(page_zip, block, index,
- rec_offs_size(offsets), mtr)) {
+ rec_offs_size(offsets), FALSE, mtr)) {
return(DB_ZIP_OVERFLOW);
}
/* Do lock checking and undo logging */
err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
- thr, &roll_ptr);
+ thr, mtr, &roll_ptr);
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
if (UNIV_LIKELY_NULL(heap)) {
@@ -1794,31 +1811,29 @@ btr_cur_update_in_place(
return(DB_SUCCESS);
}
-/*****************************************************************
+/*************************************************************//**
Tries to update a record on a page in an index tree. It is assumed that mtr
holds an x-latch on the page. The operation does not succeed if there is too
little space on the page or if the update would result in too empty a page,
so that tree compression is recommended. We assume here that the ordering
-fields of the record do not change. */
+fields of the record do not change.
+@return DB_SUCCESS, or DB_OVERFLOW if the updated record does not fit,
+DB_UNDERFLOW if the page would become too empty, or DB_ZIP_OVERFLOW if
+there is not enough space left on the compressed page */
UNIV_INTERN
ulint
btr_cur_optimistic_update(
/*======================*/
- /* out: DB_SUCCESS, or DB_OVERFLOW if the
- updated record does not fit, DB_UNDERFLOW
- if the page would become too empty, or
- DB_ZIP_OVERFLOW if there is not enough
- space left on the compressed page */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on the record to update;
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- const upd_t* update, /* in: update vector; this must also
+ const upd_t* update, /*!< in: update vector; this must also
contain trx id and roll ptr fields */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
dict_index_t* index;
@@ -1833,7 +1848,7 @@ btr_cur_optimistic_update(
ulint new_rec_size;
ulint old_rec_size;
dtuple_t* new_entry;
- dulint roll_ptr;
+ roll_ptr_t roll_ptr;
trx_t* trx;
mem_heap_t* heap;
ulint i;
@@ -1909,7 +1924,7 @@ any_extern:
if (UNIV_LIKELY_NULL(page_zip)
&& !btr_cur_update_alloc_zip(page_zip, block, index,
- new_rec_size, mtr)) {
+ new_rec_size, TRUE, mtr)) {
err = DB_ZIP_OVERFLOW;
goto err_exit;
}
@@ -1948,8 +1963,8 @@ any_extern:
}
/* Do lock checking and undo logging */
- err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, thr,
- &roll_ptr);
+ err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
+ thr, mtr, &roll_ptr);
if (err != DB_SUCCESS) {
err_exit:
mem_heap_free(heap);
@@ -2004,7 +2019,7 @@ err_exit:
return(DB_SUCCESS);
}
-/*****************************************************************
+/*************************************************************//**
If, in a split, a new supremum record was created as the predecessor of the
updated record, the supremum record must inherit exactly the locks on the
updated record. In the split it may have inherited locks from the successor
@@ -2014,9 +2029,9 @@ static
void
btr_cur_pess_upd_restore_supremum(
/*==============================*/
- buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: updated record */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: updated record */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
buf_block_t* prev_block;
@@ -2052,30 +2067,30 @@ btr_cur_pess_upd_restore_supremum(
page_rec_get_heap_no(rec));
}
-/*****************************************************************
+/*************************************************************//**
Performs an update of a record on a page of a tree. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. If the
update is made on the leaf level, to avoid deadlocks, mtr must also
own x-latches to brothers of page, if those brothers exist. We assume
-here that the ordering fields of the record do not change. */
+here that the ordering fields of the record do not change.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
btr_cur_pessimistic_update(
/*=======================*/
- /* out: DB_SUCCESS or error code */
- ulint flags, /* in: undo logging, locking, and rollback
+ ulint flags, /*!< in: undo logging, locking, and rollback
flags */
- btr_cur_t* cursor, /* in: cursor on the record to update */
- mem_heap_t** heap, /* in/out: pointer to memory heap, or NULL */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ btr_cur_t* cursor, /*!< in: cursor on the record to update */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or NULL */
- const upd_t* update, /* in: update vector; this is allowed also
+ const upd_t* update, /*!< in: update vector; this is allowed also
contain trx id and roll ptr fields, but
the values in update vector have no effect */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
big_rec_t* big_rec_vec = NULL;
@@ -2089,7 +2104,7 @@ btr_cur_pessimistic_update(
dtuple_t* new_entry;
ulint err;
ulint optim_err;
- dulint roll_ptr;
+ roll_ptr_t roll_ptr;
trx_t* trx;
ibool was_first;
ulint n_extents = 0;
@@ -2128,7 +2143,7 @@ btr_cur_pessimistic_update(
/* Do lock checking and undo logging */
err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
- thr, &roll_ptr);
+ thr, mtr, &roll_ptr);
if (err != DB_SUCCESS) {
return(err);
@@ -2303,6 +2318,19 @@ make_external:
ut_a(err == DB_SUCCESS);
ut_a(dummy_big_rec == NULL);
+ if (dict_index_is_sec_or_ibuf(index)) {
+ /* Update PAGE_MAX_TRX_ID in the index page header.
+ It was not updated by btr_cur_pessimistic_insert()
+ because of BTR_NO_LOCKING_FLAG. */
+ buf_block_t* rec_block;
+
+ rec_block = btr_cur_get_block(cursor);
+
+ page_update_max_trx_id(rec_block,
+ buf_block_get_page_zip(rec_block),
+ trx->id, mtr);
+ }
+
if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
/* The new inserted record owns its possible externally
stored fields */
@@ -2349,20 +2377,20 @@ return_after_reservations:
/*==================== B-TREE DELETE MARK AND UNMARK ===============*/
-/********************************************************************
+/****************************************************************//**
Writes the redo log record for delete marking or unmarking of an index
record. */
UNIV_INLINE
void
btr_cur_del_mark_set_clust_rec_log(
/*===============================*/
- ulint flags, /* in: flags */
- rec_t* rec, /* in: record */
- dict_index_t* index, /* in: index of the record */
- ibool val, /* in: value to set */
- trx_t* trx, /* in: deleting transaction */
- dulint roll_ptr,/* in: roll ptr to the undo log record */
- mtr_t* mtr) /* in: mtr */
+ ulint flags, /*!< in: flags */
+ rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: index of the record */
+ ibool val, /*!< in: value to set */
+ trx_t* trx, /*!< in: deleting transaction */
+ roll_ptr_t roll_ptr,/*!< in: roll ptr to the undo log record */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
ut_ad(flags < 256);
@@ -2394,28 +2422,29 @@ btr_cur_del_mark_set_clust_rec_log(
mlog_close(mtr, log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/********************************************************************
+/****************************************************************//**
Parses the redo log record for delete marking or unmarking of a clustered
-index record. */
+index record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_del_mark_set_clust_rec(
/*=================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index) /* in: index corresponding to page */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index) /*!< in: index corresponding to page */
{
- ulint flags;
- ulint val;
- ulint pos;
- dulint trx_id;
- dulint roll_ptr;
- ulint offset;
- rec_t* rec;
+ ulint flags;
+ ulint val;
+ ulint pos;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
+ ulint offset;
+ rec_t* rec;
ut_ad(!page
|| !!page_is_comp(page) == dict_table_is_comp(index->table));
@@ -2475,26 +2504,26 @@ btr_cur_parse_del_mark_set_clust_rec(
return(ptr);
}
-/***************************************************************
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
Marks a clustered index record deleted. Writes an undo log record to
undo log on this delete marking. Writes in the trx id field the id
of the deleting transaction, and in the roll ptr field pointer to the
-undo log record created. */
+undo log record created.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
UNIV_INTERN
ulint
btr_cur_del_mark_set_clust_rec(
/*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor */
- ibool val, /* in: value to set */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor */
+ ibool val, /*!< in: value to set */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
buf_block_t* block;
- dulint roll_ptr;
+ roll_ptr_t roll_ptr;
ulint err;
rec_t* rec;
page_zip_des_t* page_zip;
@@ -2567,16 +2596,16 @@ func_exit:
return(err);
}
-/********************************************************************
+/****************************************************************//**
Writes the redo log record for a delete mark setting of a secondary
index record. */
UNIV_INLINE
void
btr_cur_del_mark_set_sec_rec_log(
/*=============================*/
- rec_t* rec, /* in: record */
- ibool val, /* in: value to set */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record */
+ ibool val, /*!< in: value to set */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
ut_ad(val <= 1);
@@ -2599,19 +2628,20 @@ btr_cur_del_mark_set_sec_rec_log(
mlog_close(mtr, log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/********************************************************************
+/****************************************************************//**
Parses the redo log record for delete marking or unmarking of a secondary
-index record. */
+index record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_del_mark_set_sec_rec(
/*===============================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip)/* in/out: compressed page, or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip)/*!< in/out: compressed page, or NULL */
{
ulint val;
ulint offset;
@@ -2643,19 +2673,19 @@ btr_cur_parse_del_mark_set_sec_rec(
return(ptr);
}
-/***************************************************************
-Sets a secondary index record delete mark to TRUE or FALSE. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
+Sets a secondary index record delete mark to TRUE or FALSE.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
UNIV_INTERN
ulint
btr_cur_del_mark_set_sec_rec(
/*=========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- number */
- ulint flags, /* in: locking flag */
- btr_cur_t* cursor, /* in: cursor */
- ibool val, /* in: value to set */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
+ ulint flags, /*!< in: locking flag */
+ btr_cur_t* cursor, /*!< in: cursor */
+ ibool val, /*!< in: value to set */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
rec_t* rec;
@@ -2674,7 +2704,7 @@ btr_cur_del_mark_set_sec_rec(
err = lock_sec_rec_modify_check_and_lock(flags,
btr_cur_get_block(cursor),
- rec, cursor->index, thr);
+ rec, cursor->index, thr, mtr);
if (err != DB_SUCCESS) {
return(err);
@@ -2698,19 +2728,19 @@ btr_cur_del_mark_set_sec_rec(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Clear a secondary index record's delete mark. This function is only
used by the insert buffer insert merge mechanism. */
UNIV_INTERN
void
btr_cur_del_unmark_for_ibuf(
/*========================*/
- rec_t* rec, /* in/out: record to delete unmark */
- page_zip_des_t* page_zip, /* in/out: compressed page
+ rec_t* rec, /*!< in/out: record to delete unmark */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page
corresponding to rec, or NULL
when the tablespace is
uncompressed */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
/* We do not need to reserve btr_search_latch, as the page has just
been read to the buffer pool and there cannot be a hash index to it. */
@@ -2722,21 +2752,21 @@ btr_cur_del_unmark_for_ibuf(
/*==================== B-TREE RECORD REMOVE =========================*/
-/*****************************************************************
+/*************************************************************//**
Tries to compress a page of the tree if it seems useful. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. To avoid
deadlocks, mtr must also own x-latches to brothers of page, if those
brothers exist. NOTE: it is assumed that the caller has reserved enough
-free extents so that the compression will always succeed if done! */
+free extents so that the compression will always succeed if done!
+@return TRUE if compression occurred */
UNIV_INTERN
ibool
btr_cur_compress_if_useful(
/*=======================*/
- /* out: TRUE if compression occurred */
- btr_cur_t* cursor, /* in: cursor on the page to compress;
+ btr_cur_t* cursor, /*!< in: cursor on the page to compress;
cursor does not stay valid if compression
occurs */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr_memo_contains(mtr,
dict_index_get_lock(btr_cur_get_index(cursor)),
@@ -2748,21 +2778,20 @@ btr_cur_compress_if_useful(
&& btr_compress(cursor, mtr));
}
-/***********************************************************
+/*******************************************************//**
Removes the record on which the tree cursor is positioned on a leaf page.
It is assumed that the mtr has an x-latch on the page where the cursor is
-positioned, but no latch on the whole tree. */
+positioned, but no latch on the whole tree.
+@return TRUE if success, i.e., the page did not become too empty */
UNIV_INTERN
ibool
btr_cur_optimistic_delete(
/*======================*/
- /* out: TRUE if success, i.e., the page
- did not become too empty */
- btr_cur_t* cursor, /* in: cursor on leaf page, on the record to
+ btr_cur_t* cursor, /*!< in: cursor on leaf page, on the record to
delete; cursor stays valid: if deletion
succeeds, on function exit it points to the
successor of the deleted record */
- mtr_t* mtr) /* in: mtr; if this function returns
+ mtr_t* mtr) /*!< in: mtr; if this function returns
TRUE on a leaf page of a secondary
index, the mtr must be committed
before latching any further pages */
@@ -2835,33 +2864,33 @@ btr_cur_optimistic_delete(
return(no_compress_needed);
}
-/*****************************************************************
+/*************************************************************//**
Removes the record on which the tree cursor is positioned. Tries
to compress the page if its fillfactor drops below a threshold
or if it is the only page on the level. It is assumed that mtr holds
an x-latch on the tree and on the cursor page. To avoid deadlocks,
mtr must also own x-latches to brothers of page, if those brothers
-exist. */
+exist.
+@return TRUE if compression occurred */
UNIV_INTERN
ibool
btr_cur_pessimistic_delete(
/*=======================*/
- /* out: TRUE if compression occurred */
- ulint* err, /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
+ ulint* err, /*!< out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
the latter may occur because we may have
to update node pointers on upper levels,
and in the case of variable length keys
these may actually grow in size */
- ibool has_reserved_extents, /* in: TRUE if the
+ ibool has_reserved_extents, /*!< in: TRUE if the
caller has already reserved enough free
extents so that he knows that the operation
will succeed */
- btr_cur_t* cursor, /* in: cursor on the record to delete;
+ btr_cur_t* cursor, /*!< in: cursor on the record to delete;
if compression does not occur, the cursor
stays valid: it points to successor of
deleted record on function exit */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr) /* in: mtr */
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
page_t* page;
@@ -2998,17 +3027,17 @@ return_after_reservations:
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Adds path information to the cursor for the current page, for which
the binary search has been performed. */
static
void
btr_cur_add_path_info(
/*==================*/
- btr_cur_t* cursor, /* in: cursor positioned on a page */
- ulint height, /* in: height of the page in tree;
+ btr_cur_t* cursor, /*!< in: cursor positioned on a page */
+ ulint height, /*!< in: height of the page in tree;
0 means leaf node */
- ulint root_height) /* in: root node height in tree */
+ ulint root_height) /*!< in: root node height in tree */
{
btr_path_t* slot;
rec_t* rec;
@@ -3038,18 +3067,18 @@ btr_cur_add_path_info(
slot->n_recs = page_get_n_recs(page_align(rec));
}
-/***********************************************************************
-Estimates the number of rows in a given index range. */
+/*******************************************************************//**
+Estimates the number of rows in a given index range.
+@return estimated number of rows */
UNIV_INTERN
ib_int64_t
btr_estimate_n_rows_in_range(
/*=========================*/
- /* out: estimated number of rows */
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple1, /* in: range start, may also be empty tuple */
- ulint mode1, /* in: search mode for range start */
- const dtuple_t* tuple2, /* in: range end, may also be empty tuple */
- ulint mode2) /* in: search mode for range end */
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
+ ulint mode1, /*!< in: search mode for range start */
+ const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
+ ulint mode2) /*!< in: search mode for range end */
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
btr_path_t path2[BTR_PATH_ARRAY_N_SLOTS];
@@ -3186,7 +3215,7 @@ btr_estimate_n_rows_in_range(
}
}
-/***********************************************************************
+/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
The estimates are stored in the array index->stat_n_diff_key_vals. */
@@ -3194,7 +3223,7 @@ UNIV_INTERN
void
btr_estimate_number_of_different_key_vals(
/*======================================*/
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
btr_cur_t cursor;
page_t* page;
@@ -3204,7 +3233,7 @@ btr_estimate_number_of_different_key_vals(
ulint matched_bytes;
ib_int64_t n_recs = 0;
ib_int64_t* n_diff;
- ib_int64_t* n_not_nulls;
+ ib_int64_t* n_not_nulls= 0;
ullint n_sample_pages; /* number of pages to sample */
ulint not_empty_flag = 0;
ulint total_external_size = 0;
@@ -3267,21 +3296,21 @@ btr_estimate_number_of_different_key_vals(
}
while (rec != supremum) {
- rec_t* next_rec;
+ rec_t* next_rec;
/* count recs */
if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
n_recs++;
for (j = 0; j <= n_cols; j++) {
ulint f_len;
- rec_get_nth_field(rec, offsets_rec,
- j, &f_len);
+ (void) rec_get_nth_field(rec,
+ offsets_rec,
+ j, &f_len);
if (f_len == UNIV_SQL_NULL)
break;
n_not_nulls[j]++;
}
}
-
next_rec = page_rec_get_next(rec);
if (next_rec == supremum) {
break;
@@ -3403,16 +3432,15 @@ btr_estimate_number_of_different_key_vals(
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
-/***************************************************************
-Gets the externally stored size of a record, in units of a database page. */
+/***********************************************************//**
+Gets the externally stored size of a record, in units of a database page.
+@return externally stored part, in units of a database page */
static
ulint
btr_rec_get_externally_stored_len(
/*==============================*/
- /* out: externally stored part,
- in units of a database page */
- rec_t* rec, /* in: record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
byte* data;
@@ -3442,20 +3470,20 @@ btr_rec_get_externally_stored_len(
return(total_extern_len / UNIV_PAGE_SIZE);
}
-/***********************************************************************
+/*******************************************************************//**
Sets the ownership bit of an externally stored field in a record. */
static
void
btr_cur_set_ownership_of_extern_field(
/*==================================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
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() */
- ulint i, /* in: field number */
- ibool val, /* in: value to set */
- mtr_t* mtr) /* in: mtr, or NULL if not logged */
+ 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() */
+ ulint i, /*!< in: field number */
+ ibool val, /*!< in: value to set */
+ mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
{
byte* data;
ulint local_len;
@@ -3487,7 +3515,7 @@ btr_cur_set_ownership_of_extern_field(
}
}
-/***********************************************************************
+/*******************************************************************//**
Marks not updated extern fields as not-owned by this record. The ownership
is transferred to the updated record which is inserted elsewhere in the
index tree. In purge only the owner of externally stored field is allowed
@@ -3496,13 +3524,13 @@ UNIV_INTERN
void
btr_cur_mark_extern_inherited_fields(
/*=================================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
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 upd_t* update, /* in: update vector */
- mtr_t* mtr) /* in: mtr, or NULL if not logged */
+ 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 upd_t* update, /*!< in: update vector */
+ mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
{
ulint n;
ulint j;
@@ -3542,7 +3570,7 @@ updated:
}
}
-/***********************************************************************
+/*******************************************************************//**
The complement of the previous function: in an update entry may inherit
some externally stored fields from a record. We must mark them as inherited
in entry, so that they are not freed in a rollback. */
@@ -3550,9 +3578,9 @@ UNIV_INTERN
void
btr_cur_mark_dtuple_inherited_extern(
/*=================================*/
- dtuple_t* entry, /* in/out: updated entry to be
+ dtuple_t* entry, /*!< in/out: updated entry to be
inserted to clustered index */
- const upd_t* update) /* in: update vector */
+ const upd_t* update) /*!< in: update vector */
{
ulint i;
@@ -3586,7 +3614,7 @@ is_updated:
}
}
-/***********************************************************************
+/*******************************************************************//**
Marks all extern fields in a record as owned by the record. This function
should be called if the delete mark of a record is removed: a not delete
marked record always owns all its extern fields. */
@@ -3594,12 +3622,12 @@ static
void
btr_cur_unmark_extern_fields(
/*=========================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
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() */
- mtr_t* mtr) /* in: mtr, or NULL if not logged */
+ 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() */
+ mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
{
ulint n;
ulint i;
@@ -3621,13 +3649,13 @@ btr_cur_unmark_extern_fields(
}
}
-/***********************************************************************
+/*******************************************************************//**
Marks all extern fields in a dtuple as owned by the record. */
UNIV_INTERN
void
btr_cur_unmark_dtuple_extern_fields(
/*================================*/
- dtuple_t* entry) /* in/out: clustered index entry */
+ dtuple_t* entry) /*!< in/out: clustered index entry */
{
ulint i;
@@ -3644,18 +3672,18 @@ btr_cur_unmark_dtuple_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. */
+mark as extern storage in a record inserted for an update.
+@return number of flagged external columns */
UNIV_INTERN
ulint
btr_push_update_extern_fields(
/*==========================*/
- /* out: number of flagged external columns */
- dtuple_t* tuple, /* in/out: data tuple */
- const upd_t* update, /* in: update vector */
- mem_heap_t* heap) /* in: memory heap */
+ 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;
@@ -3724,41 +3752,40 @@ btr_push_update_extern_fields(
return(n_pushed);
}
-/***********************************************************************
-Returns the length of a BLOB part stored on the header page. */
+/*******************************************************************//**
+Returns the length of a BLOB part stored on the header page.
+@return part length */
static
ulint
btr_blob_get_part_len(
/*==================*/
- /* out: part length */
- const byte* blob_header) /* in: blob header */
+ const byte* blob_header) /*!< in: blob header */
{
return(mach_read_from_4(blob_header + BTR_BLOB_HDR_PART_LEN));
}
-/***********************************************************************
-Returns the page number where the next BLOB part is stored. */
+/*******************************************************************//**
+Returns the page number where the next BLOB part is stored.
+@return page number or FIL_NULL if no more pages */
static
ulint
btr_blob_get_next_page_no(
/*======================*/
- /* out: page number or FIL_NULL if
- no more pages */
- const byte* blob_header) /* in: blob header */
+ const byte* blob_header) /*!< in: blob header */
{
return(mach_read_from_4(blob_header + BTR_BLOB_HDR_NEXT_PAGE_NO));
}
-/***********************************************************************
+/*******************************************************************//**
Deallocate a buffer block that was reserved for a BLOB part. */
static
void
btr_blob_free(
/*==========*/
- buf_block_t* block, /* in: buffer block */
- ibool all, /* in: TRUE=remove also the compressed page
+ buf_block_t* block, /*!< in: buffer block */
+ ibool all, /*!< in: TRUE=remove also the compressed page
if there is one */
- mtr_t* mtr) /* in: mini-transaction to commit */
+ mtr_t* mtr) /*!< in: mini-transaction to commit */
{
ulint space = buf_block_get_space(block);
ulint page_no = buf_block_get_page_no(block);
@@ -3798,27 +3825,27 @@ btr_blob_free(
mutex_exit(&block->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
The fields are stored on pages allocated from leaf node
-file segment of the index tree. */
+file segment of the index tree.
+@return DB_SUCCESS or error */
UNIV_INTERN
ulint
btr_store_big_rec_extern_fields(
/*============================*/
- /* out: DB_SUCCESS or error */
- dict_index_t* index, /* in: index of rec; the index tree
+ dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
- buf_block_t* rec_block, /* in/out: block containing rec */
- rec_t* rec, /* in/out: record */
- const ulint* offsets, /* in: rec_get_offsets(rec, index);
+ buf_block_t* rec_block, /*!< in/out: block containing rec */
+ rec_t* rec, /*!< in/out: record */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index);
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
- big_rec_t* big_rec_vec, /* in: vector containing fields
+ big_rec_t* big_rec_vec, /*!< in: vector containing fields
to be stored externally */
- mtr_t* local_mtr __attribute__((unused))) /* in: mtr
+ mtr_t* local_mtr __attribute__((unused))) /*!< in: mtr
containing the latch to rec and to the
tree */
{
@@ -3959,10 +3986,21 @@ btr_store_big_rec_extern_fields(
int err;
page_zip_des_t* blob_page_zip;
- mach_write_to_2(page + FIL_PAGE_TYPE,
- prev_page_no == FIL_NULL
- ? FIL_PAGE_TYPE_ZBLOB
- : FIL_PAGE_TYPE_ZBLOB2);
+ /* Write FIL_PAGE_TYPE to the redo log
+ separately, before logging any other
+ changes to the page, so that the debug
+ assertions in
+ recv_parse_or_apply_log_rec_body() can
+ be made simpler. Before InnoDB Plugin
+ 1.0.4, the initialization of
+ FIL_PAGE_TYPE was logged as part of
+ the mlog_log_string() below. */
+
+ mlog_write_ulint(page + FIL_PAGE_TYPE,
+ prev_page_no == FIL_NULL
+ ? FIL_PAGE_TYPE_ZBLOB
+ : FIL_PAGE_TYPE_ZBLOB2,
+ MLOG_2BYTES, &mtr);
c_stream.next_out = page
+ FIL_PAGE_DATA;
@@ -4008,9 +4046,9 @@ btr_store_big_rec_extern_fields(
memset(page + page_zip_get_size(page_zip)
- c_stream.avail_out,
0, c_stream.avail_out);
- mlog_log_string(page + FIL_PAGE_TYPE,
+ mlog_log_string(page + FIL_PAGE_FILE_FLUSH_LSN,
page_zip_get_size(page_zip)
- - FIL_PAGE_TYPE,
+ - FIL_PAGE_FILE_FLUSH_LSN,
&mtr);
/* Copy the page to compressed storage,
because it will be flushed to disk
@@ -4155,16 +4193,16 @@ next_zip_page:
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Check the FIL_PAGE_TYPE on an uncompressed BLOB page. */
static
void
btr_check_blob_fil_page_type(
/*=========================*/
- ulint space_id, /* in: space id */
- ulint page_no, /* in: page number */
- const page_t* page, /* in: page */
- ibool read) /* in: TRUE=read, FALSE=purge */
+ ulint space_id, /*!< in: space id */
+ ulint page_no, /*!< in: page number */
+ const page_t* page, /*!< in: page */
+ ibool read) /*!< in: TRUE=read, FALSE=purge */
{
ulint type = fil_page_get_type(page);
@@ -4193,7 +4231,7 @@ btr_check_blob_fil_page_type(
}
}
-/***********************************************************************
+/*******************************************************************//**
Frees the space in an externally stored field to the file space
management if the field in data is owned by the externally stored field,
in a rollback we may have the additional condition that the field must
@@ -4202,7 +4240,7 @@ UNIV_INTERN
void
btr_free_externally_stored_field(
/*=============================*/
- dict_index_t* index, /* in: index of the data, the index
+ dict_index_t* index, /*!< in: index of the data, the index
tree MUST be X-latched; if the tree
height is 1, then also the root page
must be X-latched! (this is relevant
@@ -4210,17 +4248,17 @@ btr_free_externally_stored_field(
from purge where 'data' is located on
an undo log page, not an index
page) */
- byte* field_ref, /* in/out: field reference */
- const rec_t* rec, /* in: record containing field_ref, for
+ 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 ulint* offsets, /*!< in: rec_get_offsets(rec, index),
or NULL */
- page_zip_des_t* page_zip, /* in: compressed page corresponding
+ page_zip_des_t* page_zip, /*!< in: compressed page corresponding
to rec, or NULL if rec == NULL */
- ulint i, /* in: field number of field_ref;
+ ulint i, /*!< in: field number of field_ref;
ignored if rec == NULL */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* local_mtr __attribute__((unused))) /* in: mtr
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* local_mtr __attribute__((unused))) /*!< in: mtr
containing the latch to data an an
X-latch to the index tree */
{
@@ -4378,20 +4416,20 @@ btr_free_externally_stored_field(
}
}
-/***************************************************************
+/***********************************************************//**
Frees the externally stored fields for a record. */
static
void
btr_rec_free_externally_stored_fields(
/*==================================*/
- dict_index_t* index, /* in: index of the data, the index
+ 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) */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ rec_t* rec, /*!< in/out: record */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr) /* in: mini-transaction handle which contains
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr) /*!< in: mini-transaction handle which contains
an X-latch to record page and to the index
tree */
{
@@ -4419,22 +4457,22 @@ btr_rec_free_externally_stored_fields(
}
}
-/***************************************************************
+/***********************************************************//**
Frees the externally stored fields for a record, if the field is mentioned
in the update vector. */
static
void
btr_rec_free_updated_extern_fields(
/*===============================*/
- dict_index_t* index, /* in: index of rec; the index tree MUST be
+ dict_index_t* index, /*!< in: index of rec; the index tree MUST be
X-latched */
- rec_t* rec, /* in/out: record */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ 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 upd_t* update, /* in: update vector */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr) /* in: mini-transaction handle which contains
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update, /*!< in: update vector */
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr) /*!< in: mini-transaction handle which contains
an X-latch to record page and to the tree */
{
ulint n_fields;
@@ -4464,20 +4502,20 @@ btr_rec_free_updated_extern_fields(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of an uncompressed BLOB. The clustered index record
-that points to this BLOB must be protected by a lock or a page latch. */
+that points to this BLOB must be protected by a lock or a page latch.
+@return number of bytes written to buf */
static
ulint
btr_copy_blob_prefix(
/*=================*/
- /* out: number of bytes written to buf */
- byte* buf, /* out: the externally stored part of
+ byte* buf, /*!< out: the externally stored part of
the field, or a prefix of it */
- ulint len, /* in: length of buf, in bytes */
- ulint space_id,/* in: space id of the BLOB pages */
- ulint page_no,/* in: page number of the first BLOB page */
- ulint offset) /* in: offset on the first BLOB page */
+ ulint len, /*!< in: length of buf, in bytes */
+ ulint space_id,/*!< in: space id of the BLOB pages */
+ ulint page_no,/*!< in: page number of the first BLOB page */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
ulint copied_len = 0;
@@ -4522,18 +4560,18 @@ btr_copy_blob_prefix(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of a compressed BLOB. The clustered index record
that points to this BLOB must be protected by a lock or a page latch. */
static
void
btr_copy_zblob_prefix(
/*==================*/
- z_stream* d_stream,/* in/out: the decompressing stream */
- ulint zip_size,/* in: compressed BLOB page size */
- ulint space_id,/* in: space id of the BLOB pages */
- ulint page_no,/* in: page number of the first BLOB page */
- ulint offset) /* in: offset on the first BLOB page */
+ z_stream* d_stream,/*!< in/out: the decompressing stream */
+ ulint zip_size,/*!< in: compressed BLOB page size */
+ ulint space_id,/*!< in: space id of the BLOB pages */
+ ulint page_no,/*!< in: page number of the first BLOB page */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
ulint page_type = FIL_PAGE_TYPE_ZBLOB;
@@ -4650,23 +4688,23 @@ end_of_blob:
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of an externally stored field of a record. The
clustered index record that points to this BLOB must be protected by a
-lock or a page latch. */
+lock or a page latch.
+@return number of bytes written to buf */
static
ulint
btr_copy_externally_stored_field_prefix_low(
/*========================================*/
- /* out: number of bytes written to buf */
- byte* buf, /* out: the externally stored part of
+ byte* buf, /*!< out: the externally stored part of
the field, or a prefix of it */
- ulint len, /* in: length of buf, in bytes */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ ulint len, /*!< in: length of buf, in bytes */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- ulint space_id,/* in: space id of the first BLOB page */
- ulint page_no,/* in: page number of the first BLOB page */
- ulint offset) /* in: offset on the first BLOB page */
+ ulint space_id,/*!< in: space id of the first BLOB page */
+ ulint page_no,/*!< in: page number of the first BLOB page */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
@@ -4700,25 +4738,24 @@ btr_copy_externally_stored_field_prefix_low(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of an externally stored field of a record. The
-clustered index record must be protected by a lock or a page latch. */
+clustered index record must be protected by a lock or a page latch.
+@return the length of the copied field, or 0 if the column was being
+or has been deleted */
UNIV_INTERN
ulint
btr_copy_externally_stored_field_prefix(
/*====================================*/
- /* out: the length of the copied field,
- or 0 if the column was being or has been
- deleted */
- byte* buf, /* out: the field, or a prefix of it */
- ulint len, /* in: length of buf, in bytes */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ byte* buf, /*!< out: the field, or a prefix of it */
+ ulint len, /*!< in: length of buf, in bytes */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- const byte* data, /* in: 'internally' stored part of the
+ const byte* data, /*!< in: 'internally' stored part of the
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len)/* in: length of data, in bytes */
+ ulint local_len)/*!< in: length of data, in bytes */
{
ulint space_id;
ulint page_no;
@@ -4760,23 +4797,23 @@ btr_copy_externally_stored_field_prefix(
offset));
}
-/***********************************************************************
+/*******************************************************************//**
Copies an externally stored field of a record to mem heap. The
-clustered index record must be protected by a lock or a page latch. */
+clustered index record must be protected by a lock or a page latch.
+@return the whole field copied to heap */
static
byte*
btr_copy_externally_stored_field(
/*=============================*/
- /* out: the whole field copied to heap */
- ulint* len, /* out: length of the whole field */
- const byte* data, /* in: 'internally' stored part of the
+ ulint* len, /*!< out: length of the whole field */
+ const byte* data, /*!< in: 'internally' stored part of the
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- ulint local_len,/* in: length of data */
- mem_heap_t* heap) /* in: mem heap */
+ ulint local_len,/*!< in: length of data */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint space_id;
ulint page_no;
@@ -4812,21 +4849,21 @@ btr_copy_externally_stored_field(
return(buf);
}
-/***********************************************************************
-Copies an externally stored field of a record to mem heap. */
+/*******************************************************************//**
+Copies an externally stored field of a record to mem heap.
+@return the field copied to heap */
UNIV_INTERN
byte*
btr_rec_copy_externally_stored_field(
/*=================================*/
- /* out: the field copied to heap */
- const rec_t* rec, /* in: record in a clustered index;
+ const rec_t* rec, /*!< in: record in a clustered index;
must be protected by a lock or a page latch */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- ulint no, /* in: field number */
- ulint* len, /* out: length of the field */
- mem_heap_t* heap) /* in: mem heap */
+ ulint no, /*!< in: field number */
+ ulint* len, /*!< out: length of the field */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint local_len;
const byte* data;
@@ -4847,3 +4884,4 @@ btr_rec_copy_externally_stored_field(
return(btr_copy_externally_stored_field(len, data,
zip_size, local_len, heap));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/btr/btr0pcur.c b/storage/xtradb/btr/btr0pcur.c
index b14efefe13f..ec98692c35b 100644
--- a/storage/xtradb/btr/btr0pcur.c
+++ b/storage/xtradb/btr/btr0pcur.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file btr/btr0pcur.c
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
@@ -32,13 +33,13 @@ Created 2/23/1996 Heikki Tuuri
#include "rem0cmp.h"
#include "trx0trx.h"
-/******************************************************************
-Allocates memory for a persistent cursor object and initializes the cursor. */
+/**************************************************************//**
+Allocates memory for a persistent cursor object and initializes the cursor.
+@return own: persistent cursor */
UNIV_INTERN
btr_pcur_t*
btr_pcur_create_for_mysql(void)
/*============================*/
- /* out, own: persistent cursor */
{
btr_pcur_t* pcur;
@@ -50,13 +51,13 @@ btr_pcur_create_for_mysql(void)
return(pcur);
}
-/******************************************************************
+/**************************************************************//**
Frees the memory for a persistent cursor object. */
UNIV_INTERN
void
btr_pcur_free_for_mysql(
/*====================*/
- btr_pcur_t* cursor) /* in, own: persistent cursor */
+ btr_pcur_t* cursor) /*!< in, own: persistent cursor */
{
if (cursor->old_rec_buf != NULL) {
@@ -76,7 +77,7 @@ btr_pcur_free_for_mysql(
mem_free(cursor);
}
-/******************************************************************
+/**************************************************************//**
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
cursor data structure, or just setting a flag if the cursor id before the
@@ -87,8 +88,8 @@ UNIV_INTERN
void
btr_pcur_store_position(
/*====================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
buf_block_t* block;
@@ -157,15 +158,15 @@ btr_pcur_store_position(
cursor->modify_clock = buf_block_get_modify_clock(block);
}
-/******************************************************************
+/**************************************************************//**
Copies the stored position of a pcur to another pcur. */
UNIV_INTERN
void
btr_pcur_copy_stored_position(
/*==========================*/
- btr_pcur_t* pcur_receive, /* in: pcur which will receive the
+ btr_pcur_t* pcur_receive, /*!< in: pcur which will receive the
position info */
- btr_pcur_t* pcur_donate) /* in: pcur from which the info is
+ btr_pcur_t* pcur_donate) /*!< in: pcur from which the info is
copied */
{
if (pcur_receive->old_rec_buf) {
@@ -187,7 +188,7 @@ btr_pcur_copy_stored_position(
pcur_receive->old_n_fields = pcur_donate->old_n_fields;
}
-/******************************************************************
+/**************************************************************//**
Restores the stored position of a persistent cursor bufferfixing the page and
obtaining the specified latches. If the cursor position was saved when the
(1) cursor was positioned on a user record: this function restores the position
@@ -198,19 +199,17 @@ infimum;
(3) cursor was positioned on the page supremum: restores to the first record
GREATER than the user record which was the predecessor of the supremum.
(4) cursor was positioned before the first or after the last in an empty tree:
-restores to before first or after the last in the tree. */
+restores to before first or after the last in the tree.
+@return TRUE if the cursor position was stored when it was on a user
+record and it can be restored on a user record whose ordering fields
+are identical to the ones of the original user record */
UNIV_INTERN
ibool
btr_pcur_restore_position(
/*======================*/
- /* out: TRUE if the cursor position
- was stored when it was on a user record
- and it can be restored on a user record
- whose ordering fields are identical to
- the ones of the original user record */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in: detached persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in: detached persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
dtuple_t* tuple;
@@ -351,7 +350,7 @@ btr_pcur_restore_position(
return(FALSE);
}
-/******************************************************************
+/**************************************************************//**
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
releases the page latch and bufferfix reserved by the cursor.
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
@@ -361,8 +360,8 @@ UNIV_INTERN
void
btr_pcur_release_leaf(
/*==================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -378,7 +377,7 @@ btr_pcur_release_leaf(
cursor->pos_state = BTR_PCUR_WAS_POSITIONED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the first record on the next page. Releases the
latch on the current page, and bufferunfixes it. Note that there must not be
modifications on the current page, as then the x-latch can be released only in
@@ -387,9 +386,9 @@ UNIV_INTERN
void
btr_pcur_move_to_next_page(
/*=======================*/
- btr_pcur_t* cursor, /* in: persistent cursor; must be on the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; must be on the
last record of the current page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint next_page_no;
ulint space;
@@ -429,7 +428,7 @@ btr_pcur_move_to_next_page(
page_check_dir(next_page);
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor backward if it is on the first record of the page.
Commits mtr. Note that to prevent a possible deadlock, the operation
first stores the position of the cursor, commits mtr, acquires the necessary
@@ -442,9 +441,9 @@ UNIV_INTERN
void
btr_pcur_move_backward_from_page(
/*=============================*/
- btr_pcur_t* cursor, /* in: persistent cursor, must be on the first
+ btr_pcur_t* cursor, /*!< in: persistent cursor, must be on the first
record of the current page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint prev_page_no;
ulint space;
@@ -511,18 +510,17 @@ btr_pcur_move_backward_from_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the previous record in the tree. If no records
-are left, the cursor stays 'before first in tree'. */
+are left, the cursor stays 'before first in tree'.
+@return TRUE if the cursor was not before first in tree */
UNIV_INTERN
ibool
btr_pcur_move_to_prev(
/*==================*/
- /* out: TRUE if the cursor was not before first
- in tree */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -546,7 +544,7 @@ btr_pcur_move_to_prev(
return(TRUE);
}
-/******************************************************************
+/**************************************************************//**
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
user record satisfying the search condition, in the case PAGE_CUR_L or
PAGE_CUR_LE, on the last user record. If no such user record exists, then
@@ -557,14 +555,14 @@ UNIV_INTERN
void
btr_pcur_open_on_user_rec(
/*======================*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ... */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF or
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ... */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- btr_pcur_t* cursor, /* in: memory buffer for persistent
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
btr_pcur_open(index, tuple, mode, latch_mode, cursor, mtr);
diff --git a/storage/xtradb/btr/btr0sea.c b/storage/xtradb/btr/btr0sea.c
index a60f02cf86c..e59d51e056e 100644
--- a/storage/xtradb/btr/btr0sea.c
+++ b/storage/xtradb/btr/btr0sea.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file btr/btr0sea.c
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@@ -42,26 +43,29 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0btr.h"
#include "ha0ha.h"
-/* Flag: has the search system been enabled?
+/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
UNIV_INTERN char btr_search_enabled = TRUE;
+/** Mutex protecting btr_search_enabled */
static mutex_t btr_search_enabled_mutex;
-/* A dummy variable to fool the compiler */
+/** A dummy variable to fool the compiler */
UNIV_INTERN ulint btr_search_this_is_zero = 0;
#ifdef UNIV_SEARCH_PERF_STAT
+/** Number of successful adaptive hash index lookups */
UNIV_INTERN ulint btr_search_n_succ = 0;
+/** Number of failed adaptive hash index lookups */
UNIV_INTERN ulint btr_search_n_hash_fail = 0;
#endif /* UNIV_SEARCH_PERF_STAT */
-/* padding to prevent other memory update
+/** padding to prevent other memory update
hotspots from residing on the same memory
cache line as btr_search_latch */
UNIV_INTERN byte btr_sea_pad1[64];
-/* The latch protecting the adaptive search system: this latch protects the
+/** The latch protecting the adaptive search system: this latch protects the
(1) positions of records on those pages where a hash index has been built.
NOTE: It does not protect values of non-ordering fields within a record from
being updated in-place! We can use fact (1) to perform unique searches to
@@ -71,24 +75,23 @@ indexes. */
same DRAM page as other hotspot semaphores */
UNIV_INTERN rw_lock_t* btr_search_latch_temp;
-/* padding to prevent other memory update hotspots from residing on
+/** padding to prevent other memory update hotspots from residing on
the same memory cache line */
UNIV_INTERN byte btr_sea_pad2[64];
+/** The adaptive hash index */
UNIV_INTERN btr_search_sys_t* btr_search_sys;
-/* If the number of records on the page divided by this parameter
+/** If the number of records on the page divided by this parameter
would have been successfully accessed using a hash index, the index
is then built on the page, assuming the global limit has been reached */
-
#define BTR_SEARCH_PAGE_BUILD_LIMIT 16
-/* The global limit for consecutive potentially successful hash searches,
+/** The global limit for consecutive potentially successful hash searches,
before hash index building is started */
-
#define BTR_SEARCH_BUILD_LIMIT 100
-/************************************************************************
+/********************************************************************//**
Builds a hash index on a page with the given parameters. If the page already
has a hash index with different parameters, the old hash index is removed.
If index is non-NULL, this function checks if n_fields and n_bytes are
@@ -97,15 +100,15 @@ static
void
btr_search_build_page_hash_index(
/*=============================*/
- dict_index_t* index, /* in: index for which to build, or NULL if
+ dict_index_t* index, /*!< in: index for which to build, or NULL if
not known */
- buf_block_t* block, /* in: index page, s- or x-latched */
- ulint n_fields,/* in: hash this many full fields */
- ulint n_bytes,/* in: hash this many bytes from the next
+ buf_block_t* block, /*!< in: index page, s- or x-latched */
+ ulint n_fields,/*!< in: hash this many full fields */
+ ulint n_bytes,/*!< in: hash this many bytes from the next
field */
- ibool left_side);/* in: hash for searches from left side? */
+ ibool left_side);/*!< in: hash for searches from left side? */
-/*********************************************************************
+/*****************************************************************//**
This function should be called before reserving any btr search mutex, if
the intended operation might add nodes to the search system hash table.
Because of the latching order, once we have reserved the btr search system
@@ -151,13 +154,13 @@ btr_search_check_free_space_in_heap(void)
}
}
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the adaptive search system at a database start. */
UNIV_INTERN
void
btr_search_sys_create(
/*==================*/
- ulint hash_size) /* in: hash index hash table size */
+ ulint hash_size) /*!< in: hash index hash table size */
{
/* We allocate the search latch from dynamic memory:
see above at the global variable definition */
@@ -172,7 +175,22 @@ btr_search_sys_create(
btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
}
-/************************************************************************
+/*****************************************************************//**
+Frees the adaptive search system at a database shutdown. */
+UNIV_INTERN
+void
+btr_search_sys_free(void)
+/*=====================*/
+{
+ mem_free(btr_search_latch_temp);
+ btr_search_latch_temp = NULL;
+ mem_heap_free(btr_search_sys->hash_index->heap);
+ hash_table_free(btr_search_sys->hash_index);
+ mem_free(btr_search_sys);
+ btr_search_sys = NULL;
+}
+
+/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
UNIV_INTERN
void
@@ -195,7 +213,7 @@ btr_search_disable(void)
mutex_exit(&btr_search_enabled_mutex);
}
-/************************************************************************
+/********************************************************************//**
Enable the adaptive hash search system. */
UNIV_INTERN
void
@@ -211,14 +229,14 @@ btr_search_enable(void)
mutex_exit(&btr_search_enabled_mutex);
}
-/*********************************************************************
-Creates and initializes a search info struct. */
+/*****************************************************************//**
+Creates and initializes a search info struct.
+@return own: search info struct */
UNIV_INTERN
btr_search_t*
btr_search_info_create(
/*===================*/
- /* out, own: search info struct */
- mem_heap_t* heap) /* in: heap where created */
+ mem_heap_t* heap) /*!< in: heap where created */
{
btr_search_t* info;
@@ -252,15 +270,15 @@ btr_search_info_create(
return(info);
}
-/*********************************************************************
+/*****************************************************************//**
Returns the value of ref_count. The value is protected by
-btr_search_latch. */
+btr_search_latch.
+@return ref_count value. */
UNIV_INTERN
ulint
btr_search_info_get_ref_count(
/*==========================*/
- /* out: ref_count value. */
- btr_search_t* info) /* in: search info. */
+ btr_search_t* info) /*!< in: search info. */
{
ulint ret;
@@ -278,7 +296,7 @@ btr_search_info_get_ref_count(
return(ret);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the search info of an index about hash successes. NOTE that info
is NOT protected by any semaphore, to save CPU time! Do not assume its fields
are consistent. */
@@ -286,8 +304,8 @@ static
void
btr_search_info_update_hash(
/*========================*/
- btr_search_t* info, /* in/out: search info */
- btr_cur_t* cursor) /* in: cursor which was just positioned */
+ btr_search_t* info, /*!< in/out: search info */
+ btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
dict_index_t* index;
ulint n_unique;
@@ -398,20 +416,19 @@ set_new_recomm:
}
}
-/*************************************************************************
+/*********************************************************************//**
Updates the block search info on hash successes. NOTE that info and
block->n_hash_helps, n_fields, n_bytes, side are NOT protected by any
-semaphore, to save CPU time! Do not assume the fields are consistent. */
+semaphore, to save CPU time! Do not assume the fields are consistent.
+@return TRUE if building a (new) hash index on the block is recommended */
static
ibool
btr_search_update_block_hash_info(
/*==============================*/
- /* out: TRUE if building a (new) hash index on
- the block is recommended */
- btr_search_t* info, /* in: search info */
- buf_block_t* block, /* in: buffer block */
+ btr_search_t* info, /*!< in: search info */
+ buf_block_t* block, /*!< in: buffer block */
btr_cur_t* cursor __attribute__((unused)))
- /* in: cursor */
+ /*!< in: cursor */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
@@ -477,7 +494,7 @@ btr_search_update_block_hash_info(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Updates a hash node reference when it has been unsuccessfully used in a
search which could have succeeded with the used hash parameters. This can
happen because when building a hash index for a page, we do not check
@@ -489,9 +506,9 @@ static
void
btr_search_update_hash_ref(
/*=======================*/
- btr_search_t* info, /* in: search info */
- buf_block_t* block, /* in: buffer block where cursor positioned */
- btr_cur_t* cursor) /* in: cursor */
+ btr_search_t* info, /*!< in: search info */
+ buf_block_t* block, /*!< in: buffer block where cursor positioned */
+ btr_cur_t* cursor) /*!< in: cursor */
{
ulint fold;
rec_t* rec;
@@ -547,14 +564,14 @@ btr_search_update_hash_ref(
}
}
-/*************************************************************************
+/*********************************************************************//**
Updates the search info. */
UNIV_INTERN
void
btr_search_info_update_slow(
/*========================*/
- btr_search_t* info, /* in/out: search info */
- btr_cur_t* cursor) /* in: cursor which was just positioned */
+ btr_search_t* info, /*!< in/out: search info */
+ btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
buf_block_t* block;
ibool build_index;
@@ -624,28 +641,28 @@ btr_search_info_update_slow(
}
}
-/**********************************************************************
+/******************************************************************//**
Checks if a guessed position for a tree cursor is right. Note that if
mode is PAGE_CUR_LE, which is used in inserts, and the function returns
-TRUE, then cursor->up_match and cursor->low_match both have sensible values. */
+TRUE, then cursor->up_match and cursor->low_match both have sensible values.
+@return TRUE if success */
static
ibool
btr_search_check_guess(
/*===================*/
- /* out: TRUE if success */
- btr_cur_t* cursor, /* in: guessed cursor position */
+ btr_cur_t* cursor, /*!< in: guessed cursor position */
ibool can_only_compare_to_cursor_rec,
- /* in: if we do not have a latch on the page
+ /*!< in: if we do not have a latch on the page
of cursor, but only a latch on
btr_search_latch, then ONLY the columns
of the record UNDER the cursor are
protected, not the next or previous record
in the chain: we cannot look at the next or
previous record to check our guess! */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
or PAGE_CUR_GE */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
rec_t* rec;
ulint n_unique;
@@ -770,31 +787,31 @@ exit_func:
return(success);
}
-/**********************************************************************
+/******************************************************************//**
Tries to guess the right search position based on the hash search info
of the index. Note that if mode is PAGE_CUR_LE, which is used in inserts,
and the function returns TRUE, then cursor->up_match and cursor->low_match
-both have sensible values. */
+both have sensible values.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
btr_search_guess_on_hash(
/*=====================*/
- /* out: TRUE if succeeded */
- dict_index_t* index, /* in: index */
- btr_search_t* info, /* in: index search info */
- const dtuple_t* tuple, /* in: logical record */
- ulint mode, /* in: PAGE_CUR_L, ... */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ...;
+ dict_index_t* index, /*!< in: index */
+ btr_search_t* info, /*!< in: index search info */
+ const dtuple_t* tuple, /*!< in: logical record */
+ ulint mode, /*!< in: PAGE_CUR_L, ... */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ...;
NOTE that only if has_search_latch
is 0, we will have a latch set on
the cursor page, otherwise we assume
the caller uses his search latch
to protect the record! */
- btr_cur_t* cursor, /* out: tree cursor */
- ulint has_search_latch,/* in: latch mode the caller
+ btr_cur_t* cursor, /*!< out: tree cursor */
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, RW_X_LATCH, or 0 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
rec_t* rec;
@@ -955,7 +972,7 @@ btr_search_guess_on_hash(
/* Increment the page get statistics though we did not really
fix the page: for user info only */
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
return(TRUE);
@@ -979,13 +996,13 @@ failure:
return(FALSE);
}
-/************************************************************************
+/********************************************************************//**
Drops a page hash index. */
UNIV_INTERN
void
btr_search_drop_page_hash_index(
/*============================*/
- buf_block_t* block) /* in: block containing index page,
+ buf_block_t* block) /*!< in: block containing index page,
s- or x-latched, or an index page
for which we know that
block->buf_fix_count == 0 */
@@ -1147,16 +1164,136 @@ cleanup:
}
/************************************************************************
+Drops a page hash index based on index */
+UNIV_INTERN
+void
+btr_search_drop_page_hash_index_on_index(
+/*=====================================*/
+ dict_index_t* index) /* in: record descriptor */
+{
+ buf_page_t* bpage;
+ hash_table_t* table;
+ buf_block_t* block;
+ ulint n_fields;
+ ulint n_bytes;
+ const page_t* page;
+ const rec_t* rec;
+ ulint fold;
+ ulint prev_fold;
+ dulint index_id;
+ ulint n_cached;
+ ulint n_recs;
+ ulint* folds;
+ ulint i;
+ mem_heap_t* heap = NULL;
+ ulint* offsets;
+
+ rw_lock_x_lock(&btr_search_latch);
+ mutex_enter(&LRU_list_mutex);
+
+ table = btr_search_sys->hash_index;
+
+ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
+
+ while (bpage != NULL) {
+ block = (buf_block_t*) bpage;
+ if (block->index == index && block->is_hashed) {
+ page = block->frame;
+
+ /* from btr_search_drop_page_hash_index() */
+ n_fields = block->curr_n_fields;
+ n_bytes = block->curr_n_bytes;
+
+ ut_a(n_fields + n_bytes > 0);
+
+ n_recs = page_get_n_recs(page);
+
+ /* Calculate and cache fold values into an array for fast deletion
+ from the hash index */
+
+ folds = mem_alloc(n_recs * sizeof(ulint));
+
+ n_cached = 0;
+
+ rec = page_get_infimum_rec(page);
+ rec = page_rec_get_next_low(rec, page_is_comp(page));
+
+ index_id = btr_page_get_index_id(page);
+
+ ut_a(0 == ut_dulint_cmp(index_id, index->id));
+
+ prev_fold = 0;
+
+ offsets = NULL;
+
+ while (!page_rec_is_supremum(rec)) {
+ offsets = rec_get_offsets(rec, index, offsets,
+ n_fields + (n_bytes > 0), &heap);
+ ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
+ fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
+
+ if (fold == prev_fold && prev_fold != 0) {
+
+ goto next_rec;
+ }
+
+ /* Remove all hash nodes pointing to this page from the
+ hash chain */
+
+ folds[n_cached] = fold;
+ n_cached++;
+next_rec:
+ rec = page_rec_get_next_low(rec, page_rec_is_comp(rec));
+ prev_fold = fold;
+ }
+
+ for (i = 0; i < n_cached; i++) {
+
+ ha_remove_all_nodes_to_page(table, folds[i], page);
+ }
+
+ ut_a(index->search_info->ref_count > 0);
+ index->search_info->ref_count--;
+
+ block->is_hashed = FALSE;
+ block->index = NULL;
+
+#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ if (UNIV_UNLIKELY(block->n_pointers)) {
+ /* Corruption */
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Corruption of adaptive hash index. After dropping\n"
+"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
+ index->name, (ulong) block->n_pointers);
+ }
+#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+
+ mem_free(folds);
+ }
+
+ bpage = UT_LIST_GET_PREV(LRU, bpage);
+ }
+
+ mutex_exit(&LRU_list_mutex);
+ rw_lock_x_unlock(&btr_search_latch);
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+}
+
+/********************************************************************//**
Drops a page hash index when a page is freed from a fseg to the file system.
Drops possible hash index if the page happens to be in the buffer pool. */
UNIV_INTERN
void
btr_search_drop_page_hash_when_freed(
/*=================================*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no) /* in: page number */
+ ulint page_no) /*!< in: page number */
{
buf_block_t* block;
mtr_t mtr;
@@ -1192,7 +1329,7 @@ btr_search_drop_page_hash_when_freed(
mtr_commit(&mtr);
}
-/************************************************************************
+/********************************************************************//**
Builds a hash index on a page with the given parameters. If the page already
has a hash index with different parameters, the old hash index is removed.
If index is non-NULL, this function checks if n_fields and n_bytes are
@@ -1201,12 +1338,12 @@ static
void
btr_search_build_page_hash_index(
/*=============================*/
- dict_index_t* index, /* in: index for which to build */
- buf_block_t* block, /* in: index page, s- or x-latched */
- ulint n_fields,/* in: hash this many full fields */
- ulint n_bytes,/* in: hash this many bytes from the next
+ dict_index_t* index, /*!< in: index for which to build */
+ buf_block_t* block, /*!< in: index page, s- or x-latched */
+ ulint n_fields,/*!< in: hash this many full fields */
+ ulint n_bytes,/*!< in: hash this many bytes from the next
field */
- ibool left_side)/* in: hash for searches from left side? */
+ ibool left_side)/*!< in: hash for searches from left side? */
{
hash_table_t* table;
page_t* page;
@@ -1387,7 +1524,7 @@ exit_func:
}
}
-/************************************************************************
+/********************************************************************//**
Moves or deletes hash entries for moved records. If new_page is already hashed,
then the hash index for page, if any, is dropped. If new_page is not hashed,
and page is hashed, then a new hash index is built to new_page with the same
@@ -1396,13 +1533,13 @@ UNIV_INTERN
void
btr_search_move_or_delete_hash_entries(
/*===================================*/
- buf_block_t* new_block, /* in: records are copied
+ buf_block_t* new_block, /*!< in: records are copied
to this page */
- buf_block_t* block, /* in: index page from which
+ buf_block_t* block, /*!< in: index page from which
records were copied, and the
copied records will be deleted
from this page */
- dict_index_t* index) /* in: record descriptor */
+ dict_index_t* index) /*!< in: record descriptor */
{
ulint n_fields;
ulint n_bytes;
@@ -1453,13 +1590,13 @@ btr_search_move_or_delete_hash_entries(
rw_lock_s_unlock(&btr_search_latch);
}
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is deleted from a page. */
UNIV_INTERN
void
btr_search_update_hash_on_delete(
/*=============================*/
- btr_cur_t* cursor) /* in: cursor which was positioned on the
+ btr_cur_t* cursor) /*!< in: cursor which was positioned on the
record to delete using btr_cur_search_...,
the record is not yet deleted */
{
@@ -1506,13 +1643,13 @@ btr_search_update_hash_on_delete(
rw_lock_x_unlock(&btr_search_latch);
}
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_node_on_insert(
/*==================================*/
- btr_cur_t* cursor) /* in: cursor which was positioned to the
+ btr_cur_t* cursor) /*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
@@ -1557,13 +1694,13 @@ btr_search_update_hash_node_on_insert(
}
}
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_on_insert(
/*=============================*/
- btr_cur_t* cursor) /* in: cursor which was positioned to the
+ btr_cur_t* cursor) /*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
@@ -1707,13 +1844,13 @@ function_exit:
}
}
-/************************************************************************
-Validates the search system. */
+/********************************************************************//**
+Validates the search system.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_search_validate(void)
/*=====================*/
- /* out: TRUE if ok */
{
ha_node_t* node;
ulint n_page_dumps = 0;
diff --git a/storage/xtradb/buf/buf0buddy.c b/storage/xtradb/buf/buf0buddy.c
index 494db91d159..586a8dee1a2 100644
--- a/storage/xtradb/buf/buf0buddy.c
+++ b/storage/xtradb/buf/buf0buddy.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0buddy.c
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@@ -44,15 +45,15 @@ static ulint buf_buddy_n_frames;
Protected by buf_pool_mutex. */
UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
-/**************************************************************************
-Get the offset of the buddy of a compressed page frame. */
+/**********************************************************************//**
+Get the offset of the buddy of a compressed page frame.
+@return the buddy relative of page */
UNIV_INLINE
byte*
buf_buddy_get(
/*==========*/
- /* out: the buddy relative of page */
- byte* page, /* in: compressed page */
- ulint size) /* in: page size in bytes */
+ byte* page, /*!< in: compressed page */
+ ulint size) /*!< in: page size in bytes */
{
ut_ad(ut_is_2pow(size));
ut_ad(size >= BUF_BUDDY_LOW);
@@ -66,14 +67,14 @@ buf_buddy_get(
}
}
-/**************************************************************************
+/**********************************************************************//**
Add a block to the head of the appropriate buddy free list. */
UNIV_INLINE
void
buf_buddy_add_to_free(
/*==================*/
- buf_page_t* bpage, /* in,own: block to be freed */
- ulint i) /* in: index of buf_pool->zip_free[] */
+ buf_page_t* bpage, /*!< in,own: block to be freed */
+ ulint i) /*!< in: index of buf_pool->zip_free[] */
{
#ifdef UNIV_DEBUG_VALGRIND
buf_page_t* b = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
@@ -81,6 +82,9 @@ buf_buddy_add_to_free(
if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
#endif /* UNIV_DEBUG_VALGRIND */
+ //ut_ad(buf_pool_mutex_own());
+ ut_ad(mutex_own(&zip_free_mutex));
+ ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
ut_ad(buf_pool->zip_free[i].start != bpage);
UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
@@ -90,14 +94,14 @@ buf_buddy_add_to_free(
#endif /* UNIV_DEBUG_VALGRIND */
}
-/**************************************************************************
+/**********************************************************************//**
Remove a block from the appropriate buddy free list. */
UNIV_INLINE
void
buf_buddy_remove_from_free(
/*=======================*/
- buf_page_t* bpage, /* in: block to be removed */
- ulint i) /* in: index of buf_pool->zip_free[] */
+ buf_page_t* bpage, /*!< in: block to be removed */
+ ulint i) /*!< in: index of buf_pool->zip_free[] */
{
#ifdef UNIV_DEBUG_VALGRIND
buf_page_t* prev = UT_LIST_GET_PREV(zip_list, bpage);
@@ -110,6 +114,8 @@ buf_buddy_remove_from_free(
ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
#endif /* UNIV_DEBUG_VALGRIND */
+ //ut_ad(buf_pool_mutex_own());
+ ut_ad(mutex_own(&zip_free_mutex));
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
@@ -119,15 +125,14 @@ buf_buddy_remove_from_free(
#endif /* UNIV_DEBUG_VALGRIND */
}
-/**************************************************************************
-Try to allocate a block from buf_pool->zip_free[]. */
+/**********************************************************************//**
+Try to allocate a block from buf_pool->zip_free[].
+@return allocated block, or NULL if buf_pool->zip_free[] was empty */
static
void*
buf_buddy_alloc_zip(
/*================*/
- /* out: allocated block, or NULL
- if buf_pool->zip_free[] was empty */
- ulint i) /* in: index of buf_pool->zip_free[] */
+ ulint i) /*!< in: index of buf_pool->zip_free[] */
{
buf_page_t* bpage;
@@ -135,10 +140,12 @@ buf_buddy_alloc_zip(
ut_ad(mutex_own(&zip_free_mutex));
ut_a(i < BUF_BUDDY_SIZES);
-#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
+#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
- UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i]);
-#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
+ ut_ad(buf_page_get_state(ut_list_node_313)
+ == BUF_BLOCK_ZIP_FREE)));
+#endif /* !UNIV_DEBUG_VALGRIND */
bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
if (bpage) {
@@ -172,13 +179,13 @@ buf_buddy_alloc_zip(
return(bpage);
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate a buffer frame of UNIV_PAGE_SIZE. */
static
void
buf_buddy_block_free(
/*=================*/
- void* buf, /* in: buffer frame to deallocate */
+ void* buf, /*!< in: buffer frame to deallocate */
ibool have_page_hash_mutex)
{
const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf);
@@ -216,17 +223,18 @@ buf_buddy_block_free(
ut_d(buf_buddy_n_frames--);
}
-/**************************************************************************
+/**********************************************************************//**
Allocate a buffer block to the buddy allocator. */
static
void
buf_buddy_block_register(
/*=====================*/
- buf_block_t* block) /* in: buffer frame to allocate */
+ buf_block_t* block) /*!< in: buffer frame to allocate */
{
const ulint fold = BUF_POOL_ZIP_FOLD(block);
//ut_ad(buf_pool_mutex_own());
ut_ad(!mutex_own(&buf_pool_zip_mutex));
+ ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
buf_block_set_state(block, BUF_BLOCK_MEMORY);
@@ -244,16 +252,16 @@ buf_buddy_block_register(
ut_d(buf_buddy_n_frames++);
}
-/**************************************************************************
-Allocate a block from a bigger object. */
+/**********************************************************************//**
+Allocate a block from a bigger object.
+@return allocated block */
static
void*
buf_buddy_alloc_from(
/*=================*/
- /* out: allocated block */
- void* buf, /* in: a block that is free to use */
- ulint i, /* in: index of buf_pool->zip_free[] */
- ulint j) /* in: size of buf as an index
+ void* buf, /*!< in: a block that is free to use */
+ ulint i, /*!< in: index of buf_pool->zip_free[] */
+ ulint j) /*!< in: size of buf as an index
of buf_pool->zip_free[] */
{
ulint offs = BUF_BUDDY_LOW << j;
@@ -271,29 +279,31 @@ buf_buddy_alloc_from(
bpage = (buf_page_t*) ((byte*) buf + offs);
ut_d(memset(bpage, j, BUF_BUDDY_LOW << j));
bpage->state = BUF_BLOCK_ZIP_FREE;
-#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
+#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
- UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[j]);
-#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
+ ut_ad(buf_page_get_state(
+ ut_list_node_313)
+ == BUF_BLOCK_ZIP_FREE)));
+#endif /* !UNIV_DEBUG_VALGRIND */
buf_buddy_add_to_free(bpage, j);
}
return(buf);
}
-/**************************************************************************
+/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
-The buf_pool_mutex may only be released and reacquired if lru != NULL. */
+The buf_pool_mutex may only be released and reacquired if lru != NULL.
+@return allocated block, possibly NULL if lru==NULL */
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
- /* out: allocated block,
- possibly NULL if lru==NULL */
- ulint i, /* in: index of buf_pool->zip_free[],
+ ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
- ibool* lru, /* in: pointer to a variable that will be assigned
+ ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
@@ -357,15 +367,15 @@ func_exit:
return(block);
}
-/**************************************************************************
-Try to relocate the control block of a compressed page. */
+/**********************************************************************//**
+Try to relocate the control block of a compressed page.
+@return TRUE if relocated */
static
ibool
buf_buddy_relocate_block(
/*=====================*/
- /* out: TRUE if relocated */
- buf_page_t* bpage, /* in: block to relocate */
- buf_page_t* dpage) /* in: free block to relocate to */
+ buf_page_t* bpage, /*!< in: block to relocate */
+ buf_page_t* dpage) /*!< in: free block to relocate to */
{
buf_page_t* b;
@@ -425,16 +435,16 @@ buf_buddy_relocate_block(
return(TRUE);
}
-/**************************************************************************
-Try to relocate a block. */
+/**********************************************************************//**
+Try to relocate a block.
+@return TRUE if relocated */
static
ibool
buf_buddy_relocate(
/*===============*/
- /* out: TRUE if relocated */
- void* src, /* in: block to relocate */
- void* dst, /* in: free block to relocate to */
- ulint i, /* in: index of buf_pool->zip_free[] */
+ void* src, /*!< in: block to relocate */
+ void* dst, /*!< in: free block to relocate to */
+ ulint i, /*!< in: index of buf_pool->zip_free[] */
ibool have_page_hash_mutex)
{
buf_page_t* bpage;
@@ -461,16 +471,15 @@ buf_buddy_relocate(
actually is a properly initialized buf_page_t object. */
if (size >= PAGE_ZIP_MIN_SIZE) {
- mutex_t* mutex;
- if (!have_page_hash_mutex)
- mutex_exit(&zip_free_mutex);
-
/* This is a compressed page. */
+ mutex_t* mutex;
if (!have_page_hash_mutex) {
+ mutex_exit(&zip_free_mutex);
mutex_enter(&LRU_list_mutex);
rw_lock_x_lock(&page_hash_latch);
}
+
/* The src block may be split into smaller blocks,
some of which may be free. Thus, the
mach_read_from_4() calls below may attempt to read
@@ -521,18 +530,11 @@ buf_buddy_relocate(
contain uninitialized data. */
UNIV_MEM_ASSERT_W(src, size);
- mutex = buf_page_get_mutex(bpage);
+ mutex = buf_page_get_mutex_enter(bpage);
-retry_lock:
- mutex_enter(mutex);
- if (mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(mutex);
- mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
mutex_enter(&zip_free_mutex);
- if (buf_page_can_relocate(bpage)) {
+ if (mutex && buf_page_can_relocate(bpage)) {
/* Relocate the compressed page. */
ut_a(bpage->zip.data == src);
memcpy(dst, src, size);
@@ -560,7 +562,9 @@ success:
rw_lock_x_unlock(&page_hash_latch);
}
- mutex_exit(mutex);
+ if (mutex) {
+ mutex_exit(mutex);
+ }
} else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
/* This must be a buf_page_t object. */
UNIV_MEM_ASSERT_RW(src, size);
@@ -594,15 +598,16 @@ success:
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate a block. */
UNIV_INTERN
void
buf_buddy_free_low(
/*===============*/
- void* buf, /* in: block to be freed, must not be
+ void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
- ulint i, /* in: index of buf_pool->zip_free[] */
+ ulint i, /*!< in: index of buf_pool->zip_free[],
+ or BUF_BUDDY_SIZES */
ibool have_page_hash_mutex)
{
buf_page_t* bpage;
@@ -676,7 +681,9 @@ buddy_free2:
#ifndef UNIV_DEBUG_VALGRIND
buddy_nonfree:
/* Valgrind would complain about accessing free memory. */
- ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i]));
+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
+ ut_ad(buf_page_get_state(ut_list_node_313)
+ == BUF_BLOCK_ZIP_FREE)));
#endif /* UNIV_DEBUG_VALGRIND */
/* The buddy is not free. Is there a free block of this size? */
@@ -702,21 +709,20 @@ buddy_nonfree:
buddy = (buf_page_t*) buf_buddy_get(((byte*) bpage),
BUF_BUDDY_LOW << i);
-#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
- {
- const buf_page_t* b;
+#ifndef UNIV_DEBUG_VALGRIND
+ /* Valgrind would complain about accessing free memory. */
- /* The buddy must not be (completely) free, because
- we always recombine adjacent free blocks.
- (Parts of the buddy can be free in
- buf_pool->zip_free[j] with j < i.)*/
- for (b = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
- b; b = UT_LIST_GET_NEXT(zip_list, b)) {
+ /* The buddy must not be (completely) free, because we
+ always recombine adjacent free blocks.
- ut_a(b != buddy);
- }
- }
-#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
+ (Parts of the buddy can be free in
+ buf_pool->zip_free[j] with j < i.) */
+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
+ ut_ad(buf_page_get_state(
+ ut_list_node_313)
+ == BUF_BLOCK_ZIP_FREE
+ && ut_list_node_313 != buddy)));
+#endif /* !UNIV_DEBUG_VALGRIND */
if (buf_buddy_relocate(buddy, buf, i, have_page_hash_mutex)) {
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index a02b7879121..2ea17baf34a 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0buf.c
The database buffer buf_pool
Created 11/5/1995 Heikki Tuuri
@@ -35,18 +36,55 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0buf.ic"
#endif
-#include "buf0buddy.h"
#include "mem0mem.h"
#include "btr0btr.h"
#include "fil0fil.h"
+#ifndef UNIV_HOTBACKUP
+#include "buf0buddy.h"
#include "lock0lock.h"
#include "btr0sea.h"
#include "ibuf0ibuf.h"
-#include "dict0dict.h"
-#include "log0recv.h"
#include "trx0undo.h"
+#include "log0log.h"
+#endif /* !UNIV_HOTBACKUP */
#include "srv0srv.h"
+#include "dict0dict.h"
+#include "log0recv.h"
#include "page0zip.h"
+#include "trx0trx.h"
+
+/* prototypes for new functions added to ha_innodb.cc */
+trx_t* innobase_get_trx();
+
+inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
+{
+ ulint block_hash;
+ ulint block_hash_byte;
+ byte block_hash_offset;
+
+ ut_ad(block);
+
+ if (!innobase_get_slow_log() || !trx || !trx->take_stats)
+ return;
+
+ if (!trx->distinct_page_access_hash) {
+ trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
+ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
+ }
+
+ block_hash = ut_hash_ulint((block->page.space << 20) + block->page.space +
+ block->page.offset, DPAH_SIZE << 3);
+ block_hash_byte = block_hash >> 3;
+ block_hash_offset = (byte) block_hash & 0x07;
+ if (block_hash_byte >= DPAH_SIZE)
+ fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", (unsigned long) block_hash_byte, (unsigned long) block_hash_offset);
+ if (block_hash_offset > 7)
+ fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", (unsigned long) block_hash_byte, (unsigned long) block_hash_offset);
+ if ((trx->distinct_page_access_hash[block_hash_byte] & ((byte) 0x01 << block_hash_offset)) == 0)
+ trx->distinct_page_access++;
+ trx->distinct_page_access_hash[block_hash_byte] |= (byte) 0x01 << block_hash_offset;
+ return;
+}
/*
IMPLEMENTATION OF THE BUFFER POOL
@@ -235,13 +273,14 @@ that the whole area may be needed in the near future, and issue
the read requests for the whole area.
*/
-/* Value in microseconds */
+#ifndef UNIV_HOTBACKUP
+/** Value in microseconds */
static const int WAIT_FOR_READ = 5000;
-/* The buffer buf_pool of the database */
+/** The buffer buf_pool of the database */
UNIV_INTERN buf_pool_t* buf_pool = NULL;
-/* mutex protecting the buffer pool struct and control blocks, except the
+/** mutex protecting the buffer pool struct and control blocks, except the
read-write lock in them */
UNIV_INTERN mutex_t buf_pool_mutex;
UNIV_INTERN mutex_t LRU_list_mutex;
@@ -250,12 +289,12 @@ UNIV_INTERN rw_lock_t page_hash_latch;
UNIV_INTERN mutex_t free_list_mutex;
UNIV_INTERN mutex_t zip_free_mutex;
UNIV_INTERN mutex_t zip_hash_mutex;
-/* mutex protecting the control blocks of compressed-only pages
+/** mutex protecting the control blocks of compressed-only pages
(of type buf_page_t, not buf_block_t) */
UNIV_INTERN mutex_t buf_pool_zip_mutex;
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-static ulint buf_dbg_counter = 0; /* This is used to insert validation
+static ulint buf_dbg_counter = 0; /*!< This is used to insert validation
operations in excution in the
debug version */
/** Flag to forbid the release of the buffer pool mutex.
@@ -263,30 +302,31 @@ Protected by buf_pool_mutex. */
UNIV_INTERN ulint buf_pool_mutex_exit_forbidden = 0;
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
-/* If this is set TRUE, the program prints info whenever
+/** If this is set TRUE, the program prints info whenever
read-ahead or flush occurs */
UNIV_INTERN ibool buf_debug_prints = FALSE;
#endif /* UNIV_DEBUG */
-/* A chunk of buffers. The buffer pool is allocated in chunks. */
+/** A chunk of buffers. The buffer pool is allocated in chunks. */
struct buf_chunk_struct{
- ulint mem_size; /* allocated size of the chunk */
- ulint size; /* size of frames[] and blocks[] */
- void* mem; /* pointer to the memory area which
+ ulint mem_size; /*!< allocated size of the chunk */
+ ulint size; /*!< size of frames[] and blocks[] */
+ void* mem; /*!< pointer to the memory area which
was allocated for the frames */
- buf_block_t* blocks; /* array of buffer control blocks */
+ buf_block_t* blocks; /*!< array of buffer control blocks */
};
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value on
-32-bit and 64-bit architectures. */
+32-bit and 64-bit architectures.
+@return checksum */
UNIV_INTERN
ulint
buf_calc_page_new_checksum(
/*=======================*/
- /* out: checksum */
- const byte* page) /* in: buffer page */
+ const byte* page) /*!< in: buffer page */
{
ulint checksum;
@@ -308,19 +348,19 @@ buf_calc_page_new_checksum(
return(checksum);
}
-/************************************************************************
+/********************************************************************//**
In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
looked at the first few bytes of the page. This calculates that old
checksum.
NOTE: we must first store the new formula checksum to
FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
-because this takes that field as an input! */
+because this takes that field as an input!
+@return checksum */
UNIV_INTERN
ulint
buf_calc_page_old_checksum(
/*=======================*/
- /* out: checksum */
- const byte* page) /* in: buffer page */
+ const byte* page) /*!< in: buffer page */
{
ulint checksum;
@@ -331,22 +371,20 @@ buf_calc_page_old_checksum(
return(checksum);
}
-/************************************************************************
-Checks if a page is corrupt. */
+/********************************************************************//**
+Checks if a page is corrupt.
+@return TRUE if corrupted */
UNIV_INTERN
ibool
buf_page_is_corrupted(
/*==================*/
- /* out: TRUE if corrupted */
- const byte* read_buf, /* in: a database page */
- ulint zip_size) /* in: size of compressed page;
+ const byte* read_buf, /*!< in: a database page */
+ ulint zip_size) /*!< in: size of compressed page;
0 for uncompressed pages */
{
ulint checksum_field;
ulint old_checksum_field;
-#ifndef UNIV_HOTBACKUP
- ib_uint64_t current_lsn;
-#endif
+
if (UNIV_LIKELY(!zip_size)
&& memcmp(read_buf + FIL_PAGE_LSN + 4,
read_buf + UNIV_PAGE_SIZE
@@ -359,8 +397,11 @@ buf_page_is_corrupted(
}
#ifndef UNIV_HOTBACKUP
- if (recv_lsn_checks_on && log_peek_lsn(&current_lsn)) {
- if (current_lsn < mach_read_ull(read_buf + FIL_PAGE_LSN)) {
+ if (recv_lsn_checks_on) {
+ ib_uint64_t current_lsn;
+
+ if (log_peek_lsn(&current_lsn)
+ && current_lsn < mach_read_ull(read_buf + FIL_PAGE_LSN)) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -372,8 +413,7 @@ buf_page_is_corrupted(
"you may have copied the InnoDB\n"
"InnoDB: tablespace but not the InnoDB "
"log files. See\n"
- "InnoDB: http://dev.mysql.com/doc/refman/"
- "5.1/en/forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-recovery.html\n"
"InnoDB: for more information.\n",
(ulong) mach_read_from_4(read_buf
+ FIL_PAGE_OFFSET),
@@ -434,17 +474,19 @@ buf_page_is_corrupted(
return(FALSE);
}
-/************************************************************************
+/********************************************************************//**
Prints a page to stderr. */
UNIV_INTERN
void
buf_page_print(
/*===========*/
- const byte* read_buf, /* in: a database page */
- ulint zip_size) /* in: compressed page size, or
+ const byte* read_buf, /*!< in: a database page */
+ ulint zip_size) /*!< in: compressed page size, or
0 for uncompressed pages */
{
+#ifndef UNIV_HOTBACKUP
dict_index_t* index;
+#endif /* !UNIV_HOTBACKUP */
ulint checksum;
ulint old_checksum;
ulint size = zip_size;
@@ -558,6 +600,7 @@ buf_page_print(
(ulong) mach_read_from_4(read_buf
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID));
+#ifndef UNIV_HOTBACKUP
if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE)
== TRX_UNDO_INSERT) {
fprintf(stderr,
@@ -568,6 +611,7 @@ buf_page_print(
fprintf(stderr,
"InnoDB: Page may be an update undo log page\n");
}
+#endif /* !UNIV_HOTBACKUP */
switch (fil_page_get_type(read_buf)) {
case FIL_PAGE_INDEX:
@@ -578,16 +622,7 @@ buf_page_print(
btr_page_get_index_id(read_buf)),
(ulong) ut_dulint_get_low(
btr_page_get_index_id(read_buf)));
-
-#ifdef UNIV_HOTBACKUP
- /* If the code is in ibbackup, dict_sys may be uninitialized,
- i.e., NULL */
-
- if (dict_sys == NULL) {
- break;
- }
-#endif /* UNIV_HOTBACKUP */
-
+#ifndef UNIV_HOTBACKUP
index = dict_index_find_on_id_low(
btr_page_get_index_id(read_buf));
if (index) {
@@ -595,6 +630,7 @@ buf_page_print(
dict_index_name_print(stderr, NULL, index);
fputs(")\n", stderr);
}
+#endif /* !UNIV_HOTBACKUP */
break;
case FIL_PAGE_INODE:
fputs("InnoDB: Page may be an 'inode' page\n", stderr);
@@ -639,14 +675,15 @@ buf_page_print(
}
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Initializes a buffer control block when the buf_pool is created. */
static
void
buf_block_init(
/*===========*/
- buf_block_t* block, /* in: pointer to control block */
- byte* frame) /* in: pointer to buffer frame */
+ buf_block_t* block, /*!< in: pointer to control block */
+ byte* frame) /*!< in: pointer to buffer frame */
{
UNIV_MEM_DESC(frame, UNIV_PAGE_SIZE, block);
@@ -688,15 +725,15 @@ buf_block_init(
#endif /* UNIV_SYNC_DEBUG */
}
-/************************************************************************
-Allocates a chunk of buffer frames. */
+/********************************************************************//**
+Allocates a chunk of buffer frames.
+@return chunk, or NULL on failure */
static
buf_chunk_t*
buf_chunk_init(
/*===========*/
- /* out: chunk, or NULL on failure */
- buf_chunk_t* chunk, /* out: chunk of buffers */
- ulint mem_size) /* in: requested size in bytes */
+ buf_chunk_t* chunk, /*!< out: chunk of buffers */
+ ulint mem_size) /*!< in: requested size in bytes */
{
buf_block_t* block;
byte* frame;
@@ -770,17 +807,16 @@ buf_chunk_init(
}
#ifdef UNIV_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Finds a block in the given buffer chunk that points to a
-given compressed page. */
+given compressed page.
+@return buffer block pointing to the compressed page, or NULL */
static
buf_block_t*
buf_chunk_contains_zip(
/*===================*/
- /* out: buffer block pointing to
- the compressed page, or NULL */
- buf_chunk_t* chunk, /* in: chunk being checked */
- const void* data) /* in: pointer to compressed page */
+ buf_chunk_t* chunk, /*!< in: chunk being checked */
+ const void* data) /*!< in: pointer to compressed page */
{
buf_block_t* block;
ulint i;
@@ -800,16 +836,15 @@ buf_chunk_contains_zip(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Finds a block in the buffer pool that points to a
-given compressed page. */
+given compressed page.
+@return buffer block pointing to the compressed page, or NULL */
UNIV_INTERN
buf_block_t*
buf_pool_contains_zip(
/*==================*/
- /* out: buffer block pointing to
- the compressed page, or NULL */
- const void* data) /* in: pointer to compressed page */
+ const void* data) /*!< in: pointer to compressed page */
{
ulint n;
buf_chunk_t* chunk = buf_pool->chunks;
@@ -826,15 +861,14 @@ buf_pool_contains_zip(
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Checks that all file pages in the buffer chunk are in a replaceable state. */
+/*********************************************************************//**
+Checks that all file pages in the buffer chunk are in a replaceable state.
+@return address of a non-free block, or NULL if all freed */
static
const buf_block_t*
buf_chunk_not_freed(
/*================*/
- /* out: address of a non-free block,
- or NULL if all freed */
- buf_chunk_t* chunk) /* in: chunk being checked */
+ buf_chunk_t* chunk) /*!< in: chunk being checked */
{
buf_block_t* block;
ulint i;
@@ -845,29 +879,48 @@ buf_chunk_not_freed(
block = chunk->blocks;
for (i = chunk->size; i--; block++) {
- mutex_enter(&block->mutex);
-
- if (buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
- && !buf_flush_ready_for_replace(&block->page)) {
+ ibool ready;
+ switch (buf_block_get_state(block)) {
+ case BUF_BLOCK_ZIP_FREE:
+ case BUF_BLOCK_ZIP_PAGE:
+ case BUF_BLOCK_ZIP_DIRTY:
+ /* The uncompressed buffer pool should never
+ contain compressed block descriptors. */
+ ut_error;
+ break;
+ case BUF_BLOCK_NOT_USED:
+ case BUF_BLOCK_READY_FOR_USE:
+ case BUF_BLOCK_MEMORY:
+ case BUF_BLOCK_REMOVE_HASH:
+ /* Skip blocks that are not being used for
+ file pages. */
+ break;
+ case BUF_BLOCK_FILE_PAGE:
+ mutex_enter(&block->mutex);
+ ready = buf_flush_ready_for_replace(&block->page);
mutex_exit(&block->mutex);
- return(block);
- }
- mutex_exit(&block->mutex);
+ if (!ready) {
+
+ return(block);
+ }
+
+ break;
+ }
}
return(NULL);
}
-/*************************************************************************
-Checks that all blocks in the buffer chunk are in BUF_BLOCK_NOT_USED state. */
+/*********************************************************************//**
+Checks that all blocks in the buffer chunk are in BUF_BLOCK_NOT_USED state.
+@return TRUE if all freed */
static
ibool
buf_chunk_all_free(
/*===============*/
- /* out: TRUE if all freed */
- const buf_chunk_t* chunk) /* in: chunk being checked */
+ const buf_chunk_t* chunk) /*!< in: chunk being checked */
{
const buf_block_t* block;
ulint i;
@@ -888,13 +941,13 @@ buf_chunk_all_free(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Frees a chunk of buffer frames. */
static
void
buf_chunk_free(
/*===========*/
- buf_chunk_t* chunk) /* out: chunk of buffers */
+ buf_chunk_t* chunk) /*!< out: chunk of buffers */
{
buf_block_t* block;
const buf_block_t* block_end;
@@ -928,14 +981,13 @@ buf_chunk_free(
os_mem_free_large(chunk->mem, chunk->mem_size);
}
-/************************************************************************
-Creates the buffer pool. */
+/********************************************************************//**
+Creates the buffer pool.
+@return own: buf_pool object, NULL if not enough memory or error */
UNIV_INTERN
buf_pool_t*
buf_pool_init(void)
/*===============*/
- /* out, own: buf_pool object, NULL if not
- enough memory or error */
{
buf_chunk_t* chunk;
ulint i;
@@ -986,8 +1038,6 @@ buf_pool_init(void)
buf_pool->no_flush[i] = os_event_create(NULL);
}
- buf_pool->ulint_clock = 1;
-
/* 3. Initialize LRU fields
--------------------------- */
/* All fields are initialized by mem_zalloc(). */
@@ -1005,7 +1055,7 @@ buf_pool_init(void)
return(buf_pool);
}
-/************************************************************************
+/********************************************************************//**
Frees the buffer pool at shutdown. This must not be invoked before
freeing all mutexes. */
UNIV_INTERN
@@ -1025,11 +1075,14 @@ buf_pool_free(void)
os_mem_free_large(chunk->mem, chunk->mem_size);
}
- buf_pool->n_chunks = 0;
+ mem_free(buf_pool->chunks);
+ hash_table_free(buf_pool->page_hash);
+ hash_table_free(buf_pool->zip_hash);
+ mem_free(buf_pool);
+ buf_pool = NULL;
}
-
-/************************************************************************
+/********************************************************************//**
Drops the adaptive hash index. To prevent a livelock, this function
is only to be called while holding btr_search_latch and while
btr_search_enabled == FALSE. */
@@ -1110,7 +1163,7 @@ buf_pool_drop_hash_index(void)
} while (released_search_latch);
}
-/************************************************************************
+/********************************************************************//**
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list.
The caller must take care of relocating bpage->list. */
@@ -1118,10 +1171,10 @@ UNIV_INTERN
void
buf_relocate(
/*=========*/
- buf_page_t* bpage, /* in/out: control block being relocated;
+ buf_page_t* bpage, /*!< in/out: control block being relocated;
buf_page_get_state(bpage) must be
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
- buf_page_t* dpage) /* in/out: destination control block */
+ buf_page_t* dpage) /*!< in/out: destination control block */
{
buf_page_t* b;
ulint fold;
@@ -1173,14 +1226,20 @@ buf_relocate(
#ifdef UNIV_LRU_DEBUG
/* buf_pool->LRU_old must be the first item in the LRU list
whose "old" flag is set. */
+ ut_a(buf_pool->LRU_old->old);
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
+ } else {
+ /* Check that the "old" flag is consistent in
+ the block and its neighbours. */
+ buf_page_set_old(dpage, buf_page_is_old(dpage));
#endif /* UNIV_LRU_DEBUG */
}
- ut_d(UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU));
+ ut_d(UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU,
+ ut_ad(ut_list_node_313->in_LRU_list)));
/* relocate buf_pool->page_hash */
fold = buf_page_address_fold(bpage->space, bpage->offset);
@@ -1191,14 +1250,13 @@ buf_relocate(
UNIV_MEM_INVALID(bpage, sizeof *bpage);
}
-/************************************************************************
+/********************************************************************//**
Shrinks the buffer pool. */
static
void
buf_pool_shrink(
/*============*/
- /* out: TRUE if shrunk */
- ulint chunk_size) /* in: number of pages to remove */
+ ulint chunk_size) /*!< in: number of pages to remove */
{
buf_chunk_t* chunks;
buf_chunk_t* chunk;
@@ -1346,7 +1404,7 @@ func_exit:
btr_search_enable();
}
-/************************************************************************
+/********************************************************************//**
Rebuild buf_pool->page_hash. */
static
void
@@ -1450,7 +1508,7 @@ buf_pool_page_hash_rebuild(void)
mutex_exit(&flush_list_mutex);
}
-/************************************************************************
+/********************************************************************//**
Resizes the buffer pool. */
UNIV_INTERN
void
@@ -1511,42 +1569,15 @@ buf_pool_resize(void)
buf_pool_page_hash_rebuild();
}
-/************************************************************************
-Moves to the block to the start of the LRU list if there is a danger
-that the block would drift out of the buffer pool. */
-UNIV_INLINE
-void
-buf_block_make_young(
-/*=================*/
- buf_page_t* bpage) /* in: block to make younger */
-{
- ut_ad(!buf_pool_mutex_own());
-
- /* Note that we read freed_page_clock's without holding any mutex:
- this is allowed since the result is used only in heuristics */
-
- if (buf_page_peek_if_too_old(bpage)) {
-
- //buf_pool_mutex_enter();
- mutex_enter(&LRU_list_mutex);
- /* There has been freeing activity in the LRU list:
- best to move to the head of the LRU list */
-
- buf_LRU_make_block_young(bpage);
- //buf_pool_mutex_exit();
- mutex_exit(&LRU_list_mutex);
- }
-}
-
-/************************************************************************
+/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
-function can be used to prevent an important page from from slipping out of
+function can be used to prevent an important page from slipping out of
the buffer pool. */
UNIV_INTERN
void
buf_page_make_young(
/*================*/
- buf_page_t* bpage) /* in: buffer block of a file page */
+ buf_page_t* bpage) /*!< in: buffer block of a file page */
{
//buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
@@ -1559,15 +1590,51 @@ buf_page_make_young(
mutex_exit(&LRU_list_mutex);
}
-/************************************************************************
+/********************************************************************//**
+Sets the time of the first access of a page and moves a page to the
+start of the buffer pool LRU list if it is too old. This high-level
+function can be used to prevent an important page from slipping
+out of the buffer pool. */
+static
+void
+buf_page_set_accessed_make_young(
+/*=============================*/
+ buf_page_t* bpage, /*!< in/out: buffer block of a
+ file page */
+ unsigned access_time) /*!< in: bpage->access_time
+ read under mutex protection,
+ or 0 if unknown */
+{
+ ut_ad(!buf_pool_mutex_own());
+ ut_a(buf_page_in_file(bpage));
+
+ if (buf_page_peek_if_too_old(bpage)) {
+ //buf_pool_mutex_enter();
+ mutex_enter(&LRU_list_mutex);
+ buf_LRU_make_block_young(bpage);
+ //buf_pool_mutex_exit();
+ mutex_exit(&LRU_list_mutex);
+ } else if (!access_time) {
+ ulint time_ms = ut_time_ms();
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
+ //buf_pool_mutex_enter();
+ if (block_mutex) {
+ buf_page_set_accessed(bpage, time_ms);
+ mutex_exit(block_mutex);
+ }
+ //buf_pool_mutex_exit();
+ }
+}
+
+/********************************************************************//**
Resets the check_index_page_at_flush field of a page if found in the buffer
pool. */
UNIV_INTERN
void
buf_reset_check_index_page_at_flush(
/*================================*/
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
buf_block_t* block;
@@ -1584,18 +1651,17 @@ buf_reset_check_index_page_at_flush(
rw_lock_s_unlock(&page_hash_latch);
}
-/************************************************************************
+/********************************************************************//**
Returns the current state of is_hashed of a page. FALSE if the page is
not in the pool. NOTE that this operation does not fix the page in the
-pool if it is found there. */
+pool if it is found there.
+@return TRUE if page hash index is built in search system */
UNIV_INTERN
ibool
buf_page_peek_if_search_hashed(
/*===========================*/
- /* out: TRUE if page hash index is built in search
- system */
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
buf_block_t* block;
ibool is_hashed;
@@ -1618,19 +1684,18 @@ buf_page_peek_if_search_hashed(
}
#ifdef UNIV_DEBUG_FILE_ACCESSES
-/************************************************************************
+/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
-reallocated. */
+reallocated.
+@return control block if found in page hash table, otherwise NULL */
UNIV_INTERN
buf_page_t*
buf_page_set_file_page_was_freed(
/*=============================*/
- /* out: control block if found in page hash table,
- otherwise NULL */
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
buf_page_t* bpage;
@@ -1649,19 +1714,18 @@ buf_page_set_file_page_was_freed(
return(bpage);
}
-/************************************************************************
+/********************************************************************//**
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
-reallocated. */
+reallocated.
+@return control block if found in page hash table, otherwise NULL */
UNIV_INTERN
buf_page_t*
buf_page_reset_file_page_was_freed(
/*===============================*/
- /* out: control block if found in page hash table,
- otherwise NULL */
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
buf_page_t* bpage;
@@ -1681,31 +1745,40 @@ buf_page_reset_file_page_was_freed(
}
#endif /* UNIV_DEBUG_FILE_ACCESSES */
-/************************************************************************
+/********************************************************************//**
Get read access to a compressed page (usually of type
FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2).
The page must be released with buf_page_release_zip().
NOTE: the page is not protected by any latch. Mutual exclusion has to
be implemented at a higher level. In other words, all possible
accesses to a given page through this function must be protected by
-the same set of mutexes or latches. */
+the same set of mutexes or latches.
+@return pointer to the block */
UNIV_INTERN
buf_page_t*
buf_page_get_zip(
/*=============*/
- /* out: pointer to the block */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size */
+ ulint offset) /*!< in: page number */
{
buf_page_t* bpage;
mutex_t* block_mutex;
ibool must_read;
+ unsigned access_time;
+ trx_t* trx = NULL;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t start_time;
+ ib_uint64_t finish_time;
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside());
#endif
- buf_pool->n_page_gets++;
+ if (innobase_get_slow_log()) {
+ trx = innobase_get_trx();
+ }
+ buf_pool->stat.n_page_gets++;
for (;;) {
//buf_pool_mutex_enter();
@@ -1721,7 +1794,7 @@ lookup:
//buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
- buf_read_page(space, zip_size, offset);
+ buf_read_page(space, zip_size, offset, trx);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 37 || buf_validate());
@@ -1730,19 +1803,13 @@ lookup:
if (UNIV_UNLIKELY(!bpage->zip.data)) {
/* There is no compressed page. */
+err_exit:
//buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
return(NULL);
}
- block_mutex = buf_page_get_mutex(bpage);
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ block_mutex = buf_page_get_mutex_enter(bpage);
rw_lock_s_unlock(&page_hash_latch);
@@ -1752,13 +1819,17 @@ retry_lock:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
case BUF_BLOCK_ZIP_FREE:
- ut_error;
+ if (block_mutex)
+ mutex_exit(block_mutex);
break;
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
+ ut_a(block_mutex == &buf_pool_zip_mutex);
bpage->buf_fix_count++;
- break;
+ goto got_block;
case BUF_BLOCK_FILE_PAGE:
+ ut_a(block_mutex == &((buf_block_t*) bpage)->mutex);
+
/* Discard the uncompressed page frame if possible. */
if (buf_LRU_free_block(bpage, FALSE, NULL, FALSE)
== BUF_LRU_FREED) {
@@ -1769,18 +1840,21 @@ retry_lock:
buf_block_buf_fix_inc((buf_block_t*) bpage,
__FILE__, __LINE__);
- break;
+ goto got_block;
}
+ ut_error;
+ goto err_exit;
+
+got_block:
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
+ access_time = buf_page_is_accessed(bpage);
//buf_pool_mutex_exit();
- buf_page_set_accessed(bpage, TRUE);
-
mutex_exit(block_mutex);
- buf_block_make_young(bpage);
+ buf_page_set_accessed_make_young(bpage, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(!bpage->file_page_was_freed);
@@ -1796,6 +1870,13 @@ retry_lock:
/* Let us wait until the read operation
completes */
+ if (innobase_get_slow_log() && trx && trx->take_stats)
+ {
+ ut_usectime(&sec, &ms);
+ start_time = (ib_uint64_t)sec * 1000000 + ms;
+ } else {
+ start_time = 0;
+ }
for (;;) {
enum buf_io_fix io_fix;
@@ -1810,6 +1891,12 @@ retry_lock:
break;
}
}
+ if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
+ }
}
#ifdef UNIV_IBUF_COUNT_DEBUG
@@ -1819,13 +1906,13 @@ retry_lock:
return(bpage);
}
-/************************************************************************
+/********************************************************************//**
Initialize some fields of a control block. */
UNIV_INLINE
void
buf_block_init_low(
/*===============*/
- buf_block_t* block) /* in: block to init */
+ buf_block_t* block) /*!< in: block to init */
{
block->check_index_page_at_flush = FALSE;
block->index = NULL;
@@ -1836,16 +1923,17 @@ buf_block_init_low(
block->n_bytes = 0;
block->left_side = TRUE;
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Decompress a block. */
-static
+/********************************************************************//**
+Decompress a block.
+@return TRUE if successful */
+UNIV_INTERN
ibool
buf_zip_decompress(
/*===============*/
- /* out: TRUE if successful */
- buf_block_t* block, /* in/out: block */
- ibool check) /* in: TRUE=verify the page checksum */
+ buf_block_t* block, /*!< in/out: block */
+ ibool check) /*!< in: TRUE=verify the page checksum */
{
const byte* frame = block->page.zip.data;
@@ -1872,7 +1960,7 @@ buf_zip_decompress(
switch (fil_page_get_type(frame)) {
case FIL_PAGE_INDEX:
if (page_zip_decompress(&block->page.zip,
- block->frame)) {
+ block->frame, TRUE)) {
return(TRUE);
}
@@ -1903,14 +1991,15 @@ buf_zip_decompress(
return(FALSE);
}
-/***********************************************************************
-Gets the block to whose frame the pointer is pointing to. */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Gets the block to whose frame the pointer is pointing to.
+@return pointer to block, never NULL */
UNIV_INTERN
buf_block_t*
buf_block_align(
/*============*/
- /* out: pointer to block, never NULL */
- const byte* ptr) /* in: pointer to a frame */
+ const byte* ptr) /*!< in: pointer to a frame */
{
buf_chunk_t* chunk;
ulint i;
@@ -1990,31 +2079,25 @@ buf_block_align(
return(NULL);
}
-/************************************************************************
-Find out if a buffer block was created by buf_chunk_init(). */
-static
+/********************************************************************//**
+Find out if a pointer belongs to a buf_block_t. It can be a pointer to
+the buf_block_t itself or a member of it
+@return TRUE if ptr belongs to a buf_block_t struct */
+UNIV_INTERN
ibool
-buf_block_is_uncompressed(
-/*======================*/
- /* out: TRUE if "block" has
- been added to buf_pool->free
- by buf_chunk_init() */
- const buf_block_t* block) /* in: pointer to block,
- not dereferenced */
+buf_pointer_is_block_field(
+/*=======================*/
+ const void* ptr) /*!< in: pointer not
+ dereferenced */
{
const buf_chunk_t* chunk = buf_pool->chunks;
const buf_chunk_t* const echunk = chunk + buf_pool->n_chunks;
- //ut_ad(buf_pool_mutex_own());
-
- if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
- /* The pointer should be aligned. */
- return(FALSE);
- }
-
+ /* TODO: protect buf_pool->chunks with a mutex (it will
+ currently remain constant after buf_pool_init()) */
while (chunk < echunk) {
- if (block >= chunk->blocks
- && block < chunk->blocks + chunk->size) {
+ if (ptr >= (void *)chunk->blocks
+ && ptr < (void *)(chunk->blocks + chunk->size)) {
return(TRUE);
}
@@ -2025,30 +2108,55 @@ buf_block_is_uncompressed(
return(FALSE);
}
-/************************************************************************
-This is the general function used to get access to a database page. */
+/********************************************************************//**
+Find out if a buffer block was created by buf_chunk_init().
+@return TRUE if "block" has been added to buf_pool->free by buf_chunk_init() */
+static
+ibool
+buf_block_is_uncompressed(
+/*======================*/
+ const buf_block_t* block) /*!< in: pointer to block,
+ not dereferenced */
+{
+ //ut_ad(buf_pool_mutex_own());
+
+ if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
+ /* The pointer should be aligned. */
+ return(FALSE);
+ }
+
+ return(buf_pointer_is_block_field((void *)block));
+}
+
+/********************************************************************//**
+This is the general function used to get access to a database page.
+@return pointer to the block or NULL */
UNIV_INTERN
buf_block_t*
buf_page_get_gen(
/*=============*/
- /* out: pointer to the block or NULL */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint offset, /* in: page number */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
- buf_block_t* guess, /* in: guessed block or NULL */
- ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL,
+ ulint offset, /*!< in: page number */
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
+ buf_block_t* guess, /*!< in: guessed block or NULL */
+ ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
BUF_GET_NO_LATCH */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr) /* in: mini-transaction */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
buf_block_t* block;
- ibool accessed;
+ unsigned access_time;
ulint fix_type;
ibool must_read;
mutex_t* block_mutex;
+ trx_t* trx = NULL;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t start_time;
+ ib_uint64_t finish_time;
ut_ad(mtr);
ut_ad((rw_latch == RW_S_LATCH)
@@ -2058,23 +2166,20 @@ buf_page_get_gen(
ut_ad((mode == BUF_GET) || (mode == BUF_GET_IF_IN_POOL)
|| (mode == BUF_GET_NO_LATCH));
ut_ad(zip_size == fil_space_get_zip_size(space));
+ ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
#endif
- buf_pool->n_page_gets++;
+ if (innobase_get_slow_log()) {
+ trx = innobase_get_trx();
+ }
+ buf_pool->stat.n_page_gets++;
loop:
block = guess;
//buf_pool_mutex_enter();
if (block) {
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
-retry_lock_1:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex((buf_page_t*)block)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
- goto retry_lock_1;
- }
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
/* If the guess is a compressed page descriptor that
has been allocated by buf_buddy_alloc(), it may have
@@ -2084,7 +2189,9 @@ retry_lock_1:
the guess may be pointing to a buffer pool chunk that
has been released when resizing the buffer pool. */
- if (!buf_block_is_uncompressed(block)
+ if (!block_mutex) {
+ block = guess = NULL;
+ } else if (!buf_block_is_uncompressed(block)
|| offset != block->page.offset
|| space != block->page.space
|| buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
@@ -2102,14 +2209,8 @@ retry_lock_1:
rw_lock_s_lock(&page_hash_latch);
block = (buf_block_t*) buf_page_hash_get(space, offset);
if (block) {
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
-retry_lock_2:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex((buf_page_t*)block)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
- goto retry_lock_2;
- }
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
+ ut_a(block_mutex);
}
rw_lock_s_unlock(&page_hash_latch);
}
@@ -2125,7 +2226,7 @@ loop2:
return(NULL);
}
- buf_read_page(space, zip_size, offset);
+ buf_read_page(space, zip_size, offset, trx);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 37 || buf_validate());
@@ -2161,12 +2262,16 @@ loop2:
case BUF_BLOCK_ZIP_DIRTY:
ut_ad(block_mutex == &buf_pool_zip_mutex);
bpage = &block->page;
+ /* Protect bpage->buf_fix_count. */
+ /* Already proteced here. */
+ //mutex_enter(&buf_pool_zip_mutex);
if (bpage->buf_fix_count
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
/* This condition often occurs when the buffer
is not buffer-fixed, but I/O-fixed by
buf_page_init_for_read(). */
+ //mutex_exit(&buf_pool_zip_mutex);
wait_until_unfixed:
/* The block is buffer-fixed or I/O-fixed.
Try again later. */
@@ -2179,6 +2284,7 @@ wait_until_unfixed:
/* Allocate an uncompressed page. */
//buf_pool_mutex_exit();
+ //mutex_exit(&buf_pool_zip_mutex);
mutex_exit(block_mutex);
block = buf_LRU_get_free_block(0);
@@ -2204,14 +2310,8 @@ wait_until_unfixed:
block = (buf_block_t*) hash_bpage;
if (block) {
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
-retry_lock_3:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex((buf_page_t*)block)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
- goto retry_lock_3;
- }
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
+ ut_a(block_mutex);
}
rw_lock_x_unlock(&page_hash_latch);
mutex_exit(&LRU_list_mutex);
@@ -2293,15 +2393,14 @@ retry_lock_3:
block->page.buf_fix_count = 1;
buf_block_set_io_fix(block, BUF_IO_READ);
+ rw_lock_x_lock(&block->lock);
+ mutex_exit(block_mutex);
+ mutex_exit(&buf_pool_zip_mutex);
mutex_enter(&buf_pool_mutex);
buf_pool->n_pend_unzip++;
mutex_exit(&buf_pool_mutex);
- rw_lock_x_lock(&block->lock);
- mutex_exit(block_mutex);
- mutex_exit(&buf_pool_zip_mutex);
-
buf_buddy_free(bpage, sizeof *bpage, FALSE);
//buf_pool_mutex_exit();
@@ -2319,12 +2418,12 @@ retry_lock_3:
//buf_pool_mutex_enter();
block_mutex = &block->mutex;
mutex_enter(block_mutex);
+ block->page.buf_fix_count--;
+ buf_block_set_io_fix(block, BUF_IO_NONE);
+
mutex_enter(&buf_pool_mutex);
buf_pool->n_pend_unzip--;
mutex_exit(&buf_pool_mutex);
- block->page.buf_fix_count--;
- buf_block_set_io_fix(block, BUF_IO_NONE);
- //mutex_exit(&block->mutex);
rw_lock_x_unlock(&block->lock);
if (UNIV_UNLIKELY(!success)) {
@@ -2351,17 +2450,17 @@ retry_lock_3:
UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
buf_block_buf_fix_inc(block, file, line);
- //buf_pool_mutex_exit();
- /* Check if this is the first access to the page */
+ //mutex_exit(&block->mutex);
- accessed = buf_page_is_accessed(&block->page);
+ /* Check if this is the first access to the page */
- buf_page_set_accessed(&block->page, TRUE);
+ access_time = buf_page_is_accessed(&block->page);
+ //buf_pool_mutex_exit();
mutex_exit(block_mutex);
- buf_block_make_young(&block->page);
+ buf_page_set_accessed_make_young(&block->page, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(!block->page.file_page_was_freed);
@@ -2379,6 +2478,13 @@ retry_lock_3:
/* Let us wait until the read operation
completes */
+ if (innobase_get_slow_log() && trx && trx->take_stats)
+ {
+ ut_usectime(&sec, &ms);
+ start_time = (ib_uint64_t)sec * 1000000 + ms;
+ } else {
+ start_time = 0;
+ }
for (;;) {
enum buf_io_fix io_fix;
@@ -2393,6 +2499,12 @@ retry_lock_3:
break;
}
}
+ if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
+ }
}
fix_type = MTR_MEMO_BUF_FIX;
@@ -2414,39 +2526,44 @@ retry_lock_3:
mtr_memo_push(mtr, block, fix_type);
- if (!accessed) {
+ if (!access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
- buf_read_ahead_linear(space, zip_size, offset);
+ buf_read_ahead_linear(space, zip_size, offset, trx);
}
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0);
#endif
+ if (innobase_get_slow_log()) {
+ _increment_page_get_statistics(block, trx);
+ }
+
return(block);
}
-/************************************************************************
+/********************************************************************//**
This is the general function used to get optimistic access to a database
-page. */
+page.
+@return TRUE if success */
UNIV_INTERN
ibool
buf_page_optimistic_get_func(
/*=========================*/
- /* out: TRUE if success */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
- buf_block_t* block, /* in: guessed buffer block */
- ib_uint64_t modify_clock,/* in: modify clock value if mode is
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
+ buf_block_t* block, /*!< in: guessed buffer block */
+ ib_uint64_t modify_clock,/*!< in: modify clock value if mode is
..._GUESS_ON_CLOCK */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr) /* in: mini-transaction */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
- ibool accessed;
+ unsigned access_time;
ibool success;
ulint fix_type;
+ trx_t* trx = NULL;
ut_ad(mtr && block);
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
@@ -2461,14 +2578,16 @@ buf_page_optimistic_get_func(
}
buf_block_buf_fix_inc(block, file, line);
- accessed = buf_page_is_accessed(&block->page);
- buf_page_set_accessed(&block->page, TRUE);
mutex_exit(&block->mutex);
- buf_block_make_young(&block->page);
+ /* Check if this is the first access to the page.
+ We do a dirty read on purpose, to avoid mutex contention.
+ This field is only used for heuristic purposes; it does not
+ affect correctness. */
- /* Check if this is the first access to the page */
+ access_time = buf_page_is_accessed(&block->page);
+ buf_page_set_accessed_make_young(&block->page, access_time);
ut_ad(!ibuf_inside()
|| ibuf_page(buf_block_get_space(block),
@@ -2520,42 +2639,50 @@ buf_page_optimistic_get_func(
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->page.file_page_was_freed == FALSE);
#endif
- if (UNIV_UNLIKELY(!accessed)) {
+ if (innobase_get_slow_log()) {
+ trx = innobase_get_trx();
+ }
+
+ if (UNIV_UNLIKELY(!access_time)) {
/* In the case of a first access, try to apply linear
read-ahead */
buf_read_ahead_linear(buf_block_get_space(block),
buf_block_get_zip_size(block),
- buf_block_get_page_no(block));
+ buf_block_get_page_no(block), trx);
}
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0);
#endif
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
+ if (innobase_get_slow_log()) {
+ _increment_page_get_statistics(block, trx);
+ }
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
This is used to get access to a known database page, when no waiting can be
done. For example, if a search in an adaptive hash index leads us to this
-frame. */
+frame.
+@return TRUE if success */
UNIV_INTERN
ibool
buf_page_get_known_nowait(
/*======================*/
- /* out: TRUE if success */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
- buf_block_t* block, /* in: the known page */
- ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr) /* in: mini-transaction */
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
+ buf_block_t* block, /*!< in: the known page */
+ ulint mode, /*!< in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ibool success;
ulint fix_type;
+ trx_t* trx = NULL;
ut_ad(mtr);
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
@@ -2581,8 +2708,24 @@ buf_page_get_known_nowait(
mutex_exit(&block->mutex);
- if (mode == BUF_MAKE_YOUNG) {
- buf_block_make_young(&block->page);
+ if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
+ //buf_pool_mutex_enter();
+ mutex_enter(&LRU_list_mutex);
+ buf_LRU_make_block_young(&block->page);
+ //buf_pool_mutex_exit();
+ mutex_exit(&LRU_list_mutex);
+ } else if (!buf_page_is_accessed(&block->page)) {
+ /* Above, we do a dirty read on purpose, to avoid
+ mutex contention. The field buf_page_t::access_time
+ is only used for heuristic purposes. Writes to the
+ field must be protected by mutex, however. */
+ ulint time_ms = ut_time_ms();
+
+ //buf_pool_mutex_enter();
+ mutex_enter(&block->mutex);
+ buf_page_set_accessed(&block->page, time_ms);
+ //buf_pool_mutex_exit();
+ mutex_exit(&block->mutex);
}
ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
@@ -2621,25 +2764,30 @@ buf_page_get_known_nowait(
|| (ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0));
#endif
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
+
+ if (innobase_get_slow_log()) {
+ trx = innobase_get_trx();
+ _increment_page_get_statistics(block, trx);
+ }
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Given a tablespace id and page number tries to get that page. If the
page is not in the buffer pool it is not loaded and NULL is returned.
-Suitable for using when holding the kernel mutex. */
+Suitable for using when holding the kernel mutex.
+@return pointer to a page or NULL */
UNIV_INTERN
const buf_block_t*
buf_page_try_get_func(
/*==================*/
- /* out: pointer to a page or NULL */
- ulint space_id,/* in: tablespace id */
- ulint page_no,/* in: page number */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr) /* in: mini-transaction */
+ ulint space_id,/*!< in: tablespace id */
+ ulint page_no,/*!< in: page number */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
buf_block_t* block;
ibool success;
@@ -2700,7 +2848,7 @@ buf_page_try_get_func(
#endif /* UNIV_DEBUG_FILE_ACCESSES */
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(buf_block_get_space(block),
@@ -2710,19 +2858,19 @@ buf_page_try_get_func(
return(block);
}
-/************************************************************************
+/********************************************************************//**
Initialize some fields of a control block. */
UNIV_INLINE
void
buf_page_init_low(
/*==============*/
- buf_page_t* bpage) /* in: block to init */
+ buf_page_t* bpage) /*!< in: block to init */
{
bpage->flush_type = BUF_FLUSH_LRU;
- bpage->accessed = FALSE;
bpage->io_fix = BUF_IO_NONE;
bpage->buf_fix_count = 0;
bpage->freed_page_clock = 0;
+ bpage->access_time = 0;
bpage->newest_modification = 0;
bpage->oldest_modification = 0;
HASH_INVALIDATE(bpage, hash);
@@ -2731,49 +2879,16 @@ buf_page_init_low(
#endif /* UNIV_DEBUG_FILE_ACCESSES */
}
-#ifdef UNIV_HOTBACKUP
-/************************************************************************
-Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
-UNIV_INTERN
-void
-buf_page_init_for_backup_restore(
-/*=============================*/
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space
- in units of a page */
- ulint zip_size,/* in: compressed page size in bytes
- or 0 for uncompressed pages */
- buf_block_t* block) /* in: block to init */
-{
- buf_block_init_low(block);
-
- block->lock_hash_val = 0;
-
- buf_page_init_low(&block->page);
- block->page.state = BUF_BLOCK_FILE_PAGE;
- block->page.space = space;
- block->page.offset = offset;
-
- page_zip_des_init(&block->page.zip);
-
- /* We assume that block->page.data has been allocated
- with zip_size == UNIV_PAGE_SIZE. */
- ut_ad(zip_size <= UNIV_PAGE_SIZE);
- ut_ad(ut_is_2pow(zip_size));
- page_zip_set_size(&block->page.zip, zip_size);
-}
-#endif /* UNIV_HOTBACKUP */
-
-/************************************************************************
+/********************************************************************//**
Inits a page to the buffer buf_pool. */
static
void
buf_page_init(
/*==========*/
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space
in units of a page */
- buf_block_t* block) /* in: block to init */
+ buf_block_t* block) /*!< in: block to init */
{
buf_page_t* hash_page;
@@ -2832,7 +2947,7 @@ buf_page_init(
buf_page_address_fold(space, offset), &block->page);
}
-/************************************************************************
+/********************************************************************//**
Function which inits a page for read to the buffer buf_pool. If the page is
(1) already in buf_pool, or
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
@@ -2840,21 +2955,21 @@ Function which inits a page for read to the buffer buf_pool. If the page is
then this function does nothing.
Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
on the buffer frame. The io-handler must take care that the flag is cleared
-and the lock released later. */
+and the lock released later.
+@return pointer to the block or NULL */
UNIV_INTERN
buf_page_t*
buf_page_init_for_read(
/*===================*/
- /* out: pointer to the block or NULL */
- ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED */
- ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ... */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size, or 0 */
- ibool unzip, /* in: TRUE=request uncompressed page */
- ib_int64_t tablespace_version,/* in: prevents reading from a wrong
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED */
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ... */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
+ ib_int64_t tablespace_version,/*!< in: prevents reading from a wrong
version of the tablespace in case we have done
DISCARD + IMPORT */
- ulint offset) /* in: page number */
+ ulint offset) /*!< in: page number */
{
buf_block_t* block;
buf_page_t* bpage;
@@ -3058,25 +3173,26 @@ func_exit:
return(bpage);
}
-/************************************************************************
+/********************************************************************//**
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 =>
-FILE_PAGE (the other is buf_page_get_gen). */
+FILE_PAGE (the other is buf_page_get_gen).
+@return pointer to the block, page bufferfixed */
UNIV_INTERN
buf_block_t*
buf_page_create(
/*============*/
- /* out: pointer to the block, page bufferfixed */
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space in units of
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space in units of
a page */
- ulint zip_size,/* in: compressed page size, or 0 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
buf_frame_t* frame;
buf_block_t* block;
buf_block_t* free_block = NULL;
+ ulint time_ms = ut_time_ms();
ut_ad(mtr);
ut_ad(space || !zip_size);
@@ -3128,7 +3244,7 @@ buf_page_create(
buf_LRU_add_block(&block->page, FALSE);
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
- buf_pool->n_pages_created++;
+ buf_pool->stat.n_pages_created++;
if (zip_size) {
void* data;
@@ -3165,13 +3281,13 @@ buf_page_create(
rw_lock_x_unlock(&block->lock);
}
+ buf_page_set_accessed(&block->page, time_ms);
+
//buf_pool_mutex_exit();
mutex_exit(&LRU_list_mutex);
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
- buf_page_set_accessed(&block->page, TRUE);
-
mutex_exit(&block->mutex);
/* Delete possible entries for the page from the insert buffer:
@@ -3206,14 +3322,14 @@ buf_page_create(
return(block);
}
-/************************************************************************
+/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
the buffer pool. */
UNIV_INTERN
void
buf_page_io_complete(
/*=================*/
- buf_page_t* bpage) /* in: pointer to the block in question */
+ buf_page_t* bpage) /*!< in: pointer to the block in question */
{
enum buf_io_fix io_type;
const ibool uncompressed = (buf_page_get_state(bpage)
@@ -3327,9 +3443,8 @@ corrupt:
" You can use CHECK\n"
"InnoDB: TABLE to scan your"
" table for corruption.\n"
- "InnoDB: See also"
- " http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html\n"
+ "InnoDB: See also "
+ REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
@@ -3343,7 +3458,7 @@ corrupt:
if (recv_recovery_is_on()) {
/* Pages must be uncompressed for crash recovery. */
ut_a(uncompressed);
- recv_recover_page(FALSE, TRUE, (buf_block_t*) bpage);
+ recv_recover_page(TRUE, (buf_block_t*) bpage);
}
if (uncompressed && !recv_no_ibuf_operations) {
@@ -3362,14 +3477,8 @@ corrupt:
mutex_enter(&LRU_list_mutex);
//}
}
- block_mutex = buf_page_get_mutex(bpage);
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ block_mutex = buf_page_get_mutex_enter(bpage);
+ ut_a(block_mutex);
mutex_enter(&buf_pool_mutex);
#ifdef UNIV_IBUF_COUNT_DEBUG
@@ -3395,7 +3504,7 @@ retry_lock:
ut_ad(buf_pool->n_pend_reads > 0);
buf_pool->n_pend_reads--;
- buf_pool->n_pages_read++;
+ buf_pool->stat.n_pages_read++;
if (uncompressed) {
rw_lock_x_unlock_gen(&((buf_block_t*) bpage)->lock,
@@ -3420,7 +3529,7 @@ retry_lock:
BUF_IO_WRITE);
}
- buf_pool->n_pages_written++;
+ buf_pool->stat.n_pages_written++;
break;
@@ -3442,7 +3551,7 @@ retry_lock:
//buf_pool_mutex_exit();
}
-/*************************************************************************
+/*********************************************************************//**
Invalidates the file pages in the buffer pool when an archive recovery is
completed. All the file pages buffered must be in a replaceable state when
this function is called: not latched and not modified. */
@@ -3451,7 +3560,32 @@ void
buf_pool_invalidate(void)
/*=====================*/
{
- ibool freed;
+ ibool freed;
+ enum buf_flush i;
+
+ buf_pool_mutex_enter();
+
+ for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) {
+
+ /* As this function is called during startup and
+ during redo application phase during recovery, InnoDB
+ is single threaded (apart from IO helper threads) at
+ this stage. No new write batch can be in intialization
+ stage at this point. */
+ ut_ad(buf_pool->init_flush[i] == FALSE);
+
+ /* However, it is possible that a write batch that has
+ been posted earlier is still not complete. For buffer
+ pool invalidation to proceed we must ensure there is NO
+ write activity happening. */
+ if (buf_pool->n_flush[i] > 0) {
+ buf_pool_mutex_exit();
+ buf_flush_wait_batch_end(i);
+ buf_pool_mutex_enter();
+ }
+ }
+
+ buf_pool_mutex_exit();
ut_ad(buf_all_freed());
@@ -3467,13 +3601,22 @@ buf_pool_invalidate(void)
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
+ buf_pool->freed_page_clock = 0;
+ buf_pool->LRU_old = NULL;
+ buf_pool->LRU_old_len = 0;
+ buf_pool->LRU_flush_ended = 0;
+
+ memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
+ buf_refresh_io_stats();
+
//buf_pool_mutex_exit();
mutex_exit(&LRU_list_mutex);
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/*************************************************************************
-Validates the buffer buf_pool data structure. */
+/*********************************************************************//**
+Validates the buffer buf_pool data structure.
+@return TRUE */
UNIV_INTERN
ibool
buf_validate(void)
@@ -3708,7 +3851,7 @@ buf_validate(void)
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Prints info of the buffer buf_pool data structure. */
UNIV_INTERN
void
@@ -3745,6 +3888,7 @@ buf_print(void)
"n pending decompressions %lu\n"
"n pending reads %lu\n"
"n pending flush LRU %lu list %lu single page %lu\n"
+ "pages made young %lu, not young %lu\n"
"pages read %lu, created %lu, written %lu\n",
(ulong) size,
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
@@ -3755,8 +3899,11 @@ buf_print(void)
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU],
(ulong) buf_pool->n_flush[BUF_FLUSH_LIST],
(ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE],
- (ulong) buf_pool->n_pages_read, buf_pool->n_pages_created,
- (ulong) buf_pool->n_pages_written);
+ (ulong) buf_pool->stat.n_pages_made_young,
+ (ulong) buf_pool->stat.n_pages_not_made_young,
+ (ulong) buf_pool->stat.n_pages_read,
+ (ulong) buf_pool->stat.n_pages_created,
+ (ulong) buf_pool->stat.n_pages_written);
/* Count the number of blocks belonging to each index in the buffer */
@@ -3827,8 +3974,9 @@ buf_print(void)
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Returns the number of latched pages in the buffer pool. */
+/*********************************************************************//**
+Returns the number of latched pages in the buffer pool.
+@return number of latched pages */
UNIV_INTERN
ulint
buf_get_latched_pages_number(void)
@@ -3917,8 +4065,9 @@ buf_get_latched_pages_number(void)
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Returns the number of pending buf pool ios. */
+/*********************************************************************//**
+Returns the number of pending buf pool ios.
+@return number of pending I/O operations */
UNIV_INTERN
ulint
buf_get_n_pending_ios(void)
@@ -3930,9 +4079,10 @@ buf_get_n_pending_ios(void)
+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
}
-/*************************************************************************
+/*********************************************************************//**
Returns the ratio in percents of modified pages in the buffer pool /
-database pages in the buffer pool. */
+database pages in the buffer pool.
+@return modified page percentage ratio */
UNIV_INTERN
ulint
buf_get_modified_ratio_pct(void)
@@ -3953,20 +4103,19 @@ buf_get_modified_ratio_pct(void)
return(ratio);
}
-/*************************************************************************
+/*********************************************************************//**
Prints info of the buffer i/o. */
UNIV_INTERN
void
buf_print_io(
/*=========*/
- FILE* file) /* in/out: buffer where to print */
+ FILE* file) /*!< in/out: buffer where to print */
{
time_t current_time;
double time_elapsed;
- ulint size;
+ ulint n_gets_diff;
ut_ad(buf_pool);
- size = buf_pool->curr_size;
//buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
@@ -3979,13 +4128,15 @@ buf_print_io(
"Buffer pool size, bytes %lu\n"
"Free buffers %lu\n"
"Database pages %lu\n"
+ "Old database pages %lu\n"
"Modified db pages %lu\n"
"Pending reads %lu\n"
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
- (ulong) size,
- (ulong) size * UNIV_PAGE_SIZE,
+ (ulong) buf_pool->curr_size,
+ (ulong) buf_pool->curr_size * UNIV_PAGE_SIZE,
(ulong) UT_LIST_GET_LEN(buf_pool->free),
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
+ (ulong) buf_pool->LRU_old_len,
(ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
(ulong) buf_pool->n_pend_reads,
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
@@ -3997,37 +4148,66 @@ buf_print_io(
current_time = time(NULL);
time_elapsed = 0.001 + difftime(current_time,
buf_pool->last_printout_time);
- buf_pool->last_printout_time = current_time;
fprintf(file,
+ "Pages made young %lu, not young %lu\n"
+ "%.2f youngs/s, %.2f non-youngs/s\n"
"Pages read %lu, created %lu, written %lu\n"
"%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
- (ulong) buf_pool->n_pages_read,
- (ulong) buf_pool->n_pages_created,
- (ulong) buf_pool->n_pages_written,
- (buf_pool->n_pages_read - buf_pool->n_pages_read_old)
+ (ulong) buf_pool->stat.n_pages_made_young,
+ (ulong) buf_pool->stat.n_pages_not_made_young,
+ (buf_pool->stat.n_pages_made_young
+ - buf_pool->old_stat.n_pages_made_young)
+ / time_elapsed,
+ (buf_pool->stat.n_pages_not_made_young
+ - buf_pool->old_stat.n_pages_not_made_young)
+ / time_elapsed,
+ (ulong) buf_pool->stat.n_pages_read,
+ (ulong) buf_pool->stat.n_pages_created,
+ (ulong) buf_pool->stat.n_pages_written,
+ (buf_pool->stat.n_pages_read
+ - buf_pool->old_stat.n_pages_read)
/ time_elapsed,
- (buf_pool->n_pages_created - buf_pool->n_pages_created_old)
+ (buf_pool->stat.n_pages_created
+ - buf_pool->old_stat.n_pages_created)
/ time_elapsed,
- (buf_pool->n_pages_written - buf_pool->n_pages_written_old)
+ (buf_pool->stat.n_pages_written
+ - buf_pool->old_stat.n_pages_written)
/ time_elapsed);
- if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
- fprintf(file, "Buffer pool hit rate %lu / 1000\n",
+ n_gets_diff = buf_pool->stat.n_page_gets - buf_pool->old_stat.n_page_gets;
+
+ if (n_gets_diff) {
+ fprintf(file,
+ "Buffer pool hit rate %lu / 1000,"
+ " young-making rate %lu / 1000 not %lu / 1000\n",
+ (ulong)
+ (1000 - ((1000 * (buf_pool->stat.n_pages_read
+ - buf_pool->old_stat.n_pages_read))
+ / (buf_pool->stat.n_page_gets
+ - buf_pool->old_stat.n_page_gets))),
(ulong)
- (1000 - ((1000 * (buf_pool->n_pages_read
- - buf_pool->n_pages_read_old))
- / (buf_pool->n_page_gets
- - buf_pool->n_page_gets_old))));
+ (1000 * (buf_pool->stat.n_pages_made_young
+ - buf_pool->old_stat.n_pages_made_young)
+ / n_gets_diff),
+ (ulong)
+ (1000 * (buf_pool->stat.n_pages_not_made_young
+ - buf_pool->old_stat.n_pages_not_made_young)
+ / n_gets_diff));
} else {
fputs("No buffer pool page gets since the last printout\n",
file);
}
- buf_pool->n_page_gets_old = buf_pool->n_page_gets;
- buf_pool->n_pages_read_old = buf_pool->n_pages_read;
- buf_pool->n_pages_created_old = buf_pool->n_pages_created;
- buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+ /* Statistics about read ahead algorithm */
+ fprintf(file, "Pages read ahead %.2f/s,"
+ " evicted without access %.2f/s\n",
+ (buf_pool->stat.n_ra_pages_read
+ - buf_pool->old_stat.n_ra_pages_read)
+ / time_elapsed,
+ (buf_pool->stat.n_ra_pages_evicted
+ - buf_pool->old_stat.n_ra_pages_evicted)
+ / time_elapsed);
/* Print some values to help us with visualizing what is
happening with LRU eviction. */
@@ -4039,6 +4219,7 @@ buf_print_io(
buf_LRU_stat_sum.io, buf_LRU_stat_cur.io,
buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
+ buf_refresh_io_stats();
//buf_pool_mutex_exit();
mutex_exit(&LRU_list_mutex);
mutex_exit(&free_list_mutex);
@@ -4046,7 +4227,7 @@ buf_print_io(
mutex_exit(&flush_list_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -4054,14 +4235,12 @@ buf_refresh_io_stats(void)
/*======================*/
{
buf_pool->last_printout_time = time(NULL);
- buf_pool->n_page_gets_old = buf_pool->n_page_gets;
- buf_pool->n_pages_read_old = buf_pool->n_pages_read;
- buf_pool->n_pages_created_old = buf_pool->n_pages_created;
- buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+ buf_pool->old_stat = buf_pool->stat;
}
-/*************************************************************************
-Checks that all file pages in the buffer are in a replaceable state. */
+/*********************************************************************//**
+Asserts that all file pages in the buffer are in a replaceable state.
+@return TRUE */
UNIV_INTERN
ibool
buf_all_freed(void)
@@ -4094,14 +4273,14 @@ buf_all_freed(void)
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer
-pool. */
+pool.
+@return TRUE if there is no pending i/o */
UNIV_INTERN
ibool
buf_pool_check_no_pending_io(void)
/*==============================*/
- /* out: TRUE if there is no pending i/o */
{
ibool ret;
@@ -4122,8 +4301,9 @@ buf_pool_check_no_pending_io(void)
return(ret);
}
-/*************************************************************************
-Gets the current length of the free list of buffer blocks. */
+/*********************************************************************//**
+Gets the current length of the free list of buffer blocks.
+@return length of the free list */
UNIV_INTERN
ulint
buf_get_free_list_len(void)
@@ -4141,3 +4321,33 @@ buf_get_free_list_len(void)
return(len);
}
+#else /* !UNIV_HOTBACKUP */
+/********************************************************************//**
+Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
+UNIV_INTERN
+void
+buf_page_init_for_backup_restore(
+/*=============================*/
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space
+ in units of a page */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
+ buf_block_t* block) /*!< in: block to init */
+{
+ block->page.state = BUF_BLOCK_FILE_PAGE;
+ block->page.space = space;
+ block->page.offset = offset;
+
+ page_zip_des_init(&block->page.zip);
+
+ /* We assume that block->page.data has been allocated
+ with zip_size == UNIV_PAGE_SIZE. */
+ ut_ad(zip_size <= UNIV_PAGE_SIZE);
+ ut_ad(ut_is_2pow(zip_size));
+ page_zip_set_size(&block->page.zip, zip_size);
+ if (zip_size) {
+ block->page.zip.data = block->frame + UNIV_PAGE_SIZE;
+ }
+}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/buf/buf0flu.c b/storage/xtradb/buf/buf0flu.c
index ba8b0e9dc60..9fb4fe7d9ea 100644
--- a/storage/xtradb/buf/buf0flu.c
+++ b/storage/xtradb/buf/buf0flu.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0flu.c
The database buffer buf_pool flush algorithm
Created 11/11/1995 Heikki Tuuri
@@ -26,40 +27,73 @@ Created 11/11/1995 Heikki Tuuri
#ifdef UNIV_NONINL
#include "buf0flu.ic"
-#include "trx0sys.h"
#endif
+#include "buf0buf.h"
+#include "srv0srv.h"
+#include "page0zip.h"
+#ifndef UNIV_HOTBACKUP
#include "ut0byte.h"
#include "ut0lst.h"
#include "page0page.h"
-#include "page0zip.h"
#include "fil0fil.h"
-#include "buf0buf.h"
#include "buf0lru.h"
#include "buf0rea.h"
#include "ibuf0ibuf.h"
#include "log0log.h"
#include "os0file.h"
#include "trx0sys.h"
-#include "srv0srv.h"
-#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************
-Validates the flush list. */
+These statistics are generated for heuristics used in estimating the
+rate at which we should flush the dirty blocks to avoid bursty IO
+activity. Note that the rate of flushing not only depends on how many
+dirty pages we have in the buffer pool but it is also a fucntion of
+how much redo the workload is generating and at what rate. */
+/* @{ */
+
+/** Number of intervals for which we keep the history of these stats.
+Each interval is 1 second, defined by the rate at which
+srv_error_monitor_thread() calls buf_flush_stat_update(). */
+#define BUF_FLUSH_STAT_N_INTERVAL 20
+
+/** Sampled values buf_flush_stat_cur.
+Not protected by any mutex. Updated by buf_flush_stat_update(). */
+static buf_flush_stat_t buf_flush_stat_arr[BUF_FLUSH_STAT_N_INTERVAL];
+
+/** Cursor to buf_flush_stat_arr[]. Updated in a round-robin fashion. */
+static ulint buf_flush_stat_arr_ind;
+
+/** Values at start of the current interval. Reset by
+buf_flush_stat_update(). */
+static buf_flush_stat_t buf_flush_stat_cur;
+
+/** Running sum of past values of buf_flush_stat_cur.
+Updated by buf_flush_stat_update(). Not protected by any mutex. */
+static buf_flush_stat_t buf_flush_stat_sum;
+
+/** Number of pages flushed through non flush_list flushes. */
+static ulint buf_lru_flush_page_count = 0;
+
+/* @} */
+
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
+/******************************************************************//**
+Validates the flush list.
+@return TRUE if ok */
static
ibool
buf_flush_validate_low(void);
/*========================*/
- /* out: TRUE if ok */
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-/************************************************************************
+/********************************************************************//**
Inserts a modified block into the flush list. */
UNIV_INTERN
void
buf_flush_insert_into_flush_list(
/*=============================*/
- buf_block_t* block) /* in/out: block which is modified */
+ buf_block_t* block) /*!< in/out: block which is modified */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&block->mutex));
@@ -81,7 +115,7 @@ buf_flush_insert_into_flush_list(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
-/************************************************************************
+/********************************************************************//**
Inserts a modified block into the flush list in the right sorted position.
This function is used by recovery, because there the modifications do not
necessarily come in the order of lsn's. */
@@ -89,7 +123,7 @@ UNIV_INTERN
void
buf_flush_insert_sorted_into_flush_list(
/*====================================*/
- buf_block_t* block) /* in/out: block which is modified */
+ buf_block_t* block) /*!< in/out: block which is modified */
{
buf_page_t* prev_b;
buf_page_t* b;
@@ -141,15 +175,15 @@ buf_flush_insert_sorted_into_flush_list(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
-/************************************************************************
+/********************************************************************//**
Returns TRUE if the file page block is immediately suitable for replacement,
-i.e., the transition FILE_PAGE => NOT_USED allowed. */
+i.e., the transition FILE_PAGE => NOT_USED allowed.
+@return TRUE if can replace immediately */
UNIV_INTERN
ibool
buf_flush_ready_for_replace(
/*========================*/
- /* out: TRUE if can replace immediately */
- buf_page_t* bpage) /* in: buffer control block, must be
+ buf_page_t* bpage) /*!< in: buffer control block, must be
buf_page_in_file(bpage) and in the LRU list */
{
//ut_ad(buf_pool_mutex_own());
@@ -177,16 +211,16 @@ buf_flush_ready_for_replace(
return(FALSE);
}
-/************************************************************************
-Returns TRUE if the block is modified and ready for flushing. */
+/********************************************************************//**
+Returns TRUE if the block is modified and ready for flushing.
+@return TRUE if can flush immediately */
UNIV_INLINE
ibool
buf_flush_ready_for_flush(
/*======================*/
- /* out: TRUE if can flush immediately */
- buf_page_t* bpage, /* in: buffer control block, must be
+ buf_page_t* bpage, /*!< in: buffer control block, must be
buf_page_in_file(bpage) */
- enum buf_flush flush_type)/* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
+ enum buf_flush flush_type)/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
{
//ut_a(buf_page_in_file(bpage));
//ut_ad(buf_pool_mutex_own()); /*optimistic...*/
@@ -214,13 +248,13 @@ buf_flush_ready_for_flush(
return(FALSE);
}
-/************************************************************************
+/********************************************************************//**
Remove a block from the flush list of modified blocks. */
UNIV_INTERN
void
buf_flush_remove(
/*=============*/
- buf_page_t* bpage) /* in: pointer to the block in question */
+ buf_page_t* bpage) /*!< in: pointer to the block in question */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -253,17 +287,18 @@ buf_flush_remove(
bpage->oldest_modification = 0;
- ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list));
+ ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
+ ut_ad(ut_list_node_313->in_flush_list)));
mutex_exit(&flush_list_mutex);
}
-/************************************************************************
+/********************************************************************//**
Updates the flush system data structures when a write is completed. */
UNIV_INTERN
void
buf_flush_write_complete(
/*=====================*/
- buf_page_t* bpage) /* in: pointer to the block in question */
+ buf_page_t* bpage) /*!< in: pointer to the block in question */
{
enum buf_flush flush_type;
@@ -295,7 +330,29 @@ buf_flush_write_complete(
}
}
-/************************************************************************
+/********************************************************************//**
+Flush a batch of writes to the datafiles that have already been
+written by the OS. */
+static
+void
+buf_flush_sync_datafiles(void)
+/*==========================*/
+{
+ /* Wake possible simulated aio thread to actually post the
+ writes to the operating system */
+ os_aio_simulated_wake_handler_threads();
+
+ /* Wait that all async writes to tablespaces have been posted to
+ the OS */
+ os_aio_wait_until_no_pending_writes();
+
+ /* Now we flush the data to disk (for example, with fsync) */
+ fil_flush_file_spaces(FIL_TABLESPACE);
+
+ return;
+}
+
+/********************************************************************//**
Flushes possible buffered writes from the doublewrite memory buffer to disk,
and also wakes up the aio thread if simulated aio is used. It is very
important to call this function after a batch of writes has been posted,
@@ -312,8 +369,8 @@ buf_flush_buffered_writes(void)
ulint i;
if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
- os_aio_simulated_wake_handler_threads();
-
+ /* Sync the writes to the disk. */
+ buf_flush_sync_datafiles();
return;
}
@@ -521,28 +578,16 @@ flush:
buf_LRU_stat_inc_io();
}
- /* Wake possible simulated aio thread to actually post the
- writes to the operating system */
-
- os_aio_simulated_wake_handler_threads();
-
- /* Wait that all async writes to tablespaces have been posted to
- the OS */
-
- os_aio_wait_until_no_pending_writes();
-
- /* Now we flush the data to disk (for example, with fsync) */
-
- fil_flush_file_spaces(FIL_TABLESPACE);
+ /* Sync the writes to the disk. */
+ buf_flush_sync_datafiles();
/* We can now reuse the doublewrite memory buffer: */
-
trx_doublewrite->first_free = 0;
mutex_exit(&(trx_doublewrite->mutex));
}
-/************************************************************************
+/********************************************************************//**
Posts a buffer page for writing. If the doublewrite memory buffer is
full, calls buf_flush_buffered_writes and waits for for free space to
appear. */
@@ -550,7 +595,7 @@ static
void
buf_flush_post_to_doublewrite_buf(
/*==============================*/
- buf_page_t* bpage) /* in: buffer block to write */
+ buf_page_t* bpage) /*!< in: buffer block to write */
{
ulint zip_size;
try_again:
@@ -600,16 +645,17 @@ try_again:
mutex_exit(&(trx_doublewrite->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Initializes a page for writing to the tablespace. */
UNIV_INTERN
void
buf_flush_init_for_writing(
/*=======================*/
- byte* page, /* in/out: page */
- void* page_zip_, /* in/out: compressed page, or NULL */
- ib_uint64_t newest_lsn) /* in: newest modification lsn
+ byte* page, /*!< in/out: page */
+ void* page_zip_, /*!< in/out: compressed page, or NULL */
+ ib_uint64_t newest_lsn) /*!< in: newest modification lsn
to the page */
{
ut_ad(page);
@@ -679,7 +725,8 @@ buf_flush_init_for_writing(
: BUF_NO_CHECKSUM_MAGIC);
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Does an asynchronous write of a buffer page. NOTE: in simulated aio and
also when the doublewrite buffer is used, we must call
buf_flush_buffered_writes after we have posted a batch of writes! */
@@ -687,7 +734,7 @@ static
void
buf_flush_write_block_low(
/*======================*/
- buf_page_t* bpage) /* in: buffer block to write */
+ buf_page_t* bpage) /*!< in: buffer block to write */
{
ulint zip_size = buf_page_get_zip_size(bpage);
page_t* frame = NULL;
@@ -769,7 +816,7 @@ buf_flush_write_block_low(
}
}
-/************************************************************************
+/********************************************************************//**
Writes a flushable page asynchronously from the buffer pool to a file.
NOTE: in simulated aio we must call
os_aio_simulated_wake_handler_threads after we have posted a batch of
@@ -780,8 +827,8 @@ static
void
buf_flush_page(
/*===========*/
- buf_page_t* bpage, /* in: buffer control block */
- enum buf_flush flush_type) /* in: BUF_FLUSH_LRU
+ buf_page_t* bpage, /*!< in: buffer control block */
+ enum buf_flush flush_type) /*!< in: BUF_FLUSH_LRU
or BUF_FLUSH_LIST */
{
mutex_t* block_mutex;
@@ -892,16 +939,16 @@ buf_flush_page(
buf_flush_write_block_low(bpage);
}
-/***************************************************************
-Flushes to disk all flushable pages within the flush area. */
+/***********************************************************//**
+Flushes to disk all flushable pages within the flush area.
+@return number of pages flushed */
static
ulint
buf_flush_try_neighbors(
/*====================*/
- /* out: number of pages flushed */
- ulint space, /* in: space id */
- ulint offset, /* in: page offset */
- enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: page offset */
+ enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST */
ulint flush_neighbors)
{
@@ -955,17 +1002,9 @@ buf_flush_try_neighbors(
if (flush_type != BUF_FLUSH_LRU
|| i == offset
|| buf_page_is_old(bpage)) {
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
-
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
- if (buf_flush_ready_for_flush(bpage, flush_type)
+ if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)
&& (i == offset || !bpage->buf_fix_count)) {
/* We only try to flush those
neighbors != offset where the buf fix count is
@@ -981,7 +1020,7 @@ retry_lock:
//buf_pool_mutex_enter();
rw_lock_s_lock(&page_hash_latch);
- } else {
+ } else if (block_mutex) {
mutex_exit(block_mutex);
}
}
@@ -993,34 +1032,33 @@ retry_lock:
return(count);
}
-/***********************************************************************
+/*******************************************************************//**
This utility flushes dirty blocks from the end of the LRU list or flush_list.
NOTE 1: in the case of an LRU flush the calling thread may own latches to
pages: to avoid deadlocks, this function must be written so that it cannot
end up waiting for these latches! NOTE 2: in the case of a flush list flush,
-the calling thread is not allowed to own any latches on pages! */
+the calling thread is not allowed to own any latches on pages!
+@return number of blocks for which the write request was queued;
+ULINT_UNDEFINED if there was a flush of the same type already running */
UNIV_INTERN
ulint
buf_flush_batch(
/*============*/
- /* out: number of blocks for which the
- write request was queued;
- ULINT_UNDEFINED if there was a flush
- of the same type already running */
- enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
+ enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST; if BUF_FLUSH_LIST,
then the caller must not own any
latches on pages */
- ulint min_n, /* in: wished minimum mumber of blocks
+ ulint min_n, /*!< in: wished minimum mumber of blocks
flushed (it is not guaranteed that the
actual number is that big, though) */
- ib_uint64_t lsn_limit) /* in the case BUF_FLUSH_LIST all
+ ib_uint64_t lsn_limit) /*!< in the case BUF_FLUSH_LIST all
blocks whose oldest_modification is
smaller than this should be flushed
(if their number does not exceed
min_n), otherwise ignored */
{
buf_page_t* bpage;
+ buf_page_t* prev_bpage = NULL;
ulint page_count = 0;
ulint old_page_count;
ulint space;
@@ -1074,6 +1112,9 @@ flush_next:
mutex_enter(&flush_list_mutex);
remaining = UT_LIST_GET_LEN(buf_pool->flush_list);
bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
+ if (bpage) {
+ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
+ }
mutex_exit(&flush_list_mutex);
if (!bpage
|| bpage->oldest_modification >= lsn_limit) {
@@ -1091,24 +1132,19 @@ flush_next:
function a pointer to a block in the list! */
do {
- mutex_t*block_mutex = buf_page_get_mutex(bpage);
+ mutex_t*block_mutex = buf_page_get_mutex_enter(bpage);
ibool ready;
-retry_lock_1:
- ut_a(buf_page_in_file(bpage));
+ //ut_a(buf_page_in_file(bpage));
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
+ if (block_mutex) {
+ ready = buf_flush_ready_for_flush(bpage, flush_type);
mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock_1;
+ } else {
+ ready = FALSE;
}
- ready = buf_flush_ready_for_flush(bpage, flush_type);
- mutex_exit(block_mutex);
if (ready) {
- mutex_t* block_mutex;
- buf_page_t* bpage_tmp;
space = buf_page_get_space(bpage);
offset = buf_page_get_page_no(bpage);
@@ -1122,8 +1158,6 @@ retry_lock_1:
/* Try to flush also all the neighbors */
page_count += buf_flush_try_neighbors(
space, offset, flush_type, srv_flush_neighbor_pages);
- block_mutex = buf_page_get_mutex(bpage);
- bpage_tmp = buf_page_hash_get(space, offset);
/* fprintf(stderr,
"Flush type %lu, page no %lu, neighb %lu\n",
flush_type, offset,
@@ -1143,6 +1177,13 @@ retry_lock_1:
mutex_enter(&flush_list_mutex);
bpage = UT_LIST_GET_PREV(flush_list, bpage);
//ut_ad(!bpage || bpage->in_flush_list); /* optimistic */
+ if (bpage != prev_bpage) {
+ /* the search may warp.. retrying */
+ bpage = NULL;
+ }
+ if (bpage) {
+ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
+ }
mutex_exit(&flush_list_mutex);
remaining--;
}
@@ -1189,38 +1230,44 @@ retry_lock_1:
srv_buf_pool_flushed += page_count;
+ /* We keep track of all flushes happening as part of LRU
+ flush. When estimating the desired rate at which flush_list
+ should be flushed we factor in this value. */
+ if (flush_type == BUF_FLUSH_LRU) {
+ buf_lru_flush_page_count += page_count;
+ }
+
return(page_count);
}
-/**********************************************************************
+/******************************************************************//**
Waits until a flush batch of the given type ends */
UNIV_INTERN
void
buf_flush_wait_batch_end(
/*=====================*/
- enum buf_flush type) /* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
+ enum buf_flush type) /*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
{
ut_ad((type == BUF_FLUSH_LRU) || (type == BUF_FLUSH_LIST));
os_event_wait(buf_pool->no_flush[type]);
}
-/**********************************************************************
+/******************************************************************//**
Gives a recommendation of how many blocks should be flushed to establish
a big enough margin of replaceable blocks near the end of the LRU list
-and in the free list. */
+and in the free list.
+@return number of blocks which should be flushed from the end of the
+LRU list */
static
ulint
buf_flush_LRU_recommendation(void)
/*==============================*/
- /* out: number of blocks which should be flushed
- from the end of the LRU list */
{
buf_page_t* bpage;
ulint n_replaceable;
ulint distance = 0;
ibool have_LRU_mutex = FALSE;
- mutex_t* block_mutex;
if(UT_LIST_GET_LEN(buf_pool->unzip_LRU))
have_LRU_mutex = TRUE;
@@ -1238,27 +1285,21 @@ buf_flush_LRU_recommendation(void)
+ BUF_FLUSH_EXTRA_MARGIN)
&& (distance < BUF_LRU_FREE_SEARCH_LEN)) {
- if (!bpage->in_LRU_list) {
+ mutex_t* block_mutex;
+ if (!bpage->in_LRU_list) {
/* reatart. but it is very optimistic */
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
continue;
}
+ block_mutex = buf_page_get_mutex_enter(bpage);
- block_mutex = buf_page_get_mutex(bpage);
-
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
-
- if (buf_flush_ready_for_replace(bpage)) {
+ if (block_mutex && buf_flush_ready_for_replace(bpage)) {
n_replaceable++;
}
- mutex_exit(block_mutex);
+ if (block_mutex) {
+ mutex_exit(block_mutex);
+ }
distance++;
@@ -1278,7 +1319,7 @@ retry_lock:
- n_replaceable);
}
-/*************************************************************************
+/*********************************************************************//**
Flushes pages from the end of the LRU list if there is too small a margin
of replaceable pages there or in the free list. VERY IMPORTANT: this function
is called also by threads which have locks on pages. To avoid deadlocks, we
@@ -1306,18 +1347,130 @@ buf_flush_free_margin(
}
}
+/*********************************************************************
+Update the historical stats that we are collecting for flush rate
+heuristics at the end of each interval.
+Flush rate heuristic depends on (a) rate of redo log generation and
+(b) the rate at which LRU flush is happening. */
+UNIV_INTERN
+void
+buf_flush_stat_update(void)
+/*=======================*/
+{
+ buf_flush_stat_t* item;
+ ib_uint64_t lsn_diff;
+ ib_uint64_t lsn;
+ ulint n_flushed;
+
+ lsn = log_get_lsn();
+ if (buf_flush_stat_cur.redo == 0) {
+ /* First time around. Just update the current LSN
+ and return. */
+ buf_flush_stat_cur.redo = lsn;
+ return;
+ }
+
+ item = &buf_flush_stat_arr[buf_flush_stat_arr_ind];
+
+ /* values for this interval */
+ lsn_diff = lsn - buf_flush_stat_cur.redo;
+ n_flushed = buf_lru_flush_page_count
+ - buf_flush_stat_cur.n_flushed;
+
+ /* add the current value and subtract the obsolete entry. */
+ buf_flush_stat_sum.redo += lsn_diff - item->redo;
+ buf_flush_stat_sum.n_flushed += n_flushed - item->n_flushed;
+
+ /* put current entry in the array. */
+ item->redo = lsn_diff;
+ item->n_flushed = n_flushed;
+
+ /* update the index */
+ buf_flush_stat_arr_ind++;
+ buf_flush_stat_arr_ind %= BUF_FLUSH_STAT_N_INTERVAL;
+
+ /* reset the current entry. */
+ buf_flush_stat_cur.redo = lsn;
+ buf_flush_stat_cur.n_flushed = buf_lru_flush_page_count;
+}
+
+/*********************************************************************
+Determines the fraction of dirty pages that need to be flushed based
+on the speed at which we generate redo log. Note that if redo log
+is generated at a significant rate without corresponding increase
+in the number of dirty pages (for example, an in-memory workload)
+it can cause IO bursts of flushing. This function implements heuristics
+to avoid this burstiness.
+@return number of dirty pages to be flushed / second */
+UNIV_INTERN
+ulint
+buf_flush_get_desired_flush_rate(void)
+/*==================================*/
+{
+ ulint redo_avg;
+ ulint lru_flush_avg;
+ ulint n_dirty;
+ ulint n_flush_req;
+ lint rate;
+ ib_uint64_t lsn = log_get_lsn();
+ ulint log_capacity = log_get_capacity();
+
+ /* log_capacity should never be zero after the initialization
+ of log subsystem. */
+ ut_ad(log_capacity != 0);
+
+ /* Get total number of dirty pages. It is OK to access
+ flush_list without holding any mtex as we are using this
+ only for heuristics. */
+ n_dirty = UT_LIST_GET_LEN(buf_pool->flush_list);
+
+ /* An overflow can happen if we generate more than 2^32 bytes
+ of redo in this interval i.e.: 4G of redo in 1 second. We can
+ safely consider this as infinity because if we ever come close
+ to 4G we'll start a synchronous flush of dirty pages. */
+ /* redo_avg below is average at which redo is generated in
+ past BUF_FLUSH_STAT_N_INTERVAL + redo generated in the current
+ interval. */
+ redo_avg = (ulint) (buf_flush_stat_sum.redo
+ / BUF_FLUSH_STAT_N_INTERVAL
+ + (lsn - buf_flush_stat_cur.redo));
+
+ /* An overflow can happen possibly if we flush more than 2^32
+ pages in BUF_FLUSH_STAT_N_INTERVAL. This is a very very
+ unlikely scenario. Even when this happens it means that our
+ flush rate will be off the mark. It won't affect correctness
+ of any subsystem. */
+ /* lru_flush_avg below is rate at which pages are flushed as
+ part of LRU flush in past BUF_FLUSH_STAT_N_INTERVAL + the
+ number of pages flushed in the current interval. */
+ lru_flush_avg = buf_flush_stat_sum.n_flushed
+ / BUF_FLUSH_STAT_N_INTERVAL
+ + (buf_lru_flush_page_count
+ - buf_flush_stat_cur.n_flushed);
+
+ n_flush_req = (n_dirty * redo_avg) / log_capacity;
+
+ /* The number of pages that we want to flush from the flush
+ list is the difference between the required rate and the
+ number of pages that we are historically flushing from the
+ LRU list */
+ rate = n_flush_req - lru_flush_avg;
+ return(rate > 0 ? (ulint) rate : 0);
+}
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**********************************************************************
-Validates the flush list. */
+/******************************************************************//**
+Validates the flush list.
+@return TRUE if ok */
static
ibool
buf_flush_validate_low(void)
/*========================*/
- /* out: TRUE if ok */
{
buf_page_t* bpage;
- UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list);
+ UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
+ ut_ad(ut_list_node_313->in_flush_list));
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
@@ -1335,13 +1488,13 @@ buf_flush_validate_low(void)
return(TRUE);
}
-/**********************************************************************
-Validates the flush list. */
+/******************************************************************//**
+Validates the flush list.
+@return TRUE if ok */
UNIV_INTERN
ibool
buf_flush_validate(void)
/*====================*/
- /* out: TRUE if ok */
{
ibool ret;
@@ -1356,3 +1509,4 @@ buf_flush_validate(void)
return(ret);
}
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c
index e5613196dd9..58e2c23275b 100644
--- a/storage/xtradb/buf/buf0lru.c
+++ b/storage/xtradb/buf/buf0lru.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0lru.c
The database buffer replacement algorithm
Created 11/5/1995 Heikki Tuuri
@@ -48,29 +49,33 @@ Created 11/5/1995 Heikki Tuuri
#include "log0recv.h"
#include "srv0srv.h"
-/* The number of blocks from the LRU_old pointer onward, including the block
-pointed to, must be 3/8 of the whole LRU list length, except that the
-tolerance defined below is allowed. Note that the tolerance must be small
-enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the
-LRU_old pointer is not allowed to point to either end of the LRU list. */
+/** The number of blocks from the LRU_old pointer onward, including
+the block pointed to, must be buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
+of the whole LRU list length, except that the tolerance defined below
+is allowed. Note that the tolerance must be small enough such that for
+even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not
+allowed to point to either end of the LRU list. */
#define BUF_LRU_OLD_TOLERANCE 20
-/* The whole LRU list length is divided by this number to determine an
-initial segment in buf_LRU_get_recent_limit */
-
-#define BUF_LRU_INITIAL_RATIO 8
+/** The minimum amount of non-old blocks when the LRU_old list exists
+(that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).
+@see buf_LRU_old_adjust_len */
+#define BUF_LRU_NON_OLD_MIN_LEN 5
+#if BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN
+# error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN"
+#endif
-/* When dropping the search hash index entries before deleting an ibd
+/** 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. */
#define BUF_LRU_DROP_SEARCH_HASH_SIZE 1024
-/* If we switch on the InnoDB monitor because there are too few available
+/** If we switch on the InnoDB monitor because there are too few available
frames in the buffer pool, we set this to TRUE */
-UNIV_INTERN ibool buf_lru_switched_on_innodb_mon = FALSE;
+static ibool buf_lru_switched_on_innodb_mon = FALSE;
-/**********************************************************************
+/******************************************************************//**
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics,
buf_LRU_evict_from_unzip_LRU() decides if we want to evict from
@@ -79,69 +84,80 @@ uncompressed frame (meaning we can evict dirty blocks as well). From
the regular LRU, we will evict the entire block (i.e.: both the
uncompressed and compressed data), which must be clean. */
-/* Number of intervals for which we keep the history of these stats.
+/* @{ */
+
+/** Number of intervals for which we keep the history of these stats.
Each interval is 1 second, defined by the rate at which
srv_error_monitor_thread() calls buf_LRU_stat_update(). */
#define BUF_LRU_STAT_N_INTERVAL 50
-/* Co-efficient with which we multiply I/O operations to equate them
+/** Co-efficient with which we multiply I/O operations to equate them
with page_zip_decompress() operations. */
#define BUF_LRU_IO_TO_UNZIP_FACTOR 50
-/* Sampled values buf_LRU_stat_cur.
+/** Sampled values buf_LRU_stat_cur.
Protected by buf_pool_mutex. Updated by buf_LRU_stat_update(). */
static buf_LRU_stat_t buf_LRU_stat_arr[BUF_LRU_STAT_N_INTERVAL];
-/* Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
+/** Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
static ulint buf_LRU_stat_arr_ind;
-/* Current operation counters. Not protected by any mutex. Cleared
+/** Current operation counters. Not protected by any mutex. Cleared
by buf_LRU_stat_update(). */
UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_cur;
-/* Running sum of past values of buf_LRU_stat_cur.
+/** Running sum of past values of buf_LRU_stat_cur.
Updated by buf_LRU_stat_update(). Protected by buf_pool_mutex. */
UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_sum;
-/**********************************************************************
+/* @} */
+
+/** @name Heuristics for detecting index scan @{ */
+/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
+"old" blocks. Protected by buf_pool_mutex. */
+UNIV_INTERN uint buf_LRU_old_ratio;
+/** Move blocks to "new" LRU list only if the first access was at
+least this many milliseconds ago. Not protected by any mutex or latch. */
+UNIV_INTERN uint buf_LRU_old_threshold_ms;
+/* @} */
+
+/******************************************************************//**
Takes a block out of the LRU list and page hash table.
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
the object will be freed and buf_pool_zip_mutex will be released.
If a compressed page or a compressed-only block descriptor is freed,
other compressed pages or compressed-only block descriptors may be
-relocated. */
+relocated.
+@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
+was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
static
enum buf_page_state
buf_LRU_block_remove_hashed_page(
/*=============================*/
- /* out: the new state of the block
- (BUF_BLOCK_ZIP_FREE if the state was
- BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH
- otherwise) */
- buf_page_t* bpage, /* in: block, must contain a file page and
+ buf_page_t* bpage, /*!< in: block, must contain a file page and
be in a state where it can be freed; there
may or may not be a hash index to the page */
- ibool zip); /* in: TRUE if should remove also the
+ ibool zip); /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
-/**********************************************************************
+/******************************************************************//**
Puts a file page whose has no hash index to the free list. */
static
void
buf_LRU_block_free_hashed_page(
/*===========================*/
- buf_block_t* block, /* in: block, must contain a file page and
+ buf_block_t* block, /*!< in: block, must contain a file page and
be in a state where it can be freed */
ibool have_page_hash_mutex);
-/**********************************************************************
+/******************************************************************//**
Determines if the unzip_LRU list should be used for evicting a victim
-instead of the general LRU list. */
+instead of the general LRU list.
+@return TRUE if should use unzip_LRU */
UNIV_INLINE
ibool
buf_LRU_evict_from_unzip_LRU(
ibool have_LRU_mutex)
/*==============================*/
- /* out: TRUE if should use unzip_LRU */
{
ulint io_avg;
ulint unzip_avg;
@@ -191,18 +207,18 @@ buf_LRU_evict_from_unzip_LRU(
return(unzip_avg <= io_avg * BUF_LRU_IO_TO_UNZIP_FACTOR);
}
-/**********************************************************************
+/******************************************************************//**
Attempts to drop page hash index on a batch of pages belonging to a
particular space id. */
static
void
buf_LRU_drop_page_hash_batch(
/*=========================*/
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- const ulint* arr, /* in: array of page_no */
- ulint count) /* in: number of entries in array */
+ const ulint* arr, /*!< in: array of page_no */
+ ulint count) /*!< in: number of entries in array */
{
ulint i;
@@ -215,7 +231,7 @@ buf_LRU_drop_page_hash_batch(
}
}
-/**********************************************************************
+/******************************************************************//**
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
@@ -224,7 +240,7 @@ static
void
buf_LRU_drop_page_hash_for_tablespace(
/*==================================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
buf_page_t* bpage;
ulint* page_arr;
@@ -249,18 +265,15 @@ scan_again:
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
buf_page_t* prev_bpage;
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
+ if (!block_mutex) {
+ goto next_page;
+ }
+
ut_a(buf_page_in_file(bpage));
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
@@ -328,14 +341,14 @@ next_page:
ut_free(page_arr);
}
-/**********************************************************************
+/******************************************************************//**
Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. */
UNIV_INTERN
void
buf_LRU_invalidate_tablespace(
/*==========================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
buf_page_t* bpage;
ibool all_freed;
@@ -358,20 +371,18 @@ scan_again:
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
buf_page_t* prev_bpage;
ut_a(buf_page_in_file(bpage));
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
+ if (!block_mutex) {
+ bpage = prev_bpage;
+ continue;
+ }
+
if (buf_page_get_space(bpage) == id) {
if (bpage->buf_fix_count > 0
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
@@ -459,51 +470,13 @@ next_page:
}
}
-/**********************************************************************
-Gets the minimum LRU_position field for the blocks in an initial segment
-(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around. */
-UNIV_INTERN
-ulint
-buf_LRU_get_recent_limit(void)
-/*==========================*/
- /* out: the limit; zero if could not determine it */
-{
- const buf_page_t* bpage;
- ulint len;
- ulint limit;
-
- //buf_pool_mutex_enter();
- mutex_enter(&LRU_list_mutex);
-
- len = UT_LIST_GET_LEN(buf_pool->LRU);
-
- if (len < BUF_LRU_OLD_MIN_LEN) {
- /* The LRU list is too short to do read-ahead */
-
- //buf_pool_mutex_exit();
- mutex_exit(&LRU_list_mutex);
-
- return(0);
- }
-
- bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
- limit = buf_page_get_LRU_position(bpage) - len / BUF_LRU_INITIAL_RATIO;
-
- //buf_pool_mutex_exit();
- mutex_exit(&LRU_list_mutex);
-
- return(limit);
-}
-
-/************************************************************************
+/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
void
buf_LRU_insert_zip_clean(
/*=====================*/
- buf_page_t* bpage) /* in: pointer to the block in question */
+ buf_page_t* bpage) /*!< in: pointer to the block in question */
{
buf_page_t* b;
@@ -531,15 +504,15 @@ buf_LRU_insert_zip_clean(
}
}
-/**********************************************************************
+/******************************************************************//**
Try to free an uncompressed page of a compressed block from the unzip
-LRU list. The compressed page is preserved, and it need not be clean. */
+LRU list. The compressed page is preserved, and it need not be clean.
+@return TRUE if freed */
UNIV_INLINE
ibool
buf_LRU_free_from_unzip_LRU_list(
/*=============================*/
- /* out: TRUE if freed */
- ulint n_iterations, /* in: how many times this has been called
+ ulint n_iterations, /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; we will search
n_iterations / 5 of the unzip_LRU list,
@@ -611,14 +584,14 @@ restart:
return(FALSE);
}
-/**********************************************************************
-Try to free a clean page from the common LRU list. */
+/******************************************************************//**
+Try to free a clean page from the common LRU list.
+@return TRUE if freed */
UNIV_INLINE
ibool
buf_LRU_free_from_common_LRU_list(
/*==============================*/
- /* out: TRUE if freed */
- ulint n_iterations, /* in: how many times this has been called
+ ulint n_iterations, /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@@ -639,16 +612,12 @@ restart:
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
enum buf_lru_free_block_status freed;
+ unsigned accessed;
mutex_t* block_mutex
- = buf_page_get_mutex(bpage);
-
-retry_lock:
- mutex_enter(block_mutex);
+ = buf_page_get_mutex_enter(bpage);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
+ if (!block_mutex) {
+ goto restart;
}
if (!bpage->in_LRU_list
@@ -660,11 +629,18 @@ retry_lock:
ut_ad(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
+ accessed = buf_page_is_accessed(bpage);
freed = buf_LRU_free_block(bpage, TRUE, NULL, have_LRU_mutex);
mutex_exit(block_mutex);
switch (freed) {
case BUF_LRU_FREED:
+ /* Keep track of pages that are evicted without
+ ever being accessed. This gives us a measure of
+ the effectiveness of readahead */
+ if (!accessed) {
+ ++buf_pool->stat.n_ra_pages_evicted;
+ }
return(TRUE);
case BUF_LRU_NOT_FREED:
@@ -686,14 +662,14 @@ retry_lock:
return(FALSE);
}
-/**********************************************************************
-Try to free a replaceable block. */
+/******************************************************************//**
+Try to free a replaceable block.
+@return TRUE if found and freed */
UNIV_INTERN
ibool
buf_LRU_search_and_free_block(
/*==========================*/
- /* out: TRUE if found and freed */
- ulint n_iterations) /* in: how many times this has been called
+ ulint n_iterations) /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@@ -734,7 +710,7 @@ buf_LRU_search_and_free_block(
return(freed);
}
-/**********************************************************************
+/******************************************************************//**
Tries to remove LRU flushed blocks from the end of the LRU list and put them
to the free list. This is beneficial for the efficiency of the insert buffer
operation, as flushed pages from non-unique non-clustered indexes are here
@@ -765,16 +741,15 @@ buf_LRU_try_free_flushed_blocks(void)
mutex_exit(&buf_pool_mutex);
}
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if less than 25 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer
-pool for their locks. */
+pool for their locks.
+@return TRUE if less than 25 % of buffer pool left */
UNIV_INTERN
ibool
buf_LRU_buf_pool_running_out(void)
/*==============================*/
- /* out: TRUE if less than 25 % of buffer pool
- left */
{
ibool ret = FALSE;
@@ -795,15 +770,14 @@ buf_LRU_buf_pool_running_out(void)
return(ret);
}
-/**********************************************************************
+/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
-free list. If it is empty, returns NULL. */
+free list. If it is empty, returns NULL.
+@return a free control block, or NULL if the buf_block->free list is empty */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_only(void)
/*=======================*/
- /* out: a free control block, or NULL
- if the buf_block->free list is empty */
{
buf_block_t* block;
@@ -835,17 +809,16 @@ buf_LRU_get_free_only(void)
return(block);
}
-/**********************************************************************
+/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, blocks are moved from the end of the
-LRU list to the free list. */
+LRU list to the free list.
+@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_block(
/*===================*/
- /* out: the free control block,
- in state BUF_BLOCK_READY_FOR_USE */
- ulint zip_size) /* in: compressed page size in bytes,
+ ulint zip_size) /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
{
buf_block_t* block = NULL;
@@ -1031,7 +1004,7 @@ loop:
goto loop;
}
-/***********************************************************************
+/*******************************************************************//**
Moves the LRU_old pointer so that the length of the old blocks list
is inside the allowed limits. */
UNIV_INLINE
@@ -1045,8 +1018,10 @@ buf_LRU_old_adjust_len(void)
ut_a(buf_pool->LRU_old);
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&LRU_list_mutex));
-#if 3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5
-# error "3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5"
+ ut_ad(buf_LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
+ ut_ad(buf_LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
+#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
+# error "BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)"
#endif
#ifdef UNIV_LRU_DEBUG
/* buf_pool->LRU_old must be the first item in the LRU list
@@ -1058,41 +1033,46 @@ buf_LRU_old_adjust_len(void)
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
#endif /* UNIV_LRU_DEBUG */
+ old_len = buf_pool->LRU_old_len;
+ new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
+ * buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
+ UT_LIST_GET_LEN(buf_pool->LRU)
+ - (BUF_LRU_OLD_TOLERANCE
+ + BUF_LRU_NON_OLD_MIN_LEN));
+
for (;;) {
- old_len = buf_pool->LRU_old_len;
- new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
+ buf_page_t* LRU_old = buf_pool->LRU_old;
- ut_ad(buf_pool->LRU_old->in_LRU_list);
- ut_a(buf_pool->LRU_old);
+ ut_a(LRU_old);
+ ut_ad(LRU_old->in_LRU_list);
#ifdef UNIV_LRU_DEBUG
- ut_a(buf_pool->LRU_old->old);
+ ut_a(LRU_old->old);
#endif /* UNIV_LRU_DEBUG */
/* Update the LRU_old pointer if necessary */
- if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
+ if (old_len + BUF_LRU_OLD_TOLERANCE < new_len) {
- buf_pool->LRU_old = UT_LIST_GET_PREV(
- LRU, buf_pool->LRU_old);
+ buf_pool->LRU_old = LRU_old = UT_LIST_GET_PREV(
+ LRU, LRU_old);
#ifdef UNIV_LRU_DEBUG
- ut_a(!buf_pool->LRU_old->old);
+ ut_a(!LRU_old->old);
#endif /* UNIV_LRU_DEBUG */
- buf_page_set_old(buf_pool->LRU_old, TRUE);
- buf_pool->LRU_old_len++;
+ old_len = ++buf_pool->LRU_old_len;
+ buf_page_set_old(LRU_old, TRUE);
} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
- buf_page_set_old(buf_pool->LRU_old, FALSE);
- buf_pool->LRU_old = UT_LIST_GET_NEXT(
- LRU, buf_pool->LRU_old);
- buf_pool->LRU_old_len--;
+ buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old);
+ old_len = --buf_pool->LRU_old_len;
+ buf_page_set_old(LRU_old, FALSE);
} else {
return;
}
}
}
-/***********************************************************************
+/*******************************************************************//**
Initializes the old blocks pointer in the LRU list. This function should be
called when the LRU list grows to BUF_LRU_OLD_MIN_LEN length. */
static
@@ -1110,12 +1090,13 @@ buf_LRU_old_init(void)
the adjust function to move the LRU_old pointer to the right
position */
- bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
- while (bpage != NULL) {
+ for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage != NULL;
+ bpage = UT_LIST_GET_PREV(LRU, bpage)) {
ut_ad(bpage->in_LRU_list);
- buf_page_set_old(bpage, TRUE);
- bpage = UT_LIST_GET_NEXT(LRU, bpage);
+ ut_ad(buf_page_in_file(bpage));
+ /* This loop temporarily violates the
+ assertions of buf_page_set_old(). */
+ bpage->old = TRUE;
}
buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU);
@@ -1124,13 +1105,13 @@ buf_LRU_old_init(void)
buf_LRU_old_adjust_len();
}
-/**********************************************************************
+/******************************************************************//**
Remove a block from the unzip_LRU list if it belonged to the list. */
static
void
buf_unzip_LRU_remove_block_if_needed(
/*=================================*/
- buf_page_t* bpage) /* in/out: control block */
+ buf_page_t* bpage) /*!< in/out: control block */
{
ut_ad(buf_pool);
ut_ad(bpage);
@@ -1148,13 +1129,13 @@ buf_unzip_LRU_remove_block_if_needed(
}
}
-/**********************************************************************
+/******************************************************************//**
Removes a block from the LRU list. */
UNIV_INLINE
void
buf_LRU_remove_block(
/*=================*/
- buf_page_t* bpage) /* in: control block */
+ buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_pool);
ut_ad(bpage);
@@ -1170,16 +1151,19 @@ buf_LRU_remove_block(
if (UNIV_UNLIKELY(bpage == buf_pool->LRU_old)) {
- /* Below: the previous block is guaranteed to exist, because
- the LRU_old pointer is only allowed to differ by the
- tolerance value from strict 3/8 of the LRU list length. */
+ /* Below: the previous block is guaranteed to exist,
+ because the LRU_old pointer is only allowed to differ
+ by BUF_LRU_OLD_TOLERANCE from strict
+ buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the LRU
+ list length. */
+ buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
- buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, bpage);
- ut_a(buf_pool->LRU_old);
+ ut_a(prev_bpage);
#ifdef UNIV_LRU_DEBUG
- ut_a(!buf_pool->LRU_old->old);
+ ut_a(!prev_bpage->old);
#endif /* UNIV_LRU_DEBUG */
- buf_page_set_old(buf_pool->LRU_old, TRUE);
+ buf_pool->LRU_old = prev_bpage;
+ buf_page_set_old(prev_bpage, TRUE);
buf_pool->LRU_old_len++;
}
@@ -1190,10 +1174,19 @@ buf_LRU_remove_block(
buf_unzip_LRU_remove_block_if_needed(bpage);
- /* If the LRU list is so short that LRU_old not defined, return */
+ /* If the LRU list is so short that LRU_old is not defined,
+ clear the "old" flags and return */
if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
+ for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU); bpage != NULL;
+ bpage = UT_LIST_GET_NEXT(LRU, bpage)) {
+ /* This loop temporarily violates the
+ assertions of buf_page_set_old(). */
+ bpage->old = FALSE;
+ }
+
buf_pool->LRU_old = NULL;
+ buf_pool->LRU_old_len = 0;
return;
}
@@ -1210,14 +1203,14 @@ buf_LRU_remove_block(
buf_LRU_old_adjust_len();
}
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list of decompressed zip pages. */
UNIV_INTERN
void
buf_unzip_LRU_add_block(
/*====================*/
- buf_block_t* block, /* in: control block */
- ibool old) /* in: TRUE if should be put to the end
+ buf_block_t* block, /*!< in: control block */
+ ibool old) /*!< in: TRUE if should be put to the end
of the list, else put to the start */
{
ut_ad(buf_pool);
@@ -1237,16 +1230,14 @@ buf_unzip_LRU_add_block(
}
}
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list end. */
UNIV_INLINE
void
buf_LRU_add_block_to_end_low(
/*=========================*/
- buf_page_t* bpage) /* in: control block */
+ buf_page_t* bpage) /*!< in: control block */
{
- buf_page_t* last_bpage;
-
ut_ad(buf_pool);
ut_ad(bpage);
//ut_ad(buf_pool_mutex_own());
@@ -1254,31 +1245,18 @@ buf_LRU_add_block_to_end_low(
ut_a(buf_page_in_file(bpage));
- last_bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-
- if (last_bpage) {
- bpage->LRU_position = last_bpage->LRU_position;
- } else {
- bpage->LRU_position = buf_pool_clock_tic();
- }
-
ut_ad(!bpage->in_LRU_list);
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
bpage->in_LRU_list = TRUE;
- buf_page_set_old(bpage, TRUE);
-
- if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-
- buf_pool->LRU_old_len++;
- }
-
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
/* Adjust the length of the old block list if necessary */
+ buf_page_set_old(bpage, TRUE);
+ buf_pool->LRU_old_len++;
buf_LRU_old_adjust_len();
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
@@ -1287,6 +1265,8 @@ buf_LRU_add_block_to_end_low(
defined: init it */
buf_LRU_old_init();
+ } else {
+ buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
}
/* If this is a zipped block with decompressed frame as well
@@ -1296,14 +1276,14 @@ buf_LRU_add_block_to_end_low(
}
}
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INLINE
void
buf_LRU_add_block_low(
/*==================*/
- buf_page_t* bpage, /* in: control block */
- ibool old) /* in: TRUE if should be put to the old blocks
+ buf_page_t* bpage, /*!< in: control block */
+ ibool old) /*!< in: TRUE if should be put to the old blocks
in the LRU list, else put to the start; if the
LRU list is very short, the block is added to
the start, regardless of this parameter */
@@ -1320,7 +1300,6 @@ buf_LRU_add_block_low(
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
- bpage->LRU_position = buf_pool_clock_tic();
bpage->freed_page_clock = buf_pool->freed_page_clock;
} else {
#ifdef UNIV_LRU_DEBUG
@@ -1335,23 +1314,17 @@ buf_LRU_add_block_low(
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
bpage);
buf_pool->LRU_old_len++;
-
- /* We copy the LRU position field of the previous block
- to the new block */
-
- bpage->LRU_position = (buf_pool->LRU_old)->LRU_position;
}
bpage->in_LRU_list = TRUE;
- buf_page_set_old(bpage, old);
-
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
/* Adjust the length of the old block list if necessary */
+ buf_page_set_old(bpage, old);
buf_LRU_old_adjust_len();
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
@@ -1360,6 +1333,8 @@ buf_LRU_add_block_low(
defined: init it */
buf_LRU_old_init();
+ } else {
+ buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
}
/* If this is a zipped block with decompressed frame as well
@@ -1369,14 +1344,14 @@ buf_LRU_add_block_low(
}
}
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INTERN
void
buf_LRU_add_block(
/*==============*/
- buf_page_t* bpage, /* in: control block */
- ibool old) /* in: TRUE if should be put to the old
+ buf_page_t* bpage, /*!< in: control block */
+ ibool old) /*!< in: TRUE if should be put to the old
blocks in the LRU list, else put to the start;
if the LRU list is very short, the block is
added to the start, regardless of this
@@ -1385,31 +1360,38 @@ buf_LRU_add_block(
buf_LRU_add_block_low(bpage, old);
}
-/**********************************************************************
+/******************************************************************//**
Moves a block to the start of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_young(
/*=====================*/
- buf_page_t* bpage) /* in: control block */
+ buf_page_t* bpage) /*!< in: control block */
{
+ //ut_ad(buf_pool_mutex_own());
+ ut_ad(mutex_own(&LRU_list_mutex));
+
+ if (bpage->old) {
+ buf_pool->stat.n_pages_made_young++;
+ }
+
buf_LRU_remove_block(bpage);
buf_LRU_add_block_low(bpage, FALSE);
}
-/**********************************************************************
+/******************************************************************//**
Moves a block to the end of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_old(
/*===================*/
- buf_page_t* bpage) /* in: control block */
+ buf_page_t* bpage) /*!< in: control block */
{
buf_LRU_remove_block(bpage);
buf_LRU_add_block_to_end_low(bpage);
}
-/**********************************************************************
+/******************************************************************//**
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
@@ -1419,19 +1401,18 @@ accessible via bpage.
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
-buf_page_get_mutex() may be held when calling this function. */
+buf_page_get_mutex() may be held when calling this function.
+@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
+BUF_LRU_NOT_FREED otherwise. */
UNIV_INTERN
enum buf_lru_free_block_status
buf_LRU_free_block(
/*===============*/
- /* out: BUF_LRU_FREED if freed,
- BUF_LRU_CANNOT_RELOCATE or
- BUF_LRU_NOT_FREED otherwise. */
- buf_page_t* bpage, /* in: block to be freed */
- ibool zip, /* in: TRUE if should remove also the
+ buf_page_t* bpage, /*!< in: block to be freed */
+ ibool zip, /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
ibool* buf_pool_mutex_released,
- /* in: pointer to a variable that will
+ /*!< in: pointer to a variable that will
be assigned TRUE if buf_pool_mutex
was temporarily released, or NULL */
ibool have_LRU_mutex)
@@ -1590,15 +1571,6 @@ not_freed:
buf_pool->LRU_old = b;
}
-#ifdef UNIV_LRU_DEBUG
- ut_a(prev_b->old
- || !UT_LIST_GET_NEXT(LRU, b)
- || UT_LIST_GET_NEXT(LRU, b)->old);
- } else {
- ut_a(!prev_b->old
- || !UT_LIST_GET_NEXT(LRU, b)
- || !UT_LIST_GET_NEXT(LRU, b)->old);
-#endif /* UNIV_LRU_DEBUG */
}
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
@@ -1614,6 +1586,11 @@ not_freed:
defined: init it */
buf_LRU_old_init();
}
+#ifdef UNIV_LRU_DEBUG
+ /* Check that the "old" flag is consistent
+ in the block and its neighbours. */
+ buf_page_set_old(b, buf_page_is_old(b));
+#endif /* UNIV_LRU_DEBUG */
} else {
b->in_LRU_list = FALSE;
buf_LRU_add_block_low(b, buf_page_is_old(b));
@@ -1722,13 +1699,13 @@ not_freed:
return(BUF_LRU_FREED);
}
-/**********************************************************************
+/******************************************************************//**
Puts a block back to the free list. */
UNIV_INTERN
void
buf_LRU_block_free_non_file_page(
/*=============================*/
- buf_block_t* block, /* in: block, must not contain a file page */
+ buf_block_t* block, /*!< in: block, must not contain a file page */
ibool have_page_hash_mutex)
{
void* data;
@@ -1783,26 +1760,24 @@ buf_LRU_block_free_non_file_page(
UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
}
-/**********************************************************************
+/******************************************************************//**
Takes a block out of the LRU list and page hash table.
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
the object will be freed and buf_pool_zip_mutex will be released.
If a compressed page or a compressed-only block descriptor is freed,
other compressed pages or compressed-only block descriptors may be
-relocated. */
+relocated.
+@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
+was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
static
enum buf_page_state
buf_LRU_block_remove_hashed_page(
/*=============================*/
- /* out: the new state of the block
- (BUF_BLOCK_ZIP_FREE if the state was
- BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH
- otherwise) */
- buf_page_t* bpage, /* in: block, must contain a file page and
+ buf_page_t* bpage, /*!< in: block, must contain a file page and
be in a state where it can be freed; there
may or may not be a hash index to the page */
- ibool zip) /* in: TRUE if should remove also the
+ ibool zip) /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
{
const buf_page_t* hashed_bpage;
@@ -1962,6 +1937,9 @@ buf_LRU_block_remove_hashed_page(
void* data = bpage->zip.data;
bpage->zip.data = NULL;
+ ut_ad(!bpage->in_free_list);
+ ut_ad(!bpage->in_flush_list);
+ ut_ad(!bpage->in_LRU_list);
mutex_exit(&((buf_block_t*) bpage)->mutex);
//buf_pool_mutex_exit_forbid();
buf_buddy_free(data, page_zip_get_size(&bpage->zip), TRUE);
@@ -1985,13 +1963,13 @@ buf_LRU_block_remove_hashed_page(
return(BUF_BLOCK_ZIP_FREE);
}
-/**********************************************************************
+/******************************************************************//**
Puts a file page whose has no hash index to the free list. */
static
void
buf_LRU_block_free_hashed_page(
/*===========================*/
- buf_block_t* block, /* in: block, must contain a file page and
+ buf_block_t* block, /*!< in: block, must contain a file page and
be in a state where it can be freed */
ibool have_page_hash_mutex)
{
@@ -2003,7 +1981,53 @@ buf_LRU_block_free_hashed_page(
buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
}
-/************************************************************************
+/**********************************************************************//**
+Updates buf_LRU_old_ratio.
+@return updated old_pct */
+UNIV_INTERN
+uint
+buf_LRU_old_ratio_update(
+/*=====================*/
+ uint old_pct,/*!< in: Reserve this percentage of
+ the buffer pool for "old" blocks. */
+ ibool adjust) /*!< in: TRUE=adjust the LRU list;
+ FALSE=just assign buf_LRU_old_ratio
+ during the initialization of InnoDB */
+{
+ uint ratio;
+
+ ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100;
+ if (ratio < BUF_LRU_OLD_RATIO_MIN) {
+ ratio = BUF_LRU_OLD_RATIO_MIN;
+ } else if (ratio > BUF_LRU_OLD_RATIO_MAX) {
+ ratio = BUF_LRU_OLD_RATIO_MAX;
+ }
+
+ if (adjust) {
+ //buf_pool_mutex_enter();
+ mutex_enter(&LRU_list_mutex);
+
+ if (ratio != buf_LRU_old_ratio) {
+ buf_LRU_old_ratio = ratio;
+
+ if (UT_LIST_GET_LEN(buf_pool->LRU)
+ >= BUF_LRU_OLD_MIN_LEN) {
+ buf_LRU_old_adjust_len();
+ }
+ }
+
+ //buf_pool_mutex_exit();
+ mutex_exit(&LRU_list_mutex);
+ } else {
+ buf_LRU_old_ratio = ratio;
+ }
+
+ /* the reverse of
+ ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100 */
+ return((uint) (ratio * 100 / (double) BUF_LRU_OLD_RATIO_DIV + 0.5));
+}
+
+/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
UNIV_INTERN
@@ -2041,9 +2065,222 @@ func_exit:
memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
}
+/********************************************************************//**
+Dump the LRU page list to the specific file. */
+#define LRU_DUMP_FILE "ib_lru_dump"
+
+UNIV_INTERN
+ibool
+buf_LRU_file_dump(void)
+/*===================*/
+{
+ os_file_t dump_file = -1;
+ ibool success;
+ byte* buffer_base = NULL;
+ byte* buffer = NULL;
+ buf_page_t* bpage;
+ ulint buffers;
+ ulint offset;
+ ibool ret = FALSE;
+ ulint i;
+
+ for (i = 0; i < srv_n_data_files; i++) {
+ if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
+ fprintf(stderr,
+ " InnoDB: The name '%s' seems to be used for"
+ " innodb_data_file_path. Dumping LRU list is not"
+ " done for safeness.\n", LRU_DUMP_FILE);
+ goto end;
+ }
+ }
+
+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
+ if (!buffer) {
+ fprintf(stderr,
+ " InnoDB: cannot allocate buffer.\n");
+ goto end;
+ }
+
+ dump_file = os_file_create(LRU_DUMP_FILE, OS_FILE_OVERWRITE,
+ OS_FILE_NORMAL, OS_DATA_FILE, &success);
+ if (!success) {
+ os_file_get_last_error(TRUE);
+ fprintf(stderr,
+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
+ goto end;
+ }
+
+ mutex_enter(&LRU_list_mutex);
+ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
+
+ buffers = offset = 0;
+ while (bpage != NULL) {
+ if (offset == 0) {
+ memset(buffer, 0, UNIV_PAGE_SIZE);
+ }
+
+ mach_write_to_4(buffer + offset * 4, bpage->space);
+ offset++;
+ mach_write_to_4(buffer + offset * 4, bpage->offset);
+ offset++;
+
+ if (offset == UNIV_PAGE_SIZE/4) {
+ success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
+ UNIV_PAGE_SIZE);
+ if (!success) {
+ mutex_exit(&LRU_list_mutex);
+ fprintf(stderr,
+ " InnoDB: cannot write page %lu of %s\n",
+ buffers, LRU_DUMP_FILE);
+ goto end;
+ }
+ buffers++;
+ offset = 0;
+ }
+
+ bpage = UT_LIST_GET_PREV(LRU, bpage);
+ }
+ mutex_exit(&LRU_list_mutex);
+
+ if (offset == 0) {
+ memset(buffer, 0, UNIV_PAGE_SIZE);
+ }
+
+ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
+ offset++;
+ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
+ offset++;
+
+ success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
+ UNIV_PAGE_SIZE);
+ if (!success) {
+ goto end;
+ }
+
+ ret = TRUE;
+end:
+ if (dump_file != -1)
+ os_file_close(dump_file);
+ if (buffer_base)
+ ut_free(buffer_base);
+
+ return(ret);
+}
+/********************************************************************//**
+Read the pages based on the specific file.*/
+UNIV_INTERN
+ibool
+buf_LRU_file_restore(void)
+/*======================*/
+{
+ os_file_t dump_file = -1;
+ ibool success;
+ byte* buffer_base = NULL;
+ byte* buffer = NULL;
+ ulint buffers;
+ ulint offset;
+ ulint reads = 0;
+ ulint req = 0;
+ ibool terminated = FALSE;
+ ibool ret = FALSE;
+
+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
+ if (!buffer) {
+ fprintf(stderr,
+ " InnoDB: cannot allocate buffer.\n");
+ goto end;
+ }
+
+ dump_file = os_file_create_simple_no_error_handling(
+ LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
+ if (!success) {
+ os_file_get_last_error(TRUE);
+ fprintf(stderr,
+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
+ goto end;
+ }
+
+ buffers = 0;
+ while (!terminated) {
+ success = os_file_read(dump_file, buffer,
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
+ UNIV_PAGE_SIZE);
+ if (!success) {
+ fprintf(stderr,
+ " InnoDB: cannot read page %lu of %s,"
+ " or meet unexpected terminal.",
+ buffers, LRU_DUMP_FILE);
+ goto end;
+ }
+
+ for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
+ ulint space_id, zip_size, page_no;
+ ulint err;
+ ib_int64_t tablespace_version;
+
+ space_id = mach_read_from_4(buffer + offset * 4);
+ page_no = mach_read_from_4(buffer + (offset + 1) * 4);
+ if (space_id == 0xFFFFFFFFUL
+ || page_no == 0xFFFFFFFFUL) {
+ terminated = TRUE;
+ break;
+ }
+
+ if (offset % 16 == 15) {
+ os_aio_simulated_wake_handler_threads();
+ buf_flush_free_margin(FALSE);
+ }
+
+ zip_size = fil_space_get_zip_size(space_id);
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+ continue;
+ }
+
+ if (fil_area_is_exist(space_id, zip_size, page_no, 0,
+ zip_size ? zip_size : UNIV_PAGE_SIZE)) {
+
+ tablespace_version = fil_space_get_version(space_id);
+
+ req++;
+ reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
+ | OS_AIO_SIMULATED_WAKE_LATER,
+ space_id, zip_size, TRUE,
+ tablespace_version, page_no, NULL);
+ buf_LRU_stat_inc_io();
+ }
+ }
+
+ buffers++;
+ }
+
+ os_aio_simulated_wake_handler_threads();
+ buf_flush_free_margin(FALSE);
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: reading pages based on the dumped LRU list was done."
+ " (requested: %lu, read: %lu)\n", req, reads);
+ ret = TRUE;
+end:
+ if (dump_file != -1)
+ os_file_close(dump_file);
+ if (buffer_base)
+ ut_free(buffer_base);
+
+ return(ret);
+}
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
-Validates the LRU list. */
+/**********************************************************************//**
+Validates the LRU list.
+@return TRUE */
UNIV_INTERN
ibool
buf_LRU_validate(void)
@@ -2053,7 +2290,6 @@ buf_LRU_validate(void)
buf_block_t* block;
ulint old_len;
ulint new_len;
- ulint LRU_pos;
ut_ad(buf_pool);
//buf_pool_mutex_enter();
@@ -2063,12 +2299,17 @@ buf_LRU_validate(void)
ut_a(buf_pool->LRU_old);
old_len = buf_pool->LRU_old_len;
- new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
+ new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
+ * buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
+ UT_LIST_GET_LEN(buf_pool->LRU)
+ - (BUF_LRU_OLD_TOLERANCE
+ + BUF_LRU_NON_OLD_MIN_LEN));
ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
}
- UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU);
+ UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU,
+ ut_ad(ut_list_node_313->in_LRU_list));
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
@@ -2093,33 +2334,30 @@ buf_LRU_validate(void)
}
if (buf_page_is_old(bpage)) {
- old_len++;
- }
+ const buf_page_t* prev
+ = UT_LIST_GET_PREV(LRU, bpage);
+ const buf_page_t* next
+ = UT_LIST_GET_NEXT(LRU, bpage);
- if (buf_pool->LRU_old && (old_len == 1)) {
- ut_a(buf_pool->LRU_old == bpage);
- }
+ if (!old_len++) {
+ ut_a(buf_pool->LRU_old == bpage);
+ } else {
+ ut_a(!prev || buf_page_is_old(prev));
+ }
- LRU_pos = buf_page_get_LRU_position(bpage);
+ ut_a(!next || buf_page_is_old(next));
+ }
bpage = UT_LIST_GET_NEXT(LRU, bpage);
-
- if (bpage) {
- /* If the following assert fails, it may
- not be an error: just the buf_pool clock
- has wrapped around */
- ut_a(LRU_pos >= buf_page_get_LRU_position(bpage));
- }
}
- if (buf_pool->LRU_old) {
- ut_a(buf_pool->LRU_old_len == old_len);
- }
+ ut_a(buf_pool->LRU_old_len == old_len);
mutex_exit(&LRU_list_mutex);
mutex_enter(&free_list_mutex);
- UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free);
+ UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free,
+ ut_ad(ut_list_node_313->in_free_list));
for (bpage = UT_LIST_GET_FIRST(buf_pool->free);
bpage != NULL;
@@ -2131,7 +2369,9 @@ buf_LRU_validate(void)
mutex_exit(&free_list_mutex);
mutex_enter(&LRU_list_mutex);
- UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU);
+ UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
+ ut_ad(ut_list_node_313->in_unzip_LRU_list
+ && ut_list_node_313->page.in_LRU_list));
for (block = UT_LIST_GET_FIRST(buf_pool->unzip_LRU);
block;
@@ -2149,7 +2389,7 @@ buf_LRU_validate(void)
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Prints the LRU list. */
UNIV_INTERN
void
@@ -2162,9 +2402,6 @@ buf_LRU_print(void)
//buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
- fprintf(stderr, "Pool ulint clock %lu\n",
- (ulong) buf_pool->ulint_clock);
-
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
while (bpage != NULL) {
@@ -2195,18 +2432,16 @@ buf_LRU_print(void)
const byte* frame;
case BUF_BLOCK_FILE_PAGE:
frame = buf_block_get_frame((buf_block_t*) bpage);
- fprintf(stderr, "\nLRU pos %lu type %lu"
+ fprintf(stderr, "\ntype %lu"
" index id %lu\n",
- (ulong) buf_page_get_LRU_position(bpage),
(ulong) fil_page_get_type(frame),
(ulong) ut_dulint_get_low(
btr_page_get_index_id(frame)));
break;
case BUF_BLOCK_ZIP_PAGE:
frame = bpage->zip.data;
- fprintf(stderr, "\nLRU pos %lu type %lu size %lu"
+ fprintf(stderr, "\ntype %lu size %lu"
" index id %lu\n",
- (ulong) buf_page_get_LRU_position(bpage),
(ulong) fil_page_get_type(frame),
(ulong) buf_page_get_zip_size(bpage),
(ulong) ut_dulint_get_low(
@@ -2214,8 +2449,7 @@ buf_LRU_print(void)
break;
default:
- fprintf(stderr, "\nLRU pos %lu !state %lu!\n",
- (ulong) buf_page_get_LRU_position(bpage),
+ fprintf(stderr, "\n!state %lu!\n",
(ulong) buf_page_get_state(bpage));
break;
}
diff --git a/storage/xtradb/buf/buf0rea.c b/storage/xtradb/buf/buf0rea.c
index 086ea035a7b..08aaac788d5 100644
--- a/storage/xtradb/buf/buf0rea.c
+++ b/storage/xtradb/buf/buf0rea.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0rea.c
The database buffer read
Created 11/5/1995 Heikki Tuuri
@@ -35,61 +36,47 @@ Created 11/5/1995 Heikki Tuuri
#include "trx0sys.h"
#include "os0file.h"
#include "srv0start.h"
+#include "srv0srv.h"
-extern ulint srv_read_ahead;
-extern ulint srv_read_ahead_rnd;
-extern ulint srv_read_ahead_seq;
-extern ulint srv_buf_pool_reads;
-
-/* The size in blocks of the area where the random read-ahead algorithm counts
-the accessed pages when deciding whether to read-ahead */
-#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA
-
-/* There must be at least this many pages in buf_pool in the area to start
-a random read-ahead */
-#define BUF_READ_AHEAD_RANDOM_THRESHOLD (5 + buf_read_ahead_random_area / 8)
-
-/* The linear read-ahead area size */
+/** The linear read-ahead area size */
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
-/* The linear read-ahead threshold */
-#define LINEAR_AREA_THRESHOLD_COEF 5 / 8
-
-/* If there are buf_pool->curr_size per the number below pending reads, then
+/** If there are buf_pool->curr_size per the number below pending reads, then
read-ahead is not done: this is to prevent flooding the buffer pool with
i/o-fixed buffer blocks */
#define BUF_READ_AHEAD_PEND_LIMIT 2
-/************************************************************************
+/********************************************************************//**
Low-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there, in which case does nothing.
Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
-flag is cleared and the x-lock released by an i/o-handler thread. */
-static
+flag is cleared and the x-lock released by an i/o-handler thread.
+@return 1 if a read request was queued, 0 if the page already resided
+in buf_pool, or if the page is in the doublewrite buffer blocks in
+which case it is never read into the pool, or if the tablespace does
+not exist or is being dropped
+@return 1 if read request is issued. 0 if it is not */
+UNIV_INTERN
ulint
buf_read_page_low(
/*==============*/
- /* out: 1 if a read request was queued, 0 if the page
- already resided in buf_pool, or if the page is in
- the doublewrite buffer blocks in which case it is never
- read into the pool, or if the tablespace does not
- exist or is being dropped */
- ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
trying to read from a non-existent tablespace, or a
tablespace which is just now being dropped */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ...,
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
at read-ahead functions) */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size, or 0 */
- ibool unzip, /* in: TRUE=request uncompressed page */
- ib_int64_t tablespace_version, /* in: if the space memory object has
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
+ ib_int64_t tablespace_version, /*!< in: if the space memory object has
this timestamp different from what we are giving here,
treat the tablespace as dropped; this is a timestamp we
use to stop dangling page reads from a tablespace
which we have DISCARDed + IMPORTed back */
- ulint offset) /* in: page number */
+ ulint offset, /*!< in: page number */
+ trx_t* trx)
{
buf_page_t* bpage;
ulint wake_later;
@@ -190,15 +177,15 @@ not_to_recover:
ut_ad(buf_page_in_file(bpage));
if (zip_size) {
- *err = fil_io(OS_FILE_READ | wake_later,
+ *err = _fil_io(OS_FILE_READ | wake_later,
sync, space, zip_size, offset, 0, zip_size,
- bpage->zip.data, bpage);
+ bpage->zip.data, bpage, trx);
} else {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
- *err = fil_io(OS_FILE_READ | wake_later,
+ *err = _fil_io(OS_FILE_READ | wake_later,
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
- ((buf_block_t*) bpage)->frame, bpage);
+ ((buf_block_t*) bpage)->frame, bpage, trx);
}
ut_a(*err == DB_SUCCESS);
@@ -211,205 +198,34 @@ not_to_recover:
return(1);
}
-/************************************************************************
-Applies a random read-ahead in buf_pool if there are at least a threshold
-value of accessed pages from the random read-ahead area. Does not read any
-page, not even the one at the position (space, offset), if the read-ahead
-mechanism is not activated. NOTE 1: the calling thread may own latches on
-pages: to avoid deadlocks this function must be written such that it cannot
-end up waiting for these latches! NOTE 2: the calling thread must want
-access to the page given: this rule is set to prevent unintended read-aheads
-performed by ibuf routines, a situation which could result in a deadlock if
-the OS does not support asynchronous i/o. */
-static
-ulint
-buf_read_ahead_random(
-/*==================*/
- /* out: number of page read requests issued; NOTE
- that if we read ibuf pages, it may happen that
- the page at the given page number does not get
- read even if we return a value > 0! */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset) /* in: page number of a page which the current thread
- wants to access */
-{
- ib_int64_t tablespace_version;
- ulint recent_blocks = 0;
- ulint count;
- ulint LRU_recent_limit;
- ulint ibuf_mode;
- ulint low, high;
- ulint err;
- ulint i;
- ulint buf_read_ahead_random_area;
-
- if (!(srv_read_ahead & 1)) {
- return(0);
- }
-
- if (srv_startup_is_before_trx_rollback_phase) {
- /* No read-ahead to avoid thread deadlocks */
- return(0);
- }
-
- if (ibuf_bitmap_page(zip_size, offset)
- || trx_sys_hdr_page(space, offset)) {
-
- /* If it is an ibuf bitmap page or trx sys hdr, we do
- no read-ahead, as that could break the ibuf page access
- order */
-
- 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! */
-
- tablespace_version = fil_space_get_version(space);
-
- buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA;
-
- 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)) {
-
- high = fil_space_get_size(space);
- }
-
- /* Get the minimum LRU_position field value for an initial segment
- of the LRU list, to determine which blocks have recently been added
- to the start of the list. */
-
- LRU_recent_limit = buf_LRU_get_recent_limit();
-
- //buf_pool_mutex_enter();
- mutex_enter(&buf_pool_mutex);
-
- if (buf_pool->n_pend_reads
- > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
- //buf_pool_mutex_exit();
- mutex_exit(&buf_pool_mutex);
-
- return(0);
- }
- mutex_exit(&buf_pool_mutex);
-
- /* Count how many blocks in the area have been recently accessed,
- that is, reside near the start of the LRU list. */
-
- rw_lock_s_lock(&page_hash_latch);
- for (i = low; i < high; i++) {
- const buf_page_t* bpage = buf_page_hash_get(space, i);
-
- if (bpage
- && buf_page_is_accessed(bpage)
- && (buf_page_get_LRU_position(bpage) > LRU_recent_limit)) {
-
- recent_blocks++;
-
- if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
-
- //buf_pool_mutex_exit();
- rw_lock_s_unlock(&page_hash_latch);
- goto read_ahead;
- }
- }
- }
-
- //buf_pool_mutex_exit();
- rw_lock_s_unlock(&page_hash_latch);
- /* Do nothing */
- return(0);
-
-read_ahead:
- /* Read all the suitable blocks within the area */
-
- if (ibuf_inside()) {
- ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
- } else {
- ibuf_mode = BUF_READ_ANY_PAGE;
- }
-
- count = 0;
-
- for (i = low; i < high; i++) {
- /* It is only sensible to do read-ahead in the non-sync aio
- mode: hence FALSE as the first parameter */
-
- if (!ibuf_bitmap_page(zip_size, i)) {
- count += buf_read_page_low(
- &err, FALSE,
- ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
- space, zip_size, FALSE,
- tablespace_version, i);
- if (err == DB_TABLESPACE_DELETED) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: in random"
- " readahead trying to access\n"
- "InnoDB: tablespace %lu page %lu,\n"
- "InnoDB: but the tablespace does not"
- " exist or is just being dropped.\n",
- (ulong) space, (ulong) i);
- }
- }
- }
-
- /* In simulated aio we wake the aio handler threads only after
- queuing all aio requests, in native aio the following call does
- nothing: */
-
- os_aio_simulated_wake_handler_threads();
-
-#ifdef UNIV_DEBUG
- if (buf_debug_prints && (count > 0)) {
- fprintf(stderr,
- "Random read-ahead space %lu offset %lu pages %lu\n",
- (ulong) space, (ulong) offset,
- (ulong) count);
- }
-#endif /* UNIV_DEBUG */
-
- ++srv_read_ahead_rnd;
- return(count);
-}
-
-/************************************************************************
+/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible. */
+released by the i/o-handler thread.
+@return TRUE if page has been read in, FALSE in case of failure */
UNIV_INTERN
-ulint
+ibool
buf_read_page(
/*==========*/
- /* out: number of page read requests issued: this can
- be > 1 if read-ahead occurred */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset, /*!< in: page number */
+ trx_t* trx)
{
ib_int64_t tablespace_version;
ulint count;
- ulint count2;
ulint err;
tablespace_version = fil_space_get_version(space);
- count = buf_read_ahead_random(space, zip_size, offset);
-
/* We do the i/o in the synchronous aio mode to save thread
switches: hence TRUE */
- count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
- zip_size, FALSE,
- tablespace_version, offset);
- srv_buf_pool_reads+= count2;
+ count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
+ zip_size, FALSE,
+ tablespace_version, offset, trx);
+ srv_buf_pool_reads += count;
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -426,14 +242,14 @@ buf_read_page(
/* Increment number of I/O operations used for LRU policy. */
buf_LRU_stat_inc_io();
- return(count + count2);
+ return(count > 0);
}
-/************************************************************************
+/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
-that the the algorithm looks at the 'natural' adjacent successor and
+that the algorithm looks at the 'natural' adjacent successor and
predecessor of the page, which on the leaf level of a B-tree are the next
and previous page in the chain of leaves. To know these, the page specified
in (space, offset) must already be present in the buf_pool. Thus, the
@@ -451,16 +267,17 @@ function must be written such that it cannot end up waiting for these
latches!
NOTE 3: the calling thread must want access to the page given: this rule is
set to prevent unintended read-aheads performed by ibuf routines, a situation
-which could result in a deadlock if the OS does not support asynchronous io. */
+which could result in a deadlock if the OS does not support asynchronous io.
+@return number of page read requests issued */
UNIV_INTERN
ulint
buf_read_ahead_linear(
/*==================*/
- /* out: number of page read requests issued */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset) /* in: page number of a page; NOTE: the current thread
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset, /*!< in: page number of a page; NOTE: the current thread
must want access to this page (see NOTE 3 above) */
+ trx_t* trx)
{
ib_int64_t tablespace_version;
buf_page_t* bpage;
@@ -478,11 +295,12 @@ buf_read_ahead_linear(
ulint i;
const ulint buf_read_ahead_linear_area
= BUF_READ_AHEAD_LINEAR_AREA;
+ ulint threshold;
if (!(srv_read_ahead & 2)) {
return(0);
}
-
+
if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
/* No read-ahead to avoid thread deadlocks */
return(0);
@@ -545,6 +363,11 @@ buf_read_ahead_linear(
asc_or_desc = -1;
}
+ /* How many out of order accessed pages can we ignore
+ when working out the access pattern for linear readahead */
+ threshold = ut_min((64 - srv_read_ahead_threshold),
+ BUF_READ_AHEAD_AREA);
+
fail_count = 0;
rw_lock_s_lock(&page_hash_latch);
@@ -555,26 +378,34 @@ buf_read_ahead_linear(
/* Not accessed */
fail_count++;
- } else if (pred_bpage
- && (ut_ulint_cmp(
- buf_page_get_LRU_position(bpage),
- buf_page_get_LRU_position(pred_bpage))
- != asc_or_desc)) {
+ } else if (pred_bpage) {
+ /* Note that buf_page_is_accessed() returns
+ the time of the first access. If some blocks
+ of the extent existed in the buffer pool at
+ the time of a linear access pattern, the first
+ access times may be nonmonotonic, even though
+ the latest access times were linear. The
+ threshold (srv_read_ahead_factor) should help
+ a little against this. */
+ int res = ut_ulint_cmp(
+ buf_page_is_accessed(bpage),
+ buf_page_is_accessed(pred_bpage));
/* Accesses not in the right order */
-
- fail_count++;
- pred_bpage = bpage;
+ if (res != 0 && res != asc_or_desc) {
+ fail_count++;
+ }
}
- }
-
- if (fail_count > buf_read_ahead_linear_area
- * LINEAR_AREA_THRESHOLD_COEF) {
- /* Too many failures: return */
- //buf_pool_mutex_exit();
- rw_lock_s_unlock(&page_hash_latch);
+ if (fail_count > threshold) {
+ /* Too many failures: return */
+ //buf_pool_mutex_exit();
+ rw_lock_s_unlock(&page_hash_latch);
+ return(0);
+ }
- return(0);
+ if (bpage && buf_page_is_accessed(bpage)) {
+ pred_bpage = bpage;
+ }
}
/* If we got this far, we know that enough pages in the area have
@@ -669,7 +500,7 @@ buf_read_ahead_linear(
count += buf_read_page_low(
&err, FALSE,
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
- space, zip_size, FALSE, tablespace_version, i);
+ space, zip_size, FALSE, tablespace_version, i, trx);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -704,11 +535,11 @@ buf_read_ahead_linear(
LRU policy decision. */
buf_LRU_stat_inc_io();
- ++srv_read_ahead_seq;
+ buf_pool->stat.n_ra_pages_read += count;
return(count);
}
-/************************************************************************
+/********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like
a read-ahead function. */
@@ -716,24 +547,24 @@ UNIV_INTERN
void
buf_read_ibuf_merge_pages(
/*======================*/
- ibool sync, /* in: TRUE if the caller
+ ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
- const ulint* space_ids, /* in: array of space ids */
- const ib_int64_t* space_versions,/* in: the spaces must have
+ const ulint* space_ids, /*!< in: array of space ids */
+ const ib_int64_t* space_versions,/*!< in: the spaces must have
this version number
(timestamp), otherwise we
discard the read; we use this
to cancel reads if DISCARD +
IMPORT may have changed the
tablespace size */
- const ulint* page_nos, /* in: array of page numbers
+ const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
- ulint n_stored) /* in: number of elements
+ ulint n_stored) /*!< in: number of elements
in the arrays */
{
ulint i;
@@ -759,7 +590,7 @@ buf_read_ibuf_merge_pages(
buf_read_page_low(&err, sync && (i + 1 == n_stored),
BUF_READ_ANY_PAGE, space_ids[i],
zip_size, TRUE, space_versions[i],
- page_nos[i]);
+ page_nos[i], NULL);
if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
tablespace_deleted:
@@ -786,25 +617,25 @@ tablespace_deleted:
#endif /* UNIV_DEBUG */
}
-/************************************************************************
+/********************************************************************//**
Issues read requests for pages which recovery wants to read in. */
UNIV_INTERN
void
buf_read_recv_pages(
/*================*/
- ibool sync, /* in: TRUE if the caller
+ ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in
bytes, or 0 */
- const ulint* page_nos, /* in: array of page numbers
+ const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
- ulint n_stored) /* in: number of page numbers
+ ulint n_stored) /*!< in: number of page numbers
in the array */
{
ib_int64_t tablespace_version;
@@ -813,6 +644,14 @@ buf_read_recv_pages(
ulint i;
zip_size = fil_space_get_zip_size(space);
+
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+ /* It is a single table tablespace and the .ibd file is
+ missing: do nothing */
+
+ return;
+ }
+
tablespace_version = fil_space_get_version(space);
for (i = 0; i < n_stored; i++) {
@@ -848,12 +687,12 @@ buf_read_recv_pages(
if ((i + 1 == n_stored) && sync) {
buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
zip_size, TRUE, tablespace_version,
- page_nos[i]);
+ page_nos[i], NULL);
} else {
buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
| OS_AIO_SIMULATED_WAKE_LATER,
space, zip_size, TRUE,
- tablespace_version, page_nos[i]);
+ tablespace_version, page_nos[i], NULL);
}
}
diff --git a/storage/xtradb/data/data0data.c b/storage/xtradb/data/data0data.c
index 1cb3803b187..e3c1f1b4f23 100644
--- a/storage/xtradb/data/data0data.c
+++ b/storage/xtradb/data/data0data.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file data/data0data.c
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@@ -28,6 +29,7 @@ Created 5/30/1994 Heikki Tuuri
#include "data0data.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#include "rem0rec.h"
#include "rem0cmp.h"
#include "page0page.h"
@@ -36,28 +38,31 @@ Created 5/30/1994 Heikki Tuuri
#include "btr0cur.h"
#include <ctype.h>
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/* data pointers of tuple fields are initialized to point here
-for error checking */
+/** Dummy variable to catch access to uninitialized fields. In the
+debug version, dtuple_create() will make all fields of dtuple_t point
+to data_error. */
UNIV_INTERN byte data_error;
# ifndef UNIV_DEBUG_VALGRIND
-/* this is used to fool the compiler in dtuple_validate */
+/** this is used to fool the compiler in dtuple_validate */
UNIV_INTERN ulint data_dummy;
# endif /* !UNIV_DEBUG_VALGRIND */
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Tests if dfield data length and content is equal to the given. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Tests if dfield data length and content is equal to the given.
+@return TRUE if equal */
UNIV_INTERN
ibool
dfield_data_is_binary_equal(
/*========================*/
- /* out: TRUE if equal */
- const dfield_t* field, /* in: field */
- ulint len, /* in: data length or UNIV_SQL_NULL */
- const byte* data) /* in: data */
+ const dfield_t* field, /*!< in: field */
+ ulint len, /*!< in: data length or UNIV_SQL_NULL */
+ const byte* data) /*!< in: data */
{
if (len != dfield_get_len(field)) {
@@ -77,16 +82,16 @@ dfield_data_is_binary_equal(
return(TRUE);
}
-/****************************************************************
-Compare two data tuples, respecting the collation of character fields. */
+/************************************************************//**
+Compare two data tuples, respecting the collation of character fields.
+@return 1, 0 , -1 if tuple1 is greater, equal, less, respectively,
+than tuple2 */
UNIV_INTERN
int
dtuple_coll_cmp(
/*============*/
- /* out: 1, 0 , -1 if tuple1 is greater, equal,
- less, respectively, than tuple2 */
- const dtuple_t* tuple1, /* in: tuple 1 */
- const dtuple_t* tuple2) /* in: tuple 2 */
+ const dtuple_t* tuple1, /*!< in: tuple 1 */
+ const dtuple_t* tuple2) /*!< in: tuple 2 */
{
ulint n_fields;
ulint i;
@@ -119,15 +124,15 @@ dtuple_coll_cmp(
return(0);
}
-/*************************************************************************
+/*********************************************************************//**
Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */
UNIV_INTERN
void
dtuple_set_n_fields(
/*================*/
- dtuple_t* tuple, /* in: tuple */
- ulint n_fields) /* in: number of fields */
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint n_fields) /*!< in: number of fields */
{
ut_ad(tuple);
@@ -135,14 +140,14 @@ dtuple_set_n_fields(
tuple->n_fields_cmp = n_fields;
}
-/**************************************************************
-Checks that a data field is typed. */
+/**********************************************************//**
+Checks that a data field is typed.
+@return TRUE if ok */
static
ibool
dfield_check_typed_no_assert(
/*=========================*/
- /* out: TRUE if ok */
- const dfield_t* field) /* in: data field */
+ const dfield_t* field) /*!< in: data field */
{
if (dfield_get_type(field)->mtype > DATA_MYSQL
|| dfield_get_type(field)->mtype < DATA_VARCHAR) {
@@ -157,14 +162,14 @@ dfield_check_typed_no_assert(
return(TRUE);
}
-/**************************************************************
-Checks that a data tuple is typed. */
+/**********************************************************//**
+Checks that a data tuple is typed.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed_no_assert(
/*=========================*/
- /* out: TRUE if ok */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint i;
@@ -192,15 +197,17 @@ dump:
return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************
-Checks that a data field is typed. Asserts an error if not. */
+#ifdef UNIV_DEBUG
+/**********************************************************//**
+Checks that a data field is typed. Asserts an error if not.
+@return TRUE if ok */
UNIV_INTERN
ibool
dfield_check_typed(
/*===============*/
- /* out: TRUE if ok */
- const dfield_t* field) /* in: data field */
+ const dfield_t* field) /*!< in: data field */
{
if (dfield_get_type(field)->mtype > DATA_MYSQL
|| dfield_get_type(field)->mtype < DATA_VARCHAR) {
@@ -216,14 +223,14 @@ dfield_check_typed(
return(TRUE);
}
-/**************************************************************
-Checks that a data tuple is typed. Asserts an error if not. */
+/**********************************************************//**
+Checks that a data tuple is typed. Asserts an error if not.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed(
/*===============*/
- /* out: TRUE if ok */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint i;
@@ -238,16 +245,15 @@ dtuple_check_typed(
return(TRUE);
}
-#ifdef UNIV_DEBUG
-/**************************************************************
+/**********************************************************//**
Validates the consistency of a tuple which must be complete, i.e,
-all fields must have been set. */
+all fields must have been set.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_validate(
/*============*/
- /* out: TRUE if ok */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint n_fields;
@@ -291,13 +297,14 @@ dtuple_validate(
}
#endif /* UNIV_DEBUG */
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Pretty prints a dfield value according to its data type. */
UNIV_INTERN
void
dfield_print(
/*=========*/
- const dfield_t* dfield) /* in: dfield */
+ const dfield_t* dfield) /*!< in: dfield */
{
const byte* data;
ulint len;
@@ -333,14 +340,14 @@ dfield_print(
}
}
-/*****************************************************************
+/*************************************************************//**
Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */
UNIV_INTERN
void
dfield_print_also_hex(
/*==================*/
- const dfield_t* dfield) /* in: dfield */
+ const dfield_t* dfield) /*!< in: dfield */
{
const byte* data;
ulint len;
@@ -505,14 +512,14 @@ print_hex:
}
}
-/*****************************************************************
+/*************************************************************//**
Print a dfield value using ut_print_buf. */
static
void
dfield_print_raw(
/*=============*/
- FILE* f, /* in: output stream */
- const dfield_t* dfield) /* in: dfield */
+ FILE* f, /*!< in: output stream */
+ const dfield_t* dfield) /*!< in: dfield */
{
ulint len = dfield_get_len(dfield);
if (!dfield_is_null(dfield)) {
@@ -528,14 +535,14 @@ dfield_print_raw(
}
}
-/**************************************************************
+/**********************************************************//**
The following function prints the contents of a tuple. */
UNIV_INTERN
void
dtuple_print(
/*=========*/
- FILE* f, /* in: output stream */
- const dtuple_t* tuple) /* in: tuple */
+ FILE* f, /*!< in: output stream */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ulint n_fields;
ulint i;
@@ -556,23 +563,21 @@ dtuple_print(
ut_ad(dtuple_validate(tuple));
}
-/******************************************************************
+/**************************************************************//**
Moves parts of long fields in entry to the big record vector so that
the size of tuple drops below the maximum record size allowed in the
database. Moves data only from those fields which are not necessary
-to determine uniquely the insertion place of the tuple in the index. */
+to determine uniquely the insertion place of the tuple in the index.
+@return own: created big record vector, NULL if we are not able to
+shorten the entry enough, i.e., if there are too many fixed-length or
+short fields in entry or the index is clustered */
UNIV_INTERN
big_rec_t*
dtuple_convert_big_rec(
/*===================*/
- /* out, own: created big record vector,
- NULL if we are not able to shorten
- the entry enough, i.e., if there are
- too many fixed-length or short fields
- in entry or the index is clustered */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in/out: index entry */
- ulint* n_ext) /* in/out: number of
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in/out: index entry */
+ ulint* n_ext) /*!< in/out: number of
externally stored columns */
{
mem_heap_t* heap;
@@ -719,7 +724,7 @@ skip_field:
return(vector);
}
-/******************************************************************
+/**************************************************************//**
Puts back to entry the data stored in vector. Note that to ensure the
fields in entry can accommodate the data, vector must have been created
from entry with dtuple_convert_big_rec. */
@@ -727,9 +732,9 @@ UNIV_INTERN
void
dtuple_convert_back_big_rec(
/*========================*/
- dict_index_t* index __attribute__((unused)), /* in: index */
- dtuple_t* entry, /* in: entry whose data was put to vector */
- big_rec_t* vector) /* in, own: big rec vector; it is
+ dict_index_t* index __attribute__((unused)), /*!< in: index */
+ dtuple_t* entry, /*!< in: entry whose data was put to vector */
+ big_rec_t* vector) /*!< in, own: big rec vector; it is
freed in this function */
{
big_rec_field_t* b = vector->fields;
@@ -756,3 +761,4 @@ dtuple_convert_back_big_rec(
mem_heap_free(vector->heap);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/data/data0type.c b/storage/xtradb/data/data0type.c
index 5df933ef9fd..e834fd2ec55 100644
--- a/storage/xtradb/data/data0type.c
+++ b/storage/xtradb/data/data0type.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file data/data0type.c
Data types
Created 1/16/1996 Heikki Tuuri
@@ -28,26 +29,8 @@ Created 1/16/1996 Heikki Tuuri
#include "data0type.ic"
#endif
-/**********************************************************************
-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
-finds charset information and returns length of prefix_len characters in the
-index field in bytes.
-
-NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
-this function, you MUST change also the prototype here! */
-UNIV_INTERN
-ulint
-innobase_get_at_most_n_mbchars(
-/*===========================*/
- /* out: number of bytes occupied by the first
- n characters */
- ulint charset_id, /* in: character set id */
- ulint prefix_len, /* in: prefix length in bytes of the index
- (this has to be divided by mbmaxlen to get the
- number of CHARACTERS n in the prefix) */
- ulint data_len, /* in: length of the string in bytes */
- const char* str); /* in: character string */
+#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h"
/* At the database startup we store the default-charset collation number of
this MySQL installation to this global variable. If we have < 4.1.2 format
@@ -56,29 +39,27 @@ charset-collation code for them. */
UNIV_INTERN ulint data_mysql_default_charset_coll;
-/*************************************************************************
+/*********************************************************************//**
Determine how many bytes the first n characters of the given string occupy.
If the string is shorter than n characters, returns the number of bytes
-the characters in the string occupy. */
+the characters in the string occupy.
+@return length of the prefix, in bytes */
UNIV_INTERN
ulint
dtype_get_at_most_n_mbchars(
/*========================*/
- /* out: length of the prefix,
- in bytes */
- ulint prtype, /* in: precise type */
- ulint mbminlen, /* in: minimum length of a
+ ulint prtype, /*!< in: precise type */
+ ulint mbminlen, /*!< in: minimum length of a
multi-byte character */
- ulint mbmaxlen, /* in: maximum length of a
+ ulint mbmaxlen, /*!< in: maximum length of a
multi-byte character */
- ulint prefix_len, /* in: length of the requested
+ ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
- ulint data_len, /* in: length of str (in bytes) */
- const char* str) /* in: the string whose prefix
+ ulint data_len, /*!< in: length of str (in bytes) */
+ const char* str) /*!< in: the string whose prefix
length is being determined */
{
-#ifndef UNIV_HOTBACKUP
ut_a(data_len != UNIV_SQL_NULL);
ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
@@ -96,23 +77,18 @@ dtype_get_at_most_n_mbchars(
}
return(data_len);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
+#endif /* UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Checks if a data main type is a string type. Also a BLOB is considered a
-string type. */
+string type.
+@return TRUE if string type */
UNIV_INTERN
ibool
dtype_is_string_type(
/*=================*/
- /* out: TRUE if string type */
- ulint mtype) /* in: InnoDB main data type code: DATA_CHAR, ... */
+ ulint mtype) /*!< in: InnoDB main data type code: DATA_CHAR, ... */
{
if (mtype <= DATA_BLOB
|| mtype == DATA_MYSQL
@@ -124,17 +100,17 @@ dtype_is_string_type(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
-those DATA_BLOB columns this function currently returns FALSE. */
+those DATA_BLOB columns this function currently returns FALSE.
+@return TRUE if binary string type */
UNIV_INTERN
ibool
dtype_is_binary_string_type(
/*========================*/
- /* out: TRUE if binary string type */
- ulint mtype, /* in: main data type */
- ulint prtype) /* in: precise type */
+ ulint mtype, /*!< in: main data type */
+ ulint prtype) /*!< in: precise type */
{
if ((mtype == DATA_FIXBINARY)
|| (mtype == DATA_BINARY)
@@ -146,18 +122,18 @@ dtype_is_binary_string_type(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
-For those DATA_BLOB columns this function currently returns TRUE. */
+For those DATA_BLOB columns this function currently returns TRUE.
+@return TRUE if non-binary string type */
UNIV_INTERN
ibool
dtype_is_non_binary_string_type(
/*============================*/
- /* out: TRUE if non-binary string type */
- ulint mtype, /* in: main data type */
- ulint prtype) /* in: precise type */
+ ulint mtype, /*!< in: main data type */
+ ulint prtype) /*!< in: precise type */
{
if (dtype_is_string_type(mtype) == TRUE
&& dtype_is_binary_string_type(mtype, prtype) == FALSE) {
@@ -168,16 +144,17 @@ dtype_is_non_binary_string_type(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Forms a precise type from the < 4.1.2 format precise type plus the
-charset-collation code. */
+charset-collation code.
+@return precise type, including the charset-collation code */
UNIV_INTERN
ulint
dtype_form_prtype(
/*==============*/
- ulint old_prtype, /* in: the MySQL type code and the flags
+ ulint old_prtype, /*!< in: the MySQL type code and the flags
DATA_BINARY_TYPE etc. */
- ulint charset_coll) /* in: MySQL charset-collation code */
+ ulint charset_coll) /*!< in: MySQL charset-collation code */
{
ut_a(old_prtype < 256 * 256);
ut_a(charset_coll < 256);
@@ -185,14 +162,14 @@ dtype_form_prtype(
return(old_prtype + (charset_coll << 16));
}
-/*************************************************************************
-Validates a data type structure. */
+/*********************************************************************//**
+Validates a data type structure.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtype_validate(
/*===========*/
- /* out: TRUE if ok */
- const dtype_t* type) /* in: type struct to validate */
+ const dtype_t* type) /*!< in: type struct to validate */
{
ut_a(type);
ut_a(type->mtype >= DATA_VARCHAR);
@@ -202,18 +179,21 @@ dtype_validate(
ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS);
}
+#ifndef UNIV_HOTBACKUP
ut_a(type->mbminlen <= type->mbmaxlen);
+#endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Prints a data type structure. */
UNIV_INTERN
void
dtype_print(
/*========*/
- const dtype_t* type) /* in: type */
+ const dtype_t* type) /*!< in: type */
{
ulint mtype;
ulint prtype;
@@ -257,6 +237,22 @@ dtype_print(
fputs("DATA_SYS", stderr);
break;
+ case DATA_FLOAT:
+ fputs("DATA_FLOAT", stderr);
+ break;
+
+ case DATA_DOUBLE:
+ fputs("DATA_DOUBLE", stderr);
+ break;
+
+ case DATA_DECIMAL:
+ fputs("DATA_DECIMAL", stderr);
+ break;
+
+ case DATA_VARMYSQL:
+ fputs("DATA_VARMYSQL", stderr);
+ break;
+
default:
fprintf(stderr, "type %lu", (ulong) mtype);
break;
@@ -298,3 +294,4 @@ dtype_print(
fprintf(stderr, " len %lu", (ulong) len);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/dict/dict0boot.c b/storage/xtradb/dict/dict0boot.c
index cd90016dd78..0eb73e6c2f9 100644
--- a/storage/xtradb/dict/dict0boot.c
+++ b/storage/xtradb/dict/dict0boot.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file dict/dict0boot.c
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
@@ -39,15 +40,14 @@ Created 4/18/1996 Heikki Tuuri
#include "log0recv.h"
#include "os0file.h"
-/**************************************************************************
-Gets a pointer to the dictionary header and x-latches its page. */
+/**********************************************************************//**
+Gets a pointer to the dictionary header and x-latches its page.
+@return pointer to the dictionary header, page x-latched */
UNIV_INTERN
dict_hdr_t*
dict_hdr_get(
/*=========*/
- /* out: pointer to the dictionary header,
- page x-latched */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
dict_hdr_t* header;
@@ -61,14 +61,14 @@ dict_hdr_get(
return(header);
}
-/**************************************************************************
-Returns a new table, index, or tree id. */
+/**********************************************************************//**
+Returns a new table, index, or tree id.
+@return the new id */
UNIV_INTERN
dulint
dict_hdr_get_new_id(
/*================*/
- /* out: the new id */
- ulint type) /* in: DICT_HDR_ROW_ID, ... */
+ ulint type) /*!< in: DICT_HDR_ROW_ID, ... */
{
dict_hdr_t* dict_hdr;
dulint id;
@@ -90,7 +90,7 @@ dict_hdr_get_new_id(
return(id);
}
-/**************************************************************************
+/**********************************************************************//**
Writes the current value of the row id counter to the dictionary header file
page. */
UNIV_INTERN
@@ -115,15 +115,15 @@ dict_hdr_flush_row_id(void)
mtr_commit(&mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Creates the file page for the dictionary header. This function is
-called only at the database creation. */
+called only at the database creation.
+@return TRUE if succeed */
static
ibool
dict_hdr_create(
/*============*/
- /* out: TRUE if succeed */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
dict_hdr_t* dict_header;
@@ -161,7 +161,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_TABLES_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -172,7 +172,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE, 0,
DICT_TABLE_IDS_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -183,7 +183,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_COLUMNS_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -194,7 +194,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_INDEXES_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -205,7 +205,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_FIELDS_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -218,7 +218,7 @@ dict_hdr_create(
return(TRUE);
}
-/*********************************************************************
+/*****************************************************************//**
Initializes the data dictionary memory structures when the database is
started. This function is also called when the data dictionary is created. */
UNIV_INTERN
@@ -434,7 +434,7 @@ dict_boot(void)
mutex_exit(&(dict_sys->mutex));
}
-/*********************************************************************
+/*****************************************************************//**
Inserts the basic system table data into themselves in the database
creation. */
static
@@ -445,7 +445,7 @@ dict_insert_initial_data(void)
/* Does nothing yet */
}
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the data dictionary at the database creation. */
UNIV_INTERN
void
diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c
index 01d092005c3..f548d89bc68 100644
--- a/storage/xtradb/dict/dict0crea.c
+++ b/storage/xtradb/dict/dict0crea.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file dict/dict0crea.c
Database object creation
Created 1/8/1996 Heikki Tuuri
@@ -42,16 +43,16 @@ Created 1/8/1996 Heikki Tuuri
#include "usr0sess.h"
#include "ut0vec.h"
-/*********************************************************************
+/*****************************************************************//**
Based on a table object, this function builds the entry to be inserted
-in the SYS_TABLES system table. */
+in the SYS_TABLES system table.
+@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_tables_tuple(
/*=========================*/
- /* out: the tuple which should be inserted */
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_tables;
@@ -134,17 +135,17 @@ dict_create_sys_tables_tuple(
return(entry);
}
-/*********************************************************************
+/*****************************************************************//**
Based on a table object, this function builds the entry to be inserted
-in the SYS_COLUMNS system table. */
+in the SYS_COLUMNS system table.
+@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_columns_tuple(
/*==========================*/
- /* out: the tuple which should be inserted */
- dict_table_t* table, /* in: table */
- ulint i, /* in: column number */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_table_t* table, /*!< in: table */
+ ulint i, /*!< in: column number */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_columns;
@@ -216,15 +217,15 @@ dict_create_sys_columns_tuple(
return(entry);
}
-/*******************************************************************
-Builds a table definition to insert. */
+/***************************************************************//**
+Builds a table definition to insert.
+@return DB_SUCCESS or error code */
static
ulint
dict_build_table_def_step(
/*======================*/
- /* out: DB_SUCCESS or error code */
- que_thr_t* thr, /* in: query thread */
- tab_node_t* node) /* in: table create node */
+ que_thr_t* thr, /*!< in: query thread */
+ tab_node_t* node) /*!< in: table create node */
{
dict_table_t* table;
dtuple_t* row;
@@ -295,14 +296,14 @@ dict_build_table_def_step(
return(DB_SUCCESS);
}
-/*******************************************************************
-Builds a column definition to insert. */
+/***************************************************************//**
+Builds a column definition to insert.
+@return DB_SUCCESS */
static
ulint
dict_build_col_def_step(
/*====================*/
- /* out: DB_SUCCESS */
- tab_node_t* node) /* in: table create node */
+ tab_node_t* node) /*!< in: table create node */
{
dtuple_t* row;
@@ -313,16 +314,16 @@ dict_build_col_def_step(
return(DB_SUCCESS);
}
-/*********************************************************************
+/*****************************************************************//**
Based on an index object, this function builds the entry to be inserted
-in the SYS_INDEXES system table. */
+in the SYS_INDEXES system table.
+@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_indexes_tuple(
/*==========================*/
- /* out: the tuple which should be inserted */
- dict_index_t* index, /* in: index */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_index_t* index, /*!< in: index */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_indexes;
@@ -403,17 +404,17 @@ dict_create_sys_indexes_tuple(
return(entry);
}
-/*********************************************************************
+/*****************************************************************//**
Based on an index object, this function builds the entry to be inserted
-in the SYS_FIELDS system table. */
+in the SYS_FIELDS system table.
+@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_fields_tuple(
/*=========================*/
- /* out: the tuple which should be inserted */
- dict_index_t* index, /* in: index */
- ulint i, /* in: field number */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_index_t* index, /*!< in: index */
+ ulint i, /*!< in: field number */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_fields;
@@ -479,17 +480,17 @@ dict_create_sys_fields_tuple(
return(entry);
}
-/*********************************************************************
+/*****************************************************************//**
Creates the tuple with which the index entry is searched for writing the index
-tree root page number, if such a tree is created. */
+tree root page number, if such a tree is created.
+@return the tuple for search */
static
dtuple_t*
dict_create_search_tuple(
/*=====================*/
- /* out: the tuple for search */
- const dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES
+ const dtuple_t* tuple, /*!< in: the tuple inserted in the SYS_INDEXES
table */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dtuple_t* search_tuple;
@@ -515,15 +516,15 @@ dict_create_search_tuple(
return(search_tuple);
}
-/*******************************************************************
-Builds an index definition row to insert. */
+/***************************************************************//**
+Builds an index definition row to insert.
+@return DB_SUCCESS or error code */
static
ulint
dict_build_index_def_step(
/*======================*/
- /* out: DB_SUCCESS or error code */
- que_thr_t* thr, /* in: query thread */
- ind_node_t* node) /* in: index create node */
+ que_thr_t* thr, /*!< in: query thread */
+ ind_node_t* node) /*!< in: index create node */
{
dict_table_t* table;
dict_index_t* index;
@@ -561,22 +562,20 @@ dict_build_index_def_step(
ins_node_set_new_row(node->ind_def, row);
-#ifdef ROW_MERGE_IS_INDEX_USABLE
/* Note that the index was created by this transaction. */
- index->trx_id = trx->id;
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
+ index->trx_id = (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
return(DB_SUCCESS);
}
-/*******************************************************************
-Builds a field definition row to insert. */
+/***************************************************************//**
+Builds a field definition row to insert.
+@return DB_SUCCESS */
static
ulint
dict_build_field_def_step(
/*======================*/
- /* out: DB_SUCCESS */
- ind_node_t* node) /* in: index create node */
+ ind_node_t* node) /*!< in: index create node */
{
dict_index_t* index;
dtuple_t* row;
@@ -590,14 +589,14 @@ dict_build_field_def_step(
return(DB_SUCCESS);
}
-/*******************************************************************
-Creates an index tree for the index if it is not a member of a cluster. */
+/***************************************************************//**
+Creates an index tree for the index if it is not a member of a cluster.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
dict_create_index_tree_step(
/*========================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- ind_node_t* node) /* in: index create node */
+ ind_node_t* node) /*!< in: index create node */
{
dict_index_t* index;
dict_table_t* sys_indexes;
@@ -647,15 +646,15 @@ dict_create_index_tree_step(
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Drops the index tree associated with a row in SYS_INDEXES table. */
UNIV_INTERN
void
dict_drop_index_tree(
/*=================*/
- rec_t* rec, /* in/out: record in the clustered index
+ rec_t* rec, /*!< in/out: record in the clustered index
of SYS_INDEXES table */
- mtr_t* mtr) /* in: mtr having the latch on the record page */
+ mtr_t* mtr) /*!< in: mtr having the latch on the record page */
{
ulint root_page_no;
ulint space;
@@ -710,23 +709,22 @@ dict_drop_index_tree(
FIL_NULL, mtr);
}
-/***********************************************************************
-Truncates the index tree associated with a row in SYS_INDEXES table. */
+/*******************************************************************//**
+Truncates the index tree associated with a row in SYS_INDEXES table.
+@return new root page number, or FIL_NULL on failure */
UNIV_INTERN
ulint
dict_truncate_index_tree(
/*=====================*/
- /* out: new root page number, or
- FIL_NULL on failure */
- dict_table_t* table, /* in: the table the index belongs to */
- ulint space, /* in: 0=truncate,
+ dict_table_t* table, /*!< in: the table the index belongs to */
+ ulint space, /*!< in: 0=truncate,
nonzero=create the index tree in the
given tablespace */
- btr_pcur_t* pcur, /* in/out: persistent cursor pointing to
+ btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing to
record in the clustered index of
SYS_INDEXES table. The cursor may be
repositioned in this call. */
- mtr_t* mtr) /* in: mtr having the latch
+ mtr_t* mtr) /*!< in: mtr having the latch
on the record page. The mtr may be
committed and restarted in this call. */
{
@@ -846,16 +844,16 @@ create:
return(FIL_NULL);
}
-/*************************************************************************
-Creates a table create graph. */
+/*********************************************************************//**
+Creates a table create graph.
+@return own: table create node */
UNIV_INTERN
tab_node_t*
tab_create_graph_create(
/*====================*/
- /* out, own: table create node */
- dict_table_t* table, /* in: table to create, built as a memory data
+ dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
- mem_heap_t* heap) /* in: heap where created */
+ mem_heap_t* heap) /*!< in: heap where created */
{
tab_node_t* node;
@@ -882,16 +880,16 @@ tab_create_graph_create(
return(node);
}
-/*************************************************************************
-Creates an index create graph. */
+/*********************************************************************//**
+Creates an index create graph.
+@return own: index create node */
UNIV_INTERN
ind_node_t*
ind_create_graph_create(
/*====================*/
- /* out, own: index create node */
- dict_index_t* index, /* in: index to create, built as a memory data
+ dict_index_t* index, /*!< in: index to create, built as a memory data
structure */
- mem_heap_t* heap) /* in: heap where created */
+ mem_heap_t* heap) /*!< in: heap where created */
{
ind_node_t* node;
@@ -919,14 +917,14 @@ ind_create_graph_create(
return(node);
}
-/***************************************************************
-Creates a table. This is a high-level function used in SQL execution graphs. */
+/***********************************************************//**
+Creates a table. This is a high-level function used in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_table_step(
/*===================*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
tab_node_t* node;
ulint err = DB_ERROR;
@@ -1025,15 +1023,15 @@ function_exit:
return(thr);
}
-/***************************************************************
+/***********************************************************//**
Creates an index. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_index_step(
/*===================*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ind_node_t* node;
ulint err = DB_ERROR;
@@ -1156,16 +1154,15 @@ function_exit:
return(thr);
}
-#ifndef UNIV_HOTBACKUP
-/********************************************************************
+/****************************************************************//**
Creates the foreign key constraints system tables inside InnoDB
at database creation or database start if they are not found or are
-not of the right form. */
+not of the right form.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_foreign_constraint_tables(void)
/*================================================*/
- /* out: DB_SUCCESS or error code */
{
dict_table_t* table1;
dict_table_t* table2;
@@ -1286,18 +1283,18 @@ dict_create_or_check_foreign_constraint_tables(void)
return(error);
}
-/********************************************************************
-Evaluate the given foreign key SQL statement. */
+/****************************************************************//**
+Evaluate the given foreign key SQL statement.
+@return error code or DB_SUCCESS */
static
ulint
dict_foreign_eval_sql(
/*==================*/
- /* out: error code or DB_SUCCESS */
- pars_info_t* info, /* in: info struct, or NULL */
- const char* sql, /* in: SQL string to evaluate */
- dict_table_t* table, /* in: table */
- dict_foreign_t* foreign,/* in: foreign */
- trx_t* trx) /* in: transaction */
+ pars_info_t* info, /*!< in: info struct, or NULL */
+ const char* sql, /*!< in: SQL string to evaluate */
+ dict_table_t* table, /*!< in: table */
+ dict_foreign_t* foreign,/*!< in: foreign */
+ trx_t* trx) /*!< in: transaction */
{
ulint error;
FILE* ef = dict_foreign_err_file;
@@ -1351,18 +1348,18 @@ dict_foreign_eval_sql(
return(DB_SUCCESS);
}
-/************************************************************************
+/********************************************************************//**
Add a single foreign key field definition to the data dictionary tables in
-the database. */
+the database.
+@return error code or DB_SUCCESS */
static
ulint
dict_create_add_foreign_field_to_dictionary(
/*========================================*/
- /* out: error code or DB_SUCCESS */
- ulint field_nr, /* in: foreign field number */
- dict_table_t* table, /* in: table */
- dict_foreign_t* foreign, /* in: foreign */
- trx_t* trx) /* in: transaction */
+ ulint field_nr, /*!< in: foreign field number */
+ dict_table_t* table, /*!< in: table */
+ dict_foreign_t* foreign, /*!< in: foreign */
+ trx_t* trx) /*!< in: transaction */
{
pars_info_t* info = pars_info_create();
@@ -1386,23 +1383,23 @@ dict_create_add_foreign_field_to_dictionary(
table, foreign, trx));
}
-/************************************************************************
+/********************************************************************//**
Add a single foreign key definition to the data dictionary tables in the
database. We also generate names to constraints that were not named by the
user. A generated constraint has a name of the format
-databasename/tablename_ibfk_<number>, where the numbers start from 1, and
+databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and
are given locally for this table, that is, the number is not global, as in
-the old format constraints < 4.0.18 it used to be. */
+the old format constraints < 4.0.18 it used to be.
+@return error code or DB_SUCCESS */
static
ulint
dict_create_add_foreign_to_dictionary(
/*==================================*/
- /* out: error code or DB_SUCCESS */
- ulint* id_nr, /* in/out: number to use in id generation;
+ ulint* id_nr, /*!< in/out: number to use in id generation;
incremented if used */
- dict_table_t* table, /* in: table */
- dict_foreign_t* foreign,/* in: foreign */
- trx_t* trx) /* in: transaction */
+ dict_table_t* table, /*!< in: table */
+ dict_foreign_t* foreign,/*!< in: foreign */
+ trx_t* trx) /*!< in: transaction */
{
ulint error;
ulint i;
@@ -1461,14 +1458,14 @@ dict_create_add_foreign_to_dictionary(
return(error);
}
-/************************************************************************
-Adds foreign key definitions to data dictionary tables in the database. */
+/********************************************************************//**
+Adds foreign key definitions to data dictionary tables in the database.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_add_foreigns_to_dictionary(
/*===================================*/
- /* out: error code or DB_SUCCESS */
- ulint start_id,/* in: if we are actually doing ALTER TABLE
+ ulint start_id,/*!< in: if we are actually doing ALTER TABLE
ADD CONSTRAINT, we want to generate constraint
numbers which are bigger than in the table so
far; we number the constraints from
@@ -1476,8 +1473,8 @@ dict_create_add_foreigns_to_dictionary(
we are creating a new table, or if the table
so far has no constraints for which the name
was generated here */
- dict_table_t* table, /* in: table */
- trx_t* trx) /* in: transaction */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx) /*!< in: transaction */
{
dict_foreign_t* foreign;
ulint number = start_id + 1;
@@ -1508,4 +1505,3 @@ dict_create_add_foreigns_to_dictionary(
return(DB_SUCCESS);
}
-#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 68fa5fccf64..3f5dd2930e3 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file dict/dict0dict.c
Data dictionary system
Created 1/8/1996 Heikki Tuuri
@@ -28,6 +29,12 @@ Created 1/8/1996 Heikki Tuuri
#include "dict0dict.ic"
#endif
+/** dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */
+UNIV_INTERN dict_index_t* dict_ind_redundant;
+/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
+UNIV_INTERN dict_index_t* dict_ind_compact;
+
+#ifndef UNIV_HOTBACKUP
#include "buf0buf.h"
#include "data0type.h"
#include "mach0data.h"
@@ -45,105 +52,102 @@ Created 1/8/1996 Heikki Tuuri
#include "que0que.h"
#include "rem0cmp.h"
#include "row0merge.h"
-#ifndef UNIV_HOTBACKUP
-# include "m_ctype.h" /* my_isspace() */
-# include "ha_prototypes.h" /* innobase_strcasecmp() */
-#endif /* !UNIV_HOTBACKUP */
+#include "m_ctype.h" /* my_isspace() */
+#include "ha_prototypes.h" /* innobase_strcasecmp() */
#include <ctype.h>
-/* the dictionary system */
+/** the dictionary system */
UNIV_INTERN dict_sys_t* dict_sys = NULL;
-/* table create, drop, etc. reserve this in X-mode; implicit or
+/** @brief the data dictionary rw-latch protecting dict_sys
+
+table create, drop, etc. reserve this in X-mode; implicit or
backround operations purge, rollback, foreign key checks reserve this
in S-mode; we cannot trust that MySQL protects implicit or background
operations a table drop since MySQL does not know of them; therefore
we need this; NOTE: a transaction which reserves this must keep book
-on the mode in trx->dict_operation_lock_mode */
+on the mode in trx_struct::dict_operation_lock_mode */
UNIV_INTERN rw_lock_t dict_operation_lock;
-#define DICT_HEAP_SIZE 100 /* initial memory heap size when
+#define DICT_HEAP_SIZE 100 /*!< initial memory heap size when
creating a table or index object */
-#define DICT_POOL_PER_TABLE_HASH 512 /* buffer pool max size per table
+#define DICT_POOL_PER_TABLE_HASH 512 /*!< buffer pool max size per table
hash table fixed size in bytes */
-#define DICT_POOL_PER_VARYING 4 /* buffer pool max size per data
+#define DICT_POOL_PER_VARYING 4 /*!< buffer pool max size per data
dictionary varying size in bytes */
-/* Identifies generated InnoDB foreign key names */
+/** Identifies generated InnoDB foreign key names */
static char dict_ibfk[] = "_ibfk_";
-/***********************************************************************
+/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
-index. */
+index.
+@return TRUE if the column names were found */
static
-void
+ibool
dict_index_find_cols(
/*=================*/
- dict_table_t* table, /* in: table */
- dict_index_t* index); /* in: index */
-/***********************************************************************
+ dict_table_t* table, /*!< in: table */
+ dict_index_t* index); /*!< in: index */
+/*******************************************************************//**
Builds the internal dictionary cache representation for a clustered
-index, containing also system fields not defined by the user. */
+index, containing also system fields not defined by the user.
+@return own: the internal representation of the clustered index */
static
dict_index_t*
dict_index_build_internal_clust(
/*============================*/
- /* out, own: the internal
- representation of the clustered
- index */
- const dict_table_t* table, /* in: table */
- dict_index_t* index); /* in: user representation of
+ const dict_table_t* table, /*!< in: table */
+ dict_index_t* index); /*!< in: user representation of
a clustered index */
-/***********************************************************************
+/*******************************************************************//**
Builds the internal dictionary cache representation for a non-clustered
-index, containing also system fields not defined by the user. */
+index, containing also system fields not defined by the user.
+@return own: the internal representation of the non-clustered index */
static
dict_index_t*
dict_index_build_internal_non_clust(
/*================================*/
- /* out, own: the internal
- representation of the non-clustered
- index */
- const dict_table_t* table, /* in: table */
- dict_index_t* index); /* in: user representation of
+ const dict_table_t* table, /*!< in: table */
+ dict_index_t* index); /*!< in: user representation of
a non-clustered index */
-/**************************************************************************
+/**********************************************************************//**
Removes a foreign constraint struct from the dictionary cache. */
static
void
dict_foreign_remove_from_cache(
/*===========================*/
- dict_foreign_t* foreign); /* in, own: foreign constraint */
-/**************************************************************************
+ dict_foreign_t* foreign); /*!< in, own: foreign constraint */
+/**********************************************************************//**
Prints a column data. */
static
void
dict_col_print_low(
/*===============*/
- const dict_table_t* table, /* in: table */
- const dict_col_t* col); /* in: column */
-/**************************************************************************
+ const dict_table_t* table, /*!< in: table */
+ const dict_col_t* col); /*!< in: column */
+/**********************************************************************//**
Prints an index data. */
static
void
dict_index_print_low(
/*=================*/
- dict_index_t* index); /* in: index */
-/**************************************************************************
+ dict_index_t* index); /*!< in: index */
+/**********************************************************************//**
Prints a field data. */
static
void
dict_field_print_low(
/*=================*/
- dict_field_t* field); /* in: field */
-/*************************************************************************
+ dict_field_t* field); /*!< in: field */
+/*********************************************************************//**
Frees a foreign key struct. */
static
void
dict_foreign_free(
/*==============*/
- dict_foreign_t* foreign); /* in, own: foreign key struct */
+ dict_foreign_t* foreign); /*!< in, own: foreign key struct */
/* Stream for storing detailed information about the latest foreign key
and unique key errors */
@@ -151,29 +155,27 @@ UNIV_INTERN FILE* dict_foreign_err_file = NULL;
/* mutex protecting the foreign and unique error buffers */
UNIV_INTERN mutex_t dict_foreign_err_mutex;
-#ifndef UNIV_HOTBACKUP
-/**********************************************************************
+/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
void
dict_casedn_str(
/*============*/
- char* a) /* in/out: string to put in lower case */
+ char* a) /*!< in/out: string to put in lower case */
{
innobase_casedn_str(a);
}
-#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Checks if the database name in two table names is the same. */
+/********************************************************************//**
+Checks if the database name in two table names is the same.
+@return TRUE if same db name */
UNIV_INTERN
ibool
dict_tables_have_same_db(
/*=====================*/
- /* out: TRUE if same db name */
- const char* name1, /* in: table name in the form
+ const char* name1, /*!< in: table name in the form
dbname '/' tablename */
- const char* name2) /* in: table name in the form
+ const char* name2) /*!< in: table name in the form
dbname '/' tablename */
{
for (; *name1 == *name2; name1++, name2++) {
@@ -185,14 +187,14 @@ dict_tables_have_same_db(
return(FALSE);
}
-/************************************************************************
-Return the end of table name where we have removed dbname and '/'. */
+/********************************************************************//**
+Return the end of table name where we have removed dbname and '/'.
+@return table name */
UNIV_INTERN
const char*
dict_remove_db_name(
/*================*/
- /* out: table name */
- const char* name) /* in: table name in the form
+ const char* name) /*!< in: table name in the form
dbname '/' tablename */
{
const char* s = strchr(name, '/');
@@ -201,14 +203,14 @@ dict_remove_db_name(
return(s + 1);
}
-/************************************************************************
-Get the database name length in a table name. */
+/********************************************************************//**
+Get the database name length in a table name.
+@return database name length */
UNIV_INTERN
ulint
dict_get_db_name_len(
/*=================*/
- /* out: database name length */
- const char* name) /* in: table name in the form
+ const char* name) /*!< in: table name in the form
dbname '/' tablename */
{
const char* s;
@@ -217,7 +219,7 @@ dict_get_db_name_len(
return(s - name);
}
-/************************************************************************
+/********************************************************************//**
Reserves the dictionary system mutex for MySQL. */
UNIV_INTERN
void
@@ -227,7 +229,7 @@ dict_mutex_enter_for_mysql(void)
mutex_enter(&(dict_sys->mutex));
}
-/************************************************************************
+/********************************************************************//**
Releases the dictionary system mutex for MySQL. */
UNIV_INTERN
void
@@ -237,14 +239,14 @@ dict_mutex_exit_for_mysql(void)
mutex_exit(&(dict_sys->mutex));
}
-/************************************************************************
+/********************************************************************//**
Decrements the count of open MySQL handles to a table. */
UNIV_INTERN
void
dict_table_decrement_handle_count(
/*==============================*/
- dict_table_t* table, /* in/out: table */
- ibool dict_locked) /* in: TRUE=data dictionary locked */
+ dict_table_t* table, /*!< in/out: table */
+ ibool dict_locked) /*!< in: TRUE=data dictionary locked */
{
if (!dict_locked) {
mutex_enter(&dict_sys->mutex);
@@ -259,19 +261,18 @@ dict_table_decrement_handle_count(
mutex_exit(&dict_sys->mutex);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Returns a column's name. */
+/**********************************************************************//**
+Returns a column's name.
+@return column name. NOTE: not guaranteed to stay valid if table is
+modified in any way (columns added, etc.). */
UNIV_INTERN
const char*
dict_table_get_col_name(
/*====================*/
- /* out: column name. NOTE: not
- guaranteed to stay valid if table is
- modified in any way (columns added,
- etc.). */
- const dict_table_t* table, /* in: table */
- ulint col_nr) /* in: column number */
+ const dict_table_t* table, /*!< in: table */
+ ulint col_nr) /*!< in: column number */
{
ulint i;
const char* s;
@@ -290,48 +291,48 @@ dict_table_get_col_name(
return(s);
}
-
-/************************************************************************
-Acquire the autoinc lock.*/
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Acquire the autoinc lock. */
UNIV_INTERN
void
dict_table_autoinc_lock(
/*====================*/
- dict_table_t* table) /* in/out: table */
+ dict_table_t* table) /*!< in/out: table */
{
mutex_enter(&table->autoinc_mutex);
}
-/************************************************************************
+/********************************************************************//**
Unconditionally set the autoinc counter. */
UNIV_INTERN
void
dict_table_autoinc_initialize(
/*==========================*/
- dict_table_t* table, /* in/out: table */
- ib_uint64_t value) /* in: next value to assign to a row */
+ dict_table_t* table, /*!< in/out: table */
+ ib_uint64_t value) /*!< in: next value to assign to a row */
{
ut_ad(mutex_own(&table->autoinc_mutex));
table->autoinc = value;
}
-/************************************************************************
+/********************************************************************//**
Reads the next autoinc value (== autoinc counter value), 0 if not yet
-initialized. */
+initialized.
+@return value for a new row, or 0 */
UNIV_INTERN
ib_uint64_t
dict_table_autoinc_read(
/*====================*/
- /* out: value for a new row, or 0 */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(mutex_own(&table->autoinc_mutex));
return(table->autoinc);
}
-/************************************************************************
+/********************************************************************//**
Updates the autoinc counter if the value supplied is greater than the
current value. */
UNIV_INTERN
@@ -339,8 +340,8 @@ void
dict_table_autoinc_update_if_greater(
/*=================================*/
- dict_table_t* table, /* in/out: table */
- ib_uint64_t value) /* in: value which was assigned to a row */
+ dict_table_t* table, /*!< in/out: table */
+ ib_uint64_t value) /*!< in: value which was assigned to a row */
{
ut_ad(mutex_own(&table->autoinc_mutex));
@@ -350,28 +351,27 @@ dict_table_autoinc_update_if_greater(
}
}
-/************************************************************************
-Release the autoinc lock.*/
+/********************************************************************//**
+Release the autoinc lock. */
UNIV_INTERN
void
dict_table_autoinc_unlock(
/*======================*/
- dict_table_t* table) /* in/out: table */
+ dict_table_t* table) /*!< in/out: table */
{
mutex_exit(&table->autoinc_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Looks for an index with the given table and index id.
-NOTE that we do not reserve the dictionary mutex. */
+NOTE that we do not reserve the dictionary mutex.
+@return index or NULL if not found from cache */
UNIV_INTERN
dict_index_t*
dict_index_get_on_id_low(
/*=====================*/
- /* out: index or NULL if not found
- from cache */
- dict_table_t* table, /* in: table */
- dulint id) /* in: index id */
+ dict_table_t* table, /*!< in: table */
+ dulint id) /*!< in: index id */
{
dict_index_t* index;
@@ -389,19 +389,18 @@ dict_index_get_on_id_low(
return(NULL);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Looks for column n in an index. */
+/********************************************************************//**
+Looks for column n in an index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
dict_index_get_nth_col_pos(
/*=======================*/
- /* out: position in internal
- representation of the index;
- if not contained, returns
- ULINT_UNDEFINED */
- const dict_index_t* index, /* in: index */
- ulint n) /* in: column number */
+ const dict_index_t* index, /*!< in: index */
+ ulint n) /*!< in: column number */
{
const dict_field_t* field;
const dict_col_t* col;
@@ -432,16 +431,16 @@ dict_index_get_nth_col_pos(
return(ULINT_UNDEFINED);
}
-/************************************************************************
-Returns TRUE if the index contains a column or a prefix of that column. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Returns TRUE if the index contains a column or a prefix of that column.
+@return TRUE if contains the column or its prefix */
UNIV_INTERN
ibool
dict_index_contains_col_or_prefix(
/*==============================*/
- /* out: TRUE if contains the column
- or its prefix */
- const dict_index_t* index, /* in: index */
- ulint n) /* in: column number */
+ const dict_index_t* index, /*!< in: index */
+ ulint n) /*!< in: column number */
{
const dict_field_t* field;
const dict_col_t* col;
@@ -472,22 +471,20 @@ dict_index_contains_col_or_prefix(
return(FALSE);
}
-/************************************************************************
+/********************************************************************//**
Looks for a matching field in an index. The column has to be the same. The
column in index must be complete, or must contain a prefix longer than the
column in index2. That is, we must be able to construct the prefix in index2
-from the prefix in index. */
+from the prefix in index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
dict_index_get_nth_field_pos(
/*=========================*/
- /* out: position in internal
- representation of the index;
- if not contained, returns
- ULINT_UNDEFINED */
- const dict_index_t* index, /* in: index from which to search */
- const dict_index_t* index2, /* in: index */
- ulint n) /* in: field number in index2 */
+ const dict_index_t* index, /*!< in: index from which to search */
+ const dict_index_t* index2, /*!< in: index */
+ ulint n) /*!< in: field number in index2 */
{
const dict_field_t* field;
const dict_field_t* field2;
@@ -516,15 +513,15 @@ dict_index_get_nth_field_pos(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Returns a table object based on table id. */
+/**********************************************************************//**
+Returns a table object based on table id.
+@return table, NULL if does not exist */
UNIV_INTERN
dict_table_t*
dict_table_get_on_id(
/*=================*/
- /* out: table, NULL if does not exist */
- dulint table_id, /* in: table id */
- trx_t* trx) /* in: transaction handle */
+ dulint table_id, /*!< in: table id */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_table_t* table;
@@ -552,33 +549,30 @@ dict_table_get_on_id(
return(table);
}
-/************************************************************************
-Looks for column n position in the clustered index. */
+/********************************************************************//**
+Looks for column n position in the clustered index.
+@return position in internal representation of the clustered index */
UNIV_INTERN
ulint
dict_table_get_nth_col_pos(
/*=======================*/
- /* out: position in internal
- representation of
- the clustered index */
- const dict_table_t* table, /* in: table */
- ulint n) /* in: column number */
+ const dict_table_t* table, /*!< in: table */
+ ulint n) /*!< in: column number */
{
return(dict_index_get_nth_col_pos(dict_table_get_first_index(table),
n));
}
-/************************************************************************
+/********************************************************************//**
Checks if a column is in the ordering columns of the clustered index of a
-table. Column prefixes are treated like whole columns. */
+table. Column prefixes are treated like whole columns.
+@return TRUE if the column, or its prefix, is in the clustered key */
UNIV_INTERN
ibool
dict_table_col_in_clustered_key(
/*============================*/
- /* out: TRUE if the column, or its
- prefix, is in the clustered key */
- const dict_table_t* table, /* in: table */
- ulint n) /* in: column number */
+ const dict_table_t* table, /*!< in: table */
+ ulint n) /*!< in: column number */
{
const dict_index_t* index;
const dict_field_t* field;
@@ -606,7 +600,7 @@ dict_table_col_in_clustered_key(
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Inits the data dictionary module. */
UNIV_INTERN
void
@@ -635,20 +629,18 @@ dict_init(void)
mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
}
-/**************************************************************************
+/**********************************************************************//**
Returns a table object and optionally increment its MySQL open handle count.
NOTE! This is a high-level function to be used mainly from outside the
'dict' directory. Inside this directory dict_table_get_low is usually the
-appropriate function. */
+appropriate function.
+@return table, NULL if does not exist */
UNIV_INTERN
dict_table_t*
dict_table_get(
/*===========*/
- /* out: table, NULL if
- does not exist */
- const char* table_name, /* in: table name */
- ibool inc_mysql_count)
- /* in: whether to increment the open
+ const char* table_name, /*!< in: table name */
+ ibool inc_mysql_count)/*!< in: whether to increment the open
handle count on the table */
{
dict_table_t* table;
@@ -676,15 +668,16 @@ dict_table_get(
return(table);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Adds system columns to a table object. */
UNIV_INTERN
void
dict_table_add_system_columns(
/*==========================*/
- dict_table_t* table, /* in/out: table */
- mem_heap_t* heap) /* in: temporary heap */
+ dict_table_t* table, /*!< in/out: table */
+ mem_heap_t* heap) /*!< in: temporary heap */
{
ut_ad(table);
ut_ad(table->n_def == table->n_cols - DATA_N_SYS_COLS);
@@ -723,14 +716,15 @@ dict_table_add_system_columns(
#endif
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Adds a table object to the dictionary cache. */
UNIV_INTERN
void
dict_table_add_to_cache(
/*====================*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: temporary heap */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap) /*!< in: temporary heap */
{
ulint fold;
ulint id_fold;
@@ -814,16 +808,16 @@ dict_table_add_to_cache(
dict_sys->size += mem_heap_get_size(table->heap);
}
-/**************************************************************************
+/**********************************************************************//**
Looks for an index with the given id. NOTE that we do not reserve
the dictionary mutex: this function is for emergency purposes like
-printing info of a corrupt database page! */
+printing info of a corrupt database page!
+@return index or NULL if not found from cache */
UNIV_INTERN
dict_index_t*
dict_index_find_on_id_low(
/*======================*/
- /* out: index or NULL if not found from cache */
- dulint id) /* in: index id */
+ dulint id) /*!< in: index id */
{
dict_table_t* table;
dict_index_t* index;
@@ -849,16 +843,16 @@ dict_index_find_on_id_low(
return(NULL);
}
-/**************************************************************************
-Renames a table object. */
+/**********************************************************************//**
+Renames a table object.
+@return TRUE if success */
UNIV_INTERN
ibool
dict_table_rename_in_cache(
/*=======================*/
- /* out: TRUE if success */
- dict_table_t* table, /* in/out: table */
- const char* new_name, /* in: new name */
- ibool rename_also_foreigns)/* in: in ALTER TABLE we want
+ dict_table_t* table, /*!< in/out: table */
+ const char* new_name, /*!< in: new name */
+ ibool rename_also_foreigns)/*!< in: in ALTER TABLE we want
to preserve the original table name
in constraints which reference it */
{
@@ -1065,15 +1059,15 @@ dict_table_rename_in_cache(
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Change the id of a table object in the dictionary cache. This is used in
DISCARD TABLESPACE. */
UNIV_INTERN
void
dict_table_change_id_in_cache(
/*==========================*/
- dict_table_t* table, /* in/out: table object already in cache */
- dulint new_id) /* in: new id to set */
+ dict_table_t* table, /*!< in/out: table object already in cache */
+ dulint new_id) /*!< in: new id to set */
{
ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -1090,13 +1084,13 @@ dict_table_change_id_in_cache(
ut_fold_dulint(table->id), table);
}
-/**************************************************************************
+/**********************************************************************//**
Removes a table object from the dictionary cache. */
UNIV_INTERN
void
dict_table_remove_from_cache(
/*=========================*/
- dict_table_t* table) /* in, own: table */
+ dict_table_t* table) /*!< in, own: table */
{
dict_foreign_t* foreign;
dict_index_t* index;
@@ -1215,15 +1209,15 @@ next_loop:
goto retry;
}
-/********************************************************************
+/****************************************************************//**
If the given column name is reserved for InnoDB system columns, return
-TRUE. */
+TRUE.
+@return TRUE if name is reserved */
UNIV_INTERN
ibool
dict_col_name_is_reserved(
/*======================*/
- /* out: TRUE if name is reserved */
- const char* name) /* in: column name */
+ const char* name) /*!< in: column name */
{
/* This check reminds that if a new system column is added to
the program, it should be dealt with here. */
@@ -1238,7 +1232,7 @@ dict_col_name_is_reserved(
ulint i;
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
- if (strcmp(name, reserved_names[i]) == 0) {
+ if (innobase_strcasecmp(name, reserved_names[i]) == 0) {
return(TRUE);
}
@@ -1247,17 +1241,16 @@ dict_col_name_is_reserved(
return(FALSE);
}
-/********************************************************************
+/****************************************************************//**
If an undo log record for this table might not fit on a single page,
-return TRUE. */
+return TRUE.
+@return TRUE if the undo log record could become too big */
static
ibool
dict_index_too_big_for_undo(
/*========================*/
- /* out: TRUE if the undo log
- record could become too big */
- const dict_table_t* table, /* in: table */
- const dict_index_t* new_index) /* in: index */
+ const dict_table_t* table, /*!< in: table */
+ const dict_index_t* new_index) /*!< in: index */
{
/* Make sure that all column prefixes will fit in the undo log record
in trx_undo_page_report_modify() right after trx_undo_page_init(). */
@@ -1269,7 +1262,7 @@ dict_index_too_big_for_undo(
= TRX_UNDO_PAGE_HDR - TRX_UNDO_PAGE_HDR_SIZE
+ 2 /* next record pointer */
+ 1 /* type_cmpl */
- + 11 /* trx->undo_no */ - 11 /* table->id */
+ + 11 /* trx->undo_no */ + 11 /* table->id */
+ 1 /* rec_get_info_bits() */
+ 11 /* DB_TRX_ID */
+ 11 /* DB_ROLL_PTR */
@@ -1307,7 +1300,8 @@ dict_index_too_big_for_undo(
ulint max_size
= dict_col_get_max_size(col);
ulint fixed_size
- = dict_col_get_fixed_size(col);
+ = dict_col_get_fixed_size(col,
+ dict_table_is_comp(table));
if (fixed_size) {
/* Fixed-size columns are stored locally. */
@@ -1349,17 +1343,16 @@ is_ord_part:
return(undo_page_len >= UNIV_PAGE_SIZE);
}
-/********************************************************************
+/****************************************************************//**
If a record of this index might not fit on a single B-tree page,
-return TRUE. */
+return TRUE.
+@return TRUE if the index record could become too big */
static
ibool
dict_index_too_big_for_tree(
/*========================*/
- /* out: TRUE if the index
- record could become too big */
- const dict_table_t* table, /* in: table */
- const dict_index_t* new_index) /* in: index */
+ const dict_table_t* table, /*!< in: table */
+ const dict_index_t* new_index) /*!< in: index */
{
ulint zip_size;
ulint comp;
@@ -1437,7 +1430,7 @@ dict_index_too_big_for_tree(
case in rec_get_converted_size_comp() for
REC_STATUS_ORDINARY records. */
- field_max_size = dict_col_get_fixed_size(col);
+ field_max_size = dict_col_get_fixed_size(col, comp);
if (field_max_size) {
/* dict_index_add_col() should guarantee this */
ut_ad(!field->prefix_len
@@ -1448,7 +1441,11 @@ dict_index_too_big_for_tree(
goto add_field_size;
}
+ if (srv_relax_table_creation) {
+ field_max_size = dict_col_get_min_size(col);
+ } else {
field_max_size = dict_col_get_max_size(col);
+ }
field_ext_max_size = field_max_size < 256 ? 1 : 2;
if (field->prefix_len) {
@@ -1499,18 +1496,18 @@ add_field_size:
return(FALSE);
}
-/**************************************************************************
-Adds an index to the dictionary cache. */
+/**********************************************************************//**
+Adds an index to the dictionary cache.
+@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
UNIV_INTERN
ulint
dict_index_add_to_cache(
/*====================*/
- /* out: DB_SUCCESS or DB_TOO_BIG_RECORD */
- dict_table_t* table, /* in: table on which the index is */
- dict_index_t* index, /* in, own: index; NOTE! The index memory
+ dict_table_t* table, /*!< in: table on which the index is */
+ dict_index_t* index, /*!< in, own: index; NOTE! The index memory
object is freed in this function! */
- ulint page_no,/* in: root page number of the index */
- ibool strict) /* in: TRUE=refuse to create the index
+ ulint page_no,/*!< in: root page number of the index */
+ ibool strict) /*!< in: TRUE=refuse to create the index
if records could be too big to fit in
an B-tree page */
{
@@ -1527,7 +1524,10 @@ dict_index_add_to_cache(
ut_a(!dict_index_is_clust(index)
|| UT_LIST_GET_LEN(table->indexes) == 0);
- dict_index_find_cols(table, index);
+ if (!dict_index_find_cols(table, index)) {
+
+ return(DB_CORRUPTION);
+ }
/* Build the cache internal representation of the index,
containing also the added system fields */
@@ -1597,7 +1597,7 @@ too_big:
if (field->prefix_len /* prefix index */
&& !col->ord_part /* not yet ordering column */
- && !dict_col_get_fixed_size(col) /* variable-length */
+ && !dict_col_get_fixed_size(col, TRUE) /* variable-length */
&& dict_col_get_max_size(col)
> BTR_EXTERN_FIELD_REF_SIZE * 2 /* long enough */) {
@@ -1656,14 +1656,14 @@ undo_size_ok:
return(DB_SUCCESS);
}
-/**************************************************************************
+/**********************************************************************//**
Removes an index from the dictionary cache. */
UNIV_INTERN
void
dict_index_remove_from_cache(
/*=========================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index) /* in, own: index */
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index) /*!< in, own: index */
{
ulint size;
ulint retries = 0;
@@ -1674,6 +1674,11 @@ dict_index_remove_from_cache(
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&(dict_sys->mutex)));
+ /* remove all entry of the index from adaptive hash index,
+ because removing from adaptive hash index needs dict_index */
+ if (btr_search_enabled && srv_dict_size_limit)
+ btr_search_drop_page_hash_index_on_index(index);
+
/* We always create search info whether or not adaptive
hash index is enabled or not. */
info = index->search_info;
@@ -1733,15 +1738,16 @@ dict_index_remove_from_cache(
dict_mem_index_free(index);
}
-/***********************************************************************
+/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
-index. */
+index.
+@return TRUE if the column names were found */
static
-void
+ibool
dict_index_find_cols(
/*=================*/
- dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: index */
+ dict_table_t* table, /*!< in: table */
+ dict_index_t* index) /*!< in: index */
{
ulint i;
@@ -1762,24 +1768,34 @@ dict_index_find_cols(
}
}
+#ifdef UNIV_DEBUG
/* It is an error not to find a matching column. */
- ut_error;
+ fputs("InnoDB: Error: no matching column for ", stderr);
+ ut_print_name(stderr, NULL, FALSE, field->name);
+ fputs(" in ", stderr);
+ dict_index_name_print(stderr, NULL, index);
+ fputs("!\n", stderr);
+#endif /* UNIV_DEBUG */
+ return(FALSE);
found:
;
}
+
+ return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
+/*******************************************************************//**
Adds a column to index. */
UNIV_INTERN
void
dict_index_add_col(
/*===============*/
- dict_index_t* index, /* in/out: index */
- const dict_table_t* table, /* in: table */
- dict_col_t* col, /* in: column */
- ulint prefix_len) /* in: column prefix length */
+ dict_index_t* index, /*!< in/out: index */
+ const dict_table_t* table, /*!< in: table */
+ dict_col_t* col, /*!< in: column */
+ ulint prefix_len) /*!< in: column prefix length */
{
dict_field_t* field;
const char* col_name;
@@ -1791,7 +1807,8 @@ dict_index_add_col(
field = dict_index_get_nth_field(index, index->n_def - 1);
field->col = col;
- field->fixed_len = (unsigned int) dict_col_get_fixed_size(col);
+ field->fixed_len = (unsigned int) dict_col_get_fixed_size(
+ col, dict_table_is_comp(table));
if (prefix_len && field->fixed_len > prefix_len) {
field->fixed_len = (unsigned int) prefix_len;
@@ -1816,17 +1833,18 @@ dict_index_add_col(
}
}
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Copies fields contained in index2 to index1. */
static
void
dict_index_copy(
/*============*/
- dict_index_t* index1, /* in: index to copy to */
- dict_index_t* index2, /* in: index to copy from */
- const dict_table_t* table, /* in: table */
- ulint start, /* in: first position to copy */
- ulint end) /* in: last position to copy */
+ dict_index_t* index1, /*!< in: index to copy to */
+ dict_index_t* index2, /*!< in: index to copy from */
+ const dict_table_t* table, /*!< in: table */
+ ulint start, /*!< in: first position to copy */
+ ulint end) /*!< in: last position to copy */
{
dict_field_t* field;
ulint i;
@@ -1841,15 +1859,15 @@ dict_index_copy(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies types of fields contained in index to tuple. */
UNIV_INTERN
void
dict_index_copy_types(
/*==================*/
- dtuple_t* tuple, /* in/out: data tuple */
- const dict_index_t* index, /* in: index */
- ulint n_fields) /* in: number of
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const dict_index_t* index, /*!< in: index */
+ ulint n_fields) /*!< in: number of
field types to copy */
{
ulint i;
@@ -1870,7 +1888,7 @@ dict_index_copy_types(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies types of columns contained in table to tuple and sets all
fields of the tuple to the SQL NULL value. This function should
be called right after dtuple_create(). */
@@ -1878,8 +1896,8 @@ UNIV_INTERN
void
dict_table_copy_types(
/*==================*/
- dtuple_t* tuple, /* in/out: data tuple */
- const dict_table_t* table) /* in: table */
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const dict_table_t* table) /*!< in: table */
{
ulint i;
@@ -1893,18 +1911,16 @@ dict_table_copy_types(
}
}
-/***********************************************************************
+/*******************************************************************//**
Builds the internal dictionary cache representation for a clustered
-index, containing also system fields not defined by the user. */
+index, containing also system fields not defined by the user.
+@return own: the internal representation of the clustered index */
static
dict_index_t*
dict_index_build_internal_clust(
/*============================*/
- /* out, own: the internal
- representation of the clustered
- index */
- const dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: user representation of
+ const dict_table_t* table, /*!< in: table */
+ dict_index_t* index) /*!< in: user representation of
a clustered index */
{
dict_index_t* new_index;
@@ -1987,7 +2003,8 @@ dict_index_build_internal_clust(
for (i = 0; i < trx_id_pos; i++) {
fixed_size = dict_col_get_fixed_size(
- dict_index_get_nth_col(new_index, i));
+ dict_index_get_nth_col(new_index, i),
+ dict_table_is_comp(table));
if (fixed_size == 0) {
new_index->trx_id_offset = 0;
@@ -2046,18 +2063,16 @@ dict_index_build_internal_clust(
return(new_index);
}
-/***********************************************************************
+/*******************************************************************//**
Builds the internal dictionary cache representation for a non-clustered
-index, containing also system fields not defined by the user. */
+index, containing also system fields not defined by the user.
+@return own: the internal representation of the non-clustered index */
static
dict_index_t*
dict_index_build_internal_non_clust(
/*================================*/
- /* out, own: the internal
- representation of the non-clustered
- index */
- const dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: user representation of
+ const dict_table_t* table, /*!< in: table */
+ dict_index_t* index) /*!< in: user representation of
a non-clustered index */
{
dict_field_t* field;
@@ -2143,30 +2158,29 @@ dict_index_build_internal_non_clust(
/*====================== FOREIGN KEY PROCESSING ========================*/
-/*************************************************************************
-Checks if a table is referenced by foreign keys. */
+/*********************************************************************//**
+Checks if a table is referenced by foreign keys.
+@return TRUE if table is referenced by a foreign key */
UNIV_INTERN
ibool
dict_table_is_referenced_by_foreign_key(
/*====================================*/
- /* out: TRUE if table is referenced
- by a foreign key */
- const dict_table_t* table) /* in: InnoDB table */
+ const dict_table_t* table) /*!< in: InnoDB table */
{
return(UT_LIST_GET_LEN(table->referenced_list) > 0);
}
-/*************************************************************************
+/*********************************************************************//**
Check if the index is referenced by a foreign key, if TRUE return foreign
-else return NULL */
+else return NULL
+@return pointer to foreign key struct if index is defined for foreign
+key, otherwise NULL */
UNIV_INTERN
dict_foreign_t*
dict_table_get_referenced_constraint(
/*=================================*/
- /* out: pointer to foreign key struct if index
- is defined for foreign key, otherwise NULL */
- dict_table_t* table, /* in: InnoDB table */
- dict_index_t* index) /* in: InnoDB index */
+ dict_table_t* table, /*!< in: InnoDB table */
+ dict_index_t* index) /*!< in: InnoDB index */
{
dict_foreign_t* foreign;
@@ -2186,18 +2200,18 @@ dict_table_get_referenced_constraint(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a index is defined for a foreign key constraint. Index is a part
of a foreign key constraint if the index is referenced by foreign key
-or index is a foreign key index. */
+or index is a foreign key index.
+@return pointer to foreign key struct if index is defined for foreign
+key, otherwise NULL */
UNIV_INTERN
dict_foreign_t*
dict_table_get_foreign_constraint(
/*==============================*/
- /* out: pointer to foreign key struct if index
- is defined for foreign key, otherwise NULL */
- dict_table_t* table, /* in: InnoDB table */
- dict_index_t* index) /* in: InnoDB index */
+ dict_table_t* table, /*!< in: InnoDB table */
+ dict_index_t* index) /*!< in: InnoDB index */
{
dict_foreign_t* foreign;
@@ -2218,24 +2232,24 @@ dict_table_get_foreign_constraint(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Frees a foreign key struct. */
static
void
dict_foreign_free(
/*==============*/
- dict_foreign_t* foreign) /* in, own: foreign key struct */
+ dict_foreign_t* foreign) /*!< in, own: foreign key struct */
{
mem_heap_free(foreign->heap);
}
-/**************************************************************************
+/**********************************************************************//**
Removes a foreign constraint struct from the dictionary cache. */
static
void
dict_foreign_remove_from_cache(
/*===========================*/
- dict_foreign_t* foreign) /* in, own: foreign constraint */
+ dict_foreign_t* foreign) /*!< in, own: foreign constraint */
{
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_a(foreign);
@@ -2255,17 +2269,16 @@ dict_foreign_remove_from_cache(
dict_foreign_free(foreign);
}
-#ifndef UNIV_HOTBACKUP
-/**************************************************************************
+/**********************************************************************//**
Looks for the foreign constraint from the foreign and referenced lists
-of a table. */
+of a table.
+@return foreign constraint */
static
dict_foreign_t*
dict_foreign_find(
/*==============*/
- /* out: foreign constraint */
- dict_table_t* table, /* in: table object */
- const char* id) /* in: foreign constraint id */
+ dict_table_t* table, /*!< in: table object */
+ const char* id) /*!< in: foreign constraint id */
{
dict_foreign_t* foreign;
@@ -2296,25 +2309,25 @@ dict_foreign_find(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Tries to find an index whose first fields are the columns in the array,
in the same order and is not marked for deletion and is not the same
-as types_idx. */
+as types_idx.
+@return matching index, NULL if not found */
static
dict_index_t*
dict_foreign_find_index(
/*====================*/
- /* out: matching index, NULL if not found */
- dict_table_t* table, /* in: table */
- const char** columns,/* in: array of column names */
- ulint n_cols, /* in: number of columns */
- dict_index_t* types_idx, /* in: NULL or an index to whose types the
+ dict_table_t* table, /*!< in: table */
+ const char** columns,/*!< in: array of column names */
+ ulint n_cols, /*!< in: number of columns */
+ dict_index_t* types_idx, /*!< in: NULL or an index to whose types the
column types must match */
ibool check_charsets,
- /* in: whether to check charsets.
+ /*!< in: whether to check charsets.
only has an effect if types_idx != NULL */
ulint check_null)
- /* in: nonzero if none of the columns must
+ /*!< in: nonzero if none of the columns must
be declared NOT NULL */
{
dict_index_t* index;
@@ -2382,16 +2395,15 @@ next_rec:
return(NULL);
}
-/**************************************************************************
+/**********************************************************************//**
Find an index that is equivalent to the one passed in and is not marked
-for deletion. */
+for deletion.
+@return index equivalent to foreign->foreign_index, or NULL */
UNIV_INTERN
dict_index_t*
dict_foreign_find_equiv_index(
/*==========================*/
- /* out: index equivalent to
- foreign->foreign_index, or NULL */
- dict_foreign_t* foreign)/* in: foreign key */
+ dict_foreign_t* foreign)/*!< in: foreign key */
{
ut_a(foreign != NULL);
@@ -2406,18 +2418,18 @@ dict_foreign_find_equiv_index(
FALSE/* allow columns to be NULL */));
}
-/**************************************************************************
+/**********************************************************************//**
Returns an index object by matching on the name and column names and
-if more than one index matches return the index with the max id */
+if more than one index matches return the index with the max id
+@return matching index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_table_get_index_by_max_id(
/*===========================*/
- /* out: matching index, NULL if not found */
- dict_table_t* table, /* in: table */
- const char* name, /* in: the index name to find */
- const char** columns,/* in: array of column names */
- ulint n_cols) /* in: number of columns */
+ dict_table_t* table, /*!< in: table */
+ const char* name, /*!< in: the index name to find */
+ const char** columns,/*!< in: array of column names */
+ ulint n_cols) /*!< in: number of columns */
{
dict_index_t* index;
dict_index_t* found;
@@ -2466,14 +2478,14 @@ dict_table_get_index_by_max_id(
return(found);
}
-/**************************************************************************
+/**********************************************************************//**
Report an error in a foreign key definition. */
static
void
dict_foreign_error_report_low(
/*==========================*/
- FILE* file, /* in: output stream */
- const char* name) /* in: table name */
+ FILE* file, /*!< in: output stream */
+ const char* name) /*!< in: table name */
{
rewind(file);
ut_print_timestamp(file);
@@ -2481,15 +2493,15 @@ dict_foreign_error_report_low(
name);
}
-/**************************************************************************
+/**********************************************************************//**
Report an error in a foreign key definition. */
static
void
dict_foreign_error_report(
/*======================*/
- FILE* file, /* in: output stream */
- dict_foreign_t* fk, /* in: foreign key constraint */
- const char* msg) /* in: the error message */
+ FILE* file, /*!< in: output stream */
+ dict_foreign_t* fk, /*!< in: foreign key constraint */
+ const char* msg) /*!< in: the error message */
{
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(file, fk->foreign_table_name);
@@ -2501,26 +2513,25 @@ dict_foreign_error_report(
fputs("The index in the foreign key in table is ", file);
ut_print_name(file, NULL, FALSE, fk->foreign_index->name);
fputs("\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-foreign-key-constraints.html\n"
+ "See " REFMAN "innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
file);
}
mutex_exit(&dict_foreign_err_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Adds a foreign key constraint object to the dictionary cache. May free
the object if there already is an object with the same identifier in.
At least one of the foreign table and the referenced table must already
-be in the dictionary cache! */
+be in the dictionary cache!
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_foreign_add_to_cache(
/*======================*/
- /* out: DB_SUCCESS or error code */
- dict_foreign_t* foreign, /* in, own: foreign key constraint */
- ibool check_charsets) /* in: TRUE=check charset
+ dict_foreign_t* foreign, /*!< in, own: foreign key constraint */
+ ibool check_charsets) /*!< in: TRUE=check charset
compatibility */
{
dict_table_t* for_table;
@@ -2632,17 +2643,17 @@ dict_foreign_add_to_cache(
return(DB_SUCCESS);
}
-/*************************************************************************
+/*********************************************************************//**
Scans from pointer onwards. Stops if is at the start of a copy of
'string' where characters are compared without case sensitivity, and
-only outside `` or "" quotes. Stops also at '\0'. */
+only outside `` or "" quotes. Stops also at NUL.
+@return scanned up to this */
static
const char*
dict_scan_to(
/*=========*/
- /* out: scanned up to this */
- const char* ptr, /* in: scan from */
- const char* string) /* in: look for this */
+ const char* ptr, /*!< in: scan from */
+ const char* string) /*!< in: look for this */
{
char quote = '\0';
@@ -2675,19 +2686,19 @@ nomatch:
return(ptr);
}
-/*************************************************************************
-Accepts a specified string. Comparisons are case-insensitive. */
+/*********************************************************************//**
+Accepts a specified string. Comparisons are case-insensitive.
+@return if string was accepted, the pointer is moved after that, else
+ptr is returned */
static
const char*
dict_accept(
/*========*/
- /* out: if string was accepted, the pointer
- is moved after that, else ptr is returned */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scan from this */
- const char* string, /* in: accept only this string as the next
+ struct charset_info_st* cs,/*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scan from this */
+ const char* string, /*!< in: accept only this string as the next
non-whitespace string */
- ibool* success)/* out: TRUE if accepted */
+ ibool* success)/*!< out: TRUE if accepted */
{
const char* old_ptr = ptr;
const char* old_ptr2;
@@ -2711,25 +2722,25 @@ dict_accept(
return(ptr + ut_strlen(string));
}
-/*************************************************************************
+/*********************************************************************//**
Scans an id. For the lexical definition of an 'id', see the code below.
-Strips backquotes or double quotes from around the id. */
+Strips backquotes or double quotes from around the id.
+@return scanned to */
static
const char*
dict_scan_id(
/*=========*/
- /* out: scanned to */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- mem_heap_t* heap, /* in: heap where to allocate the id
+ struct charset_info_st* cs,/*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scanned to */
+ mem_heap_t* heap, /*!< in: heap where to allocate the id
(NULL=id will not be allocated, but it
will point to string near ptr) */
- const char** id, /* out,own: the id; NULL if no id was
+ const char** id, /*!< out,own: the id; NULL if no id was
scannable */
- ibool table_id,/* in: TRUE=convert the allocated id
+ ibool table_id,/*!< in: TRUE=convert the allocated id
as a table name; FALSE=convert to UTF-8 */
ibool accept_also_dot)
- /* in: TRUE if also a dot can appear in a
+ /*!< in: TRUE if also a dot can appear in a
non-quoted id; in a quoted id it can appear
always */
{
@@ -2831,20 +2842,20 @@ convert_id:
return(ptr);
}
-/*************************************************************************
-Tries to scan a column name. */
+/*********************************************************************//**
+Tries to scan a column name.
+@return scanned to */
static
const char*
dict_scan_col(
/*==========*/
- /* out: scanned to */
- struct charset_info_st* cs, /* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- ibool* success,/* out: TRUE if success */
- dict_table_t* table, /* in: table in which the column is */
- const dict_col_t** column, /* out: pointer to column if success */
- mem_heap_t* heap, /* in: heap where to allocate */
- const char** name) /* out,own: the column name;
+ struct charset_info_st* cs, /*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scanned to */
+ ibool* success,/*!< out: TRUE if success */
+ dict_table_t* table, /*!< in: table in which the column is */
+ const dict_col_t** column, /*!< out: pointer to column if success */
+ mem_heap_t* heap, /*!< in: heap where to allocate */
+ const char** name) /*!< out,own: the column name;
NULL if no name was scannable */
{
ulint i;
@@ -2882,20 +2893,20 @@ dict_scan_col(
return(ptr);
}
-/*************************************************************************
-Scans a table name from an SQL string. */
+/*********************************************************************//**
+Scans a table name from an SQL string.
+@return scanned to */
static
const char*
dict_scan_table_name(
/*=================*/
- /* out: scanned to */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- dict_table_t** table, /* out: table object or NULL */
- const char* name, /* in: foreign key table name */
- ibool* success,/* out: TRUE if ok name found */
- mem_heap_t* heap, /* in: heap where to allocate the id */
- const char** ref_name)/* out,own: the table name;
+ struct charset_info_st* cs,/*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scanned to */
+ dict_table_t** table, /*!< out: table object or NULL */
+ const char* name, /*!< in: foreign key table name */
+ ibool* success,/*!< out: TRUE if ok name found */
+ mem_heap_t* heap, /*!< in: heap where to allocate the id */
+ const char** ref_name)/*!< out,own: the table name;
NULL if no name was scannable */
{
const char* database_name = NULL;
@@ -2981,16 +2992,16 @@ dict_scan_table_name(
return(ptr);
}
-/*************************************************************************
-Skips one id. The id is allowed to contain also '.'. */
+/*********************************************************************//**
+Skips one id. The id is allowed to contain also '.'.
+@return scanned to */
static
const char*
dict_skip_word(
/*===========*/
- /* out: scanned to */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- ibool* success)/* out: TRUE if success, FALSE if just spaces
+ struct charset_info_st* cs,/*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scanned to */
+ ibool* success)/*!< out: TRUE if success, FALSE if just spaces
left in string or a syntax error */
{
const char* start;
@@ -3006,20 +3017,19 @@ dict_skip_word(
return(ptr);
}
-/*************************************************************************
+/*********************************************************************//**
Removes MySQL comments from an SQL string. A comment is either
(a) '#' to the end of the line,
-(b) '--<space>' to the end of the line, or
-(c) '<slash><asterisk>' till the next '<asterisk><slash>' (like the familiar
-C comment syntax). */
+(b) '--[space]' to the end of the line, or
+(c) '[slash][asterisk]' till the next '[asterisk][slash]' (like the familiar
+C comment syntax).
+@return own: SQL string stripped from comments; the caller must free
+this with mem_free()! */
static
char*
dict_strip_comments(
/*================*/
- /* out, own: SQL string stripped from
- comments; the caller must free this
- with mem_free()! */
- const char* sql_string) /* in: SQL string */
+ const char* sql_string) /*!< in: SQL string */
{
char* str;
const char* sptr;
@@ -3093,17 +3103,16 @@ scan_more:
}
}
-/*************************************************************************
-Finds the highest <number> for foreign key constraints of the table. Looks
+/*********************************************************************//**
+Finds the highest [number] for foreign key constraints of the table. Looks
only at the >= 4.0.18-format id's, which are of the form
-databasename/tablename_ibfk_<number>. */
+databasename/tablename_ibfk_[number].
+@return highest number, 0 if table has no new format foreign key constraints */
static
ulint
dict_table_get_highest_foreign_id(
/*==============================*/
- /* out: highest number, 0 if table has no new
- format foreign key constraints */
- dict_table_t* table) /* in: table in the dictionary memory cache */
+ dict_table_t* table) /*!< in: table in the dictionary memory cache */
{
dict_foreign_t* foreign;
char* endp;
@@ -3142,17 +3151,17 @@ dict_table_get_highest_foreign_id(
return(biggest_id);
}
-/*************************************************************************
+/*********************************************************************//**
Reports a simple foreign key create clause syntax error. */
static
void
dict_foreign_report_syntax_err(
/*===========================*/
- const char* name, /* in: table name */
+ const char* name, /*!< in: table name */
const char* start_of_latest_foreign,
- /* in: start of the foreign key clause
+ /*!< in: start of the foreign key clause
in the SQL string */
- const char* ptr) /* in: place of the syntax error */
+ const char* ptr) /*!< in: place of the syntax error */
{
FILE* ef = dict_foreign_err_file;
@@ -3163,31 +3172,31 @@ dict_foreign_report_syntax_err(
mutex_exit(&dict_foreign_err_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary the foreign
key constraints declared in the string. This function should be called after
the indexes for a table have been created. Each foreign key constraint must
be accompanied with indexes in both participating tables. The indexes are
-allowed to contain more fields than mentioned in the constraint. */
+allowed to contain more fields than mentioned in the constraint.
+@return error code or DB_SUCCESS */
static
ulint
dict_create_foreign_constraints_low(
/*================================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap, /* in: memory heap */
- struct charset_info_st* cs,/* in: the character set of sql_string */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap, /*!< in: memory heap */
+ struct charset_info_st* cs,/*!< in: the character set of sql_string */
const char* sql_string,
- /* in: CREATE TABLE or ALTER TABLE statement
+ /*!< in: CREATE TABLE or ALTER TABLE statement
where foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the database
name before it: test.table2; the default
database is the database of parameter name */
- const char* name, /* in: table full name in the normalized form
+ const char* name, /*!< in: table full name in the normalized form
database_name/table_name */
ibool reject_fks)
- /* in: if TRUE, fail with error code
+ /*!< in: if TRUE, fail with error code
DB_CANNOT_ADD_CONSTRAINT if any foreign
keys are found. */
{
@@ -3261,8 +3270,8 @@ dict_create_foreign_constraints_low(
}
/* Starting from 4.0.18 and 4.1.2, we generate foreign key id's in the
- format databasename/tablename_ibfk_<number>, where <number> is local
- to the table; look for the highest <number> for table_to_alter, so
+ format databasename/tablename_ibfk_[number], where [number] is local
+ to the table; look for the highest [number] for table_to_alter, so
that we can assign to new constraints higher numbers. */
/* If we are altering a temporary table, the table name after ALTER
@@ -3422,8 +3431,7 @@ col_loop1:
ut_print_name(ef, NULL, TRUE, name);
fprintf(ef, " where the columns appear\n"
"as the first columns. Constraint:\n%s\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-foreign-key-constraints.html\n"
+ "See " REFMAN "innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
@@ -3703,7 +3711,7 @@ try_find_index:
" and such columns in old tables\n"
"cannot be referenced by such columns"
" in new tables.\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/"
+ "See " REFMAN
"innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);
@@ -3742,19 +3750,19 @@ try_find_index:
goto loop;
}
-/*************************************************************************
+/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary the foreign
key constraints declared in the string. This function should be called after
the indexes for a table have been created. Each foreign key constraint must
be accompanied with indexes in both participating tables. The indexes are
-allowed to contain more fields than mentioned in the constraint. */
+allowed to contain more fields than mentioned in the constraint.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_foreign_constraints(
/*============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- const char* sql_string, /* in: table create statement where
+ trx_t* trx, /*!< in: transaction */
+ const char* sql_string, /*!< in: table create statement where
foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES
table2(c, d), table2 can be written
@@ -3762,10 +3770,10 @@ dict_create_foreign_constraints(
name before it: test.table2; the
default database id the database of
parameter name */
- const char* name, /* in: table full name in the
+ const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
- ibool reject_fks) /* in: if TRUE, fail with error
+ ibool reject_fks) /*!< in: if TRUE, fail with error
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
{
@@ -3789,23 +3797,21 @@ dict_create_foreign_constraints(
return(err);
}
-/**************************************************************************
-Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */
+/**********************************************************************//**
+Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement.
+@return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the
+constraint id does not match */
UNIV_INTERN
ulint
dict_foreign_parse_drop_constraints(
/*================================*/
- /* out: DB_SUCCESS or
- DB_CANNOT_DROP_CONSTRAINT if
- syntax error or the constraint
- id does not match */
- mem_heap_t* heap, /* in: heap from which we can
+ mem_heap_t* heap, /*!< in: heap from which we can
allocate memory */
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table */
- ulint* n, /* out: number of constraints
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table */
+ ulint* n, /*!< out: number of constraints
to drop */
- const char*** constraints_to_drop) /* out: id's of the
+ const char*** constraints_to_drop) /*!< out: id's of the
constraints to drop */
{
dict_foreign_t* foreign;
@@ -3923,19 +3929,18 @@ syntax_error:
return(DB_CANNOT_DROP_CONSTRAINT);
}
-#endif /* UNIV_HOTBACKUP */
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
-/**************************************************************************
+/**********************************************************************//**
Returns an index object if it is found in the dictionary cache.
-Assumes that dict_sys->mutex is already being held. */
+Assumes that dict_sys->mutex is already being held.
+@return index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_index_get_if_in_cache_low(
/*===========================*/
- /* out: index, NULL if not found */
- dulint index_id) /* in: index id */
+ dulint index_id) /*!< in: index id */
{
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -3943,14 +3948,14 @@ dict_index_get_if_in_cache_low(
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
-Returns an index object if it is found in the dictionary cache. */
+/**********************************************************************//**
+Returns an index object if it is found in the dictionary cache.
+@return index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_index_get_if_in_cache(
/*=======================*/
- /* out: index, NULL if not found */
- dulint index_id) /* in: index id */
+ dulint index_id) /*!< in: index id */
{
dict_index_t* index;
@@ -3969,16 +3974,16 @@ dict_index_get_if_in_cache(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Checks that a tuple has n_fields_cmp value in a sensible range, so that
-no comparison can occur with the page number field in a node pointer. */
+no comparison can occur with the page number field in a node pointer.
+@return TRUE if ok */
UNIV_INTERN
ibool
dict_index_check_search_tuple(
/*==========================*/
- /* out: TRUE if ok */
- const dict_index_t* index, /* in: index tree */
- const dtuple_t* tuple) /* in: tuple used in a search */
+ const dict_index_t* index, /*!< in: index tree */
+ const dtuple_t* tuple) /*!< in: tuple used in a search */
{
ut_a(index);
ut_a(dtuple_get_n_fields_cmp(tuple)
@@ -3987,21 +3992,21 @@ dict_index_check_search_tuple(
}
#endif /* UNIV_DEBUG */
-/**************************************************************************
-Builds a node pointer out of a physical record and a page number. */
+/**********************************************************************//**
+Builds a node pointer out of a physical record and a page number.
+@return own: node pointer */
UNIV_INTERN
dtuple_t*
dict_index_build_node_ptr(
/*======================*/
- /* out, own: node pointer */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record for which to build node
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record for which to build node
pointer */
- ulint page_no,/* in: page number to put in node
+ ulint page_no,/*!< in: page number to put in node
pointer */
- mem_heap_t* heap, /* in: memory heap where pointer
+ mem_heap_t* heap, /*!< in: memory heap where pointer
created */
- ulint level) /* in: level of rec in tree:
+ ulint level) /*!< in: level of rec in tree:
0 means leaf level */
{
dtuple_t* tuple;
@@ -4056,21 +4061,21 @@ dict_index_build_node_ptr(
return(tuple);
}
-/**************************************************************************
+/**********************************************************************//**
Copies an initial segment of a physical record, long enough to specify an
-index entry uniquely. */
+index entry uniquely.
+@return pointer to the prefix record */
UNIV_INTERN
rec_t*
dict_index_copy_rec_order_prefix(
/*=============================*/
- /* out: pointer to the prefix record */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record for which to
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record for which to
copy prefix */
- ulint* n_fields,/* out: number of fields copied */
- byte** buf, /* in/out: memory buffer for the
+ ulint* n_fields,/*!< out: number of fields copied */
+ byte** buf, /*!< in/out: memory buffer for the
copied prefix, or NULL */
- ulint* buf_size)/* in/out: buffer size */
+ ulint* buf_size)/*!< in/out: buffer size */
{
ulint n;
@@ -4087,17 +4092,17 @@ dict_index_copy_rec_order_prefix(
return(rec_copy_prefix_to_buf(rec, index, n, buf, buf_size));
}
-/**************************************************************************
-Builds a typed data tuple out of a physical record. */
+/**********************************************************************//**
+Builds a typed data tuple out of a physical record.
+@return own: data tuple */
UNIV_INTERN
dtuple_t*
dict_index_build_data_tuple(
/*========================*/
- /* out, own: data tuple */
- dict_index_t* index, /* in: index tree */
- rec_t* rec, /* in: record for which to build data tuple */
- ulint n_fields,/* in: number of data fields */
- mem_heap_t* heap) /* in: memory heap where tuple created */
+ dict_index_t* index, /*!< in: index tree */
+ rec_t* rec, /*!< in: record for which to build data tuple */
+ ulint n_fields,/*!< in: number of data fields */
+ mem_heap_t* heap) /*!< in: memory heap where tuple created */
{
dtuple_t* tuple;
@@ -4115,24 +4120,25 @@ dict_index_build_data_tuple(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the minimum record length in an index. */
UNIV_INTERN
ulint
dict_index_calc_min_rec_len(
/*========================*/
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ulint sum = 0;
ulint i;
+ ulint comp = dict_table_is_comp(index->table);
- if (dict_table_is_comp(index->table)) {
+ if (comp) {
ulint nullable = 0;
sum = REC_N_NEW_EXTRA_BYTES;
for (i = 0; i < dict_index_get_n_fields(index); i++) {
const dict_col_t* col
= dict_index_get_nth_col(index, i);
- ulint size = dict_col_get_fixed_size(col);
+ ulint size = dict_col_get_fixed_size(col, comp);
sum += size;
if (!size) {
size = col->len;
@@ -4151,7 +4157,7 @@ dict_index_calc_min_rec_len(
for (i = 0; i < dict_index_get_n_fields(index); i++) {
sum += dict_col_get_fixed_size(
- dict_index_get_nth_col(index, i));
+ dict_index_get_nth_col(index, i), comp);
}
if (sum > 127) {
@@ -4165,16 +4171,16 @@ dict_index_calc_min_rec_len(
return(sum);
}
-/*************************************************************************
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics_low(
/*=======================*/
- dict_table_t* table, /* in/out: table */
+ dict_table_t* table, /*!< in/out: table */
ibool has_dict_mutex __attribute__((unused)))
- /* in: TRUE if the caller has the
+ /*!< in: TRUE if the caller has the
dictionary mutex */
{
dict_index_t* index;
@@ -4187,8 +4193,7 @@ dict_update_statistics_low(
" InnoDB: cannot calculate statistics for table %s\n"
"InnoDB: because the .ibd file is missing. For help,"
" please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n",
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
table->name);
return;
@@ -4249,25 +4254,25 @@ dict_update_statistics_low(
table->stat_modified_counter = 0;
}
-/*************************************************************************
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics(
/*===================*/
- dict_table_t* table) /* in/out: table */
+ dict_table_t* table) /*!< in/out: table */
{
dict_update_statistics_low(table, FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of a foreign key constraint. */
static
void
dict_foreign_print_low(
/*===================*/
- dict_foreign_t* foreign) /* in: foreign key constraint */
+ dict_foreign_t* foreign) /*!< in: foreign key constraint */
{
ulint i;
@@ -4291,26 +4296,26 @@ dict_foreign_print_low(
fputs(" )\n", stderr);
}
-/**************************************************************************
+/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
void
dict_table_print(
/*=============*/
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
mutex_enter(&(dict_sys->mutex));
dict_table_print_low(table);
mutex_exit(&(dict_sys->mutex));
}
-/**************************************************************************
+/**********************************************************************//**
Prints a table data when we know the table name. */
UNIV_INTERN
void
dict_table_print_by_name(
/*=====================*/
- const char* name)
+ const char* name) /*!< in: table name */
{
dict_table_t* table;
@@ -4324,13 +4329,13 @@ dict_table_print_by_name(
mutex_exit(&(dict_sys->mutex));
}
-/**************************************************************************
+/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
void
dict_table_print_low(
/*=================*/
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
dict_index_t* index;
dict_foreign_t* foreign;
@@ -4354,7 +4359,7 @@ dict_table_print_low(
(ulong) UT_LIST_GET_LEN(table->indexes),
(ulong) table->stat_n_rows);
- for (i = 0; i + 1 < (ulint) table->n_cols; i++) {
+ for (i = 0; i < (ulint) table->n_cols; i++) {
dict_col_print_low(table, dict_table_get_nth_col(table, i));
fputs("; ", stderr);
}
@@ -4383,14 +4388,14 @@ dict_table_print_low(
}
}
-/**************************************************************************
+/**********************************************************************//**
Prints a column data. */
static
void
dict_col_print_low(
/*===============*/
- const dict_table_t* table, /* in: table */
- const dict_col_t* col) /* in: column */
+ const dict_table_t* table, /*!< in: table */
+ const dict_col_t* col) /*!< in: column */
{
dtype_t type;
@@ -4403,13 +4408,13 @@ dict_col_print_low(
dtype_print(&type);
}
-/**************************************************************************
+/**********************************************************************//**
Prints an index data. */
static
void
dict_index_print_low(
/*=================*/
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
ib_int64_t n_vals;
ulint i;
@@ -4463,13 +4468,13 @@ dict_index_print_low(
#endif /* UNIV_BTR_PRINT */
}
-/**************************************************************************
+/**********************************************************************//**
Prints a field data. */
static
void
dict_field_print_low(
/*=================*/
- dict_field_t* field) /* in: field */
+ dict_field_t* field) /*!< in: field */
{
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -4480,17 +4485,17 @@ dict_field_print_low(
}
}
-/**************************************************************************
+/**********************************************************************//**
Outputs info on a foreign key of a table in a format suitable for
CREATE TABLE. */
UNIV_INTERN
void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign, /* in: foreign key constraint */
- ibool add_newline) /* in: whether to add a newline */
+ FILE* file, /*!< in: file where to print */
+ trx_t* trx, /*!< in: transaction */
+ dict_foreign_t* foreign, /*!< in: foreign key constraint */
+ ibool add_newline) /*!< in: whether to add a newline */
{
const char* stripped_id;
ulint i;
@@ -4578,19 +4583,19 @@ dict_print_info_on_foreign_key_in_create_format(
}
}
-/**************************************************************************
+/**********************************************************************//**
Outputs info on foreign keys of a table. */
UNIV_INTERN
void
dict_print_info_on_foreign_keys(
/*============================*/
- ibool create_table_format, /* in: if TRUE then print in
+ ibool create_table_format, /*!< in: if TRUE then print in
a format suitable to be inserted into
a CREATE TABLE, otherwise in the format
of SHOW TABLE STATUS */
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_table_t* table) /* in: table */
+ FILE* file, /*!< in: file where to print */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table) /*!< in: table */
{
dict_foreign_t* foreign;
@@ -4668,31 +4673,87 @@ dict_print_info_on_foreign_keys(
mutex_exit(&(dict_sys->mutex));
}
-/************************************************************************
+/********************************************************************//**
Displays the names of the index and the table. */
UNIV_INTERN
void
dict_index_name_print(
/*==================*/
- FILE* file, /* in: output stream */
- trx_t* trx, /* in: transaction */
- const dict_index_t* index) /* in: index to print */
+ FILE* file, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index) /*!< in: index to print */
{
fputs("index ", file);
ut_print_name(file, trx, FALSE, index->name);
fputs(" of table ", file);
ut_print_name(file, trx, TRUE, index->table_name);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Get index by name */
+/**********************************************************************//**
+Inits dict_ind_redundant and dict_ind_compact. */
+UNIV_INTERN
+void
+dict_ind_init(void)
+/*===============*/
+{
+ dict_table_t* table;
+
+ /* create dummy table and index for REDUNDANT infimum and supremum */
+ table = dict_mem_table_create("SYS_DUMMY1", DICT_HDR_SPACE, 1, 0);
+ dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
+ DATA_ENGLISH | DATA_NOT_NULL, 8);
+
+ dict_ind_redundant = dict_mem_index_create("SYS_DUMMY1", "SYS_DUMMY1",
+ DICT_HDR_SPACE, 0, 1);
+ dict_index_add_col(dict_ind_redundant, table,
+ dict_table_get_nth_col(table, 0), 0);
+ dict_ind_redundant->table = table;
+ /* create dummy table and index for COMPACT infimum and supremum */
+ table = dict_mem_table_create("SYS_DUMMY2",
+ DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
+ dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
+ DATA_ENGLISH | DATA_NOT_NULL, 8);
+ dict_ind_compact = dict_mem_index_create("SYS_DUMMY2", "SYS_DUMMY2",
+ DICT_HDR_SPACE, 0, 1);
+ dict_index_add_col(dict_ind_compact, table,
+ dict_table_get_nth_col(table, 0), 0);
+ dict_ind_compact->table = table;
+
+ /* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
+ dict_ind_redundant->cached = dict_ind_compact->cached = TRUE;
+}
+
+/**********************************************************************//**
+Frees dict_ind_redundant and dict_ind_compact. */
+static
+void
+dict_ind_free(void)
+/*===============*/
+{
+ dict_table_t* table;
+
+ table = dict_ind_compact->table;
+ dict_mem_index_free(dict_ind_compact);
+ dict_ind_compact = NULL;
+ dict_mem_table_free(table);
+
+ table = dict_ind_redundant->table;
+ dict_mem_index_free(dict_ind_redundant);
+ dict_ind_redundant = NULL;
+ dict_mem_table_free(table);
+}
+
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Get index by name
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_table_get_index_on_name(
/*=========================*/
- /* out: index, NULL if does not exist */
- dict_table_t* table, /* in: table */
- const char* name) /* in: name of the index to find */
+ dict_table_t* table, /*!< in: table */
+ const char* name) /*!< in: name of the index to find */
{
dict_index_t* index;
@@ -4711,15 +4772,15 @@ dict_table_get_index_on_name(
}
-/**************************************************************************
+/**********************************************************************//**
Replace the index passed in with another equivalent index in the tables
foreign key list. */
UNIV_INTERN
void
dict_table_replace_index_in_foreign_list(
/*=====================================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index) /* in: index to be replaced */
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index) /*!< in: index to be replaced */
{
dict_foreign_t* foreign;
@@ -4737,16 +4798,16 @@ dict_table_replace_index_in_foreign_list(
}
}
-/**************************************************************************
+/**********************************************************************//**
In case there is more than one index with the same name return the index
-with the min(id). */
+with the min(id).
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_table_get_index_on_name_and_min_id(
/*=====================================*/
- /* out: index, NULL if does not exist */
- dict_table_t* table, /* in: table */
- const char* name) /* in: name of the index to find */
+ dict_table_t* table, /*!< in: table */
+ const char* name) /*!< in: name of the index to find */
{
dict_index_t* index;
dict_index_t* min_index; /* Index with matching name and min(id) */
@@ -4771,13 +4832,13 @@ dict_table_get_index_on_name_and_min_id(
}
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Check for duplicate index entries in a table [using the index name] */
UNIV_INTERN
void
dict_table_check_for_dup_indexes(
/*=============================*/
- const dict_table_t* table) /* in: Check for dup indexes
+ const dict_table_t* table) /*!< in: Check for dup indexes
in this table */
{
/* Check for duplicates, ignoring indexes that are marked
@@ -4808,3 +4869,55 @@ dict_table_check_for_dup_indexes(
}
}
#endif /* UNIV_DEBUG */
+
+/**************************************************************************
+Closes the data dictionary module. */
+UNIV_INTERN
+void
+dict_close(void)
+/*============*/
+{
+ ulint i;
+
+ /* Free the hash elements. We don't remove them from the table
+ because we are going to destroy the table anyway. */
+ for (i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) {
+ dict_table_t* table;
+
+ table = HASH_GET_FIRST(dict_sys->table_hash, i);
+
+ while (table) {
+ dict_table_t* prev_table = table;
+
+ table = HASH_GET_NEXT(name_hash, prev_table);
+#ifdef UNIV_DEBUG
+ ut_a(prev_table->magic_n == DICT_TABLE_MAGIC_N);
+#endif
+ /* Acquire only because it's a pre-condition. */
+ mutex_enter(&dict_sys->mutex);
+
+ dict_table_remove_from_cache(prev_table);
+
+ mutex_exit(&dict_sys->mutex);
+ }
+ }
+
+ hash_table_free(dict_sys->table_hash);
+
+ /* The elements are the same instance as in dict_sys->table_hash,
+ therefore we don't delete the individual elements. */
+ hash_table_free(dict_sys->table_id_hash);
+
+ dict_ind_free();
+
+ mutex_free(&dict_sys->mutex);
+
+ rw_lock_free(&dict_operation_lock);
+ memset(&dict_operation_lock, 0x0, sizeof(dict_operation_lock));
+
+ mutex_free(&dict_foreign_err_mutex);
+
+ mem_free(dict_sys);
+ dict_sys = NULL;
+}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/dict/dict0load.c b/storage/xtradb/dict/dict0load.c
index 0e3f3c04c1f..46cce5050cd 100644
--- a/storage/xtradb/dict/dict0load.c
+++ b/storage/xtradb/dict/dict0load.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file dict/dict0load.c
Loads to the memory cache database object definitions
from dictionary tables
@@ -24,9 +25,7 @@ Created 4/24/1996 Heikki Tuuri
*******************************************************/
#include "dict0load.h"
-#ifndef UNIV_HOTBACKUP
#include "mysql_version.h"
-#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_NONINL
#include "dict0load.ic"
@@ -42,17 +41,17 @@ Created 4/24/1996 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
-/********************************************************************
-Returns TRUE if index's i'th column's name is 'name' .*/
+/****************************************************************//**
+Compare the name of an index column.
+@return TRUE if the i'th column of index is 'name'. */
static
ibool
name_of_col_is(
/*===========*/
- /* out: */
- dict_table_t* table, /* in: table */
- dict_index_t* index, /* in: index */
- ulint i, /* in: */
- const char* name) /* in: name to compare to */
+ const dict_table_t* table, /*!< in: table */
+ const dict_index_t* index, /*!< in: index */
+ ulint i, /*!< in: index field offset */
+ const char* name) /*!< in: name to compare to */
{
ulint tmp = dict_col_get_no(dict_field_get_col(
dict_index_get_nth_field(
@@ -61,16 +60,15 @@ name_of_col_is(
return(strcmp(name, dict_table_get_col_name(table, tmp)) == 0);
}
-/************************************************************************
-Finds the first table name in the given database. */
+/********************************************************************//**
+Finds the first table name in the given database.
+@return own: table name, NULL if does not exist; the caller must free
+the memory in the string! */
UNIV_INTERN
char*
dict_get_first_table_name_in_db(
/*============================*/
- /* out, own: table name, NULL if
- does not exist; the caller must
- free the memory in the string! */
- const char* name) /* in: database name which ends in '/' */
+ const char* name) /*!< in: database name which ends in '/' */
{
dict_table_t* sys_tables;
btr_pcur_t pcur;
@@ -145,7 +143,7 @@ loop:
goto loop;
}
-/************************************************************************
+/********************************************************************//**
Prints to the standard output information on all tables found in the data
dictionary system table. */
UNIV_INTERN
@@ -238,16 +236,15 @@ loop:
goto loop;
}
-/************************************************************************
-Determine the flags of a table described in SYS_TABLES. */
+/********************************************************************//**
+Determine the flags of a table described in SYS_TABLES.
+@return compressed page size in kilobytes; or 0 if the tablespace is
+uncompressed, ULINT_UNDEFINED on error */
static
ulint
dict_sys_tables_get_flags(
/*======================*/
- /* out: compressed page size in kilobytes;
- or 0 if the tablespace is uncompressed,
- ULINT_UNDEFINED on error */
- const rec_t* rec) /* in: a record of SYS_TABLES */
+ const rec_t* rec) /*!< in: a record of SYS_TABLES */
{
const byte* field;
ulint len;
@@ -301,7 +298,7 @@ dict_sys_tables_get_flags(
return(flags);
}
-/************************************************************************
+/********************************************************************//**
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
to what we already read with fil_load_single_table_tablespaces().
@@ -313,7 +310,7 @@ UNIV_INTERN
void
dict_check_tablespaces_and_store_max_id(
/*====================================*/
- ibool in_crash_recovery) /* in: are we doing a crash recovery */
+ ibool in_crash_recovery) /*!< in: are we doing a crash recovery */
{
dict_table_t* sys_tables;
dict_index_t* sys_index;
@@ -423,14 +420,14 @@ loop:
goto loop;
}
-/************************************************************************
+/********************************************************************//**
Loads definitions for table columns. */
static
void
dict_load_columns(
/*==============*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_columns;
dict_index_t* sys_index;
@@ -529,14 +526,14 @@ dict_load_columns(
mtr_commit(&mtr);
}
-/************************************************************************
+/********************************************************************//**
Loads definitions for index fields. */
static
void
dict_load_fields(
/*=============*/
- dict_index_t* index, /* in: index whose fields to load */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
+ dict_index_t* index, /*!< in: index whose fields to load */
+ mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_fields;
dict_index_t* sys_index;
@@ -630,19 +627,17 @@ next_rec:
mtr_commit(&mtr);
}
-/************************************************************************
+/********************************************************************//**
Loads definitions for table indexes. Adds them to the data dictionary
-cache. */
+cache.
+@return DB_SUCCESS if ok, DB_CORRUPTION if corruption of dictionary
+table or DB_UNSUPPORTED if table has unknown index type */
static
ulint
dict_load_indexes(
/*==============*/
- /* out: DB_SUCCESS if ok, DB_CORRUPTION
- if corruption of dictionary table or
- DB_UNSUPPORTED if table has unknown index
- type */
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_indexes;
dict_index_t* sys_index;
@@ -805,22 +800,20 @@ func_exit:
return(error);
}
-/************************************************************************
+/********************************************************************//**
Loads a table definition and also all its index definitions, and also
the cluster definition if the table is a member in a cluster. Also loads
all foreign key constraints where the foreign key is in the table or where
a foreign key references columns in this table. Adds all these to the data
-dictionary cache. */
+dictionary cache.
+@return table, NULL if does not exist; if the table is stored in an
+.ibd file, but the file does not exist, then we set the
+ibd_file_missing flag TRUE in the table object we return */
UNIV_INTERN
dict_table_t*
dict_load_table(
/*============*/
- /* out: table, NULL if does not exist;
- if the table is stored in an .ibd file,
- but the file does not exist,
- then we set the ibd_file_missing flag TRUE
- in the table object we return */
- const char* name) /* in: table name in the
+ const char* name) /*!< in: table name in the
databasename/tablename format */
{
ibool ibd_file_missing = FALSE;
@@ -960,7 +953,7 @@ err_exit:
mem_heap_empty(heap);
err = dict_load_indexes(table, heap);
-#ifndef UNIV_HOTBACKUP
+
/* If the force recovery flag is set, we open the table irrespective
of the error condition, since the user may want to dump data from the
clustered index. However we load the foreign key information only if
@@ -971,7 +964,7 @@ err_exit:
dict_table_remove_from_cache(table);
table = NULL;
}
-# if 0
+#if 0
if (err != DB_SUCCESS && table != NULL) {
mutex_enter(&dict_foreign_err_mutex);
@@ -994,21 +987,20 @@ err_exit:
mutex_exit(&dict_foreign_err_mutex);
}
-# endif /* 0 */
-#endif /* !UNIV_HOTBACKUP */
+#endif /* 0 */
mem_heap_free(heap);
return(table);
}
-/***************************************************************************
-Loads a table object based on the table id. */
+/***********************************************************************//**
+Loads a table object based on the table id.
+@return table; NULL if table does not exist */
UNIV_INTERN
dict_table_t*
dict_load_table_on_id(
/*==================*/
- /* out: table; NULL if table does not exist */
- dulint table_id) /* in: table id */
+ dulint table_id) /*!< in: table id */
{
byte id_buf[8];
btr_pcur_t pcur;
@@ -1092,7 +1084,7 @@ dict_load_table_on_id(
return(table);
}
-/************************************************************************
+/********************************************************************//**
This function is called when the database is booted. Loads system table
index definitions except for the clustered index which is added to the
dictionary cache at booting before calling this function. */
@@ -1100,7 +1092,7 @@ UNIV_INTERN
void
dict_load_sys_table(
/*================*/
- dict_table_t* table) /* in: system table */
+ dict_table_t* table) /*!< in: system table */
{
mem_heap_t* heap;
@@ -1113,16 +1105,15 @@ dict_load_sys_table(
mem_heap_free(heap);
}
-#ifndef UNIV_HOTBACKUP
-/************************************************************************
+/********************************************************************//**
Loads foreign key constraint col names (also for the referenced table). */
static
void
dict_load_foreign_cols(
/*===================*/
- const char* id, /* in: foreign constraint id as a
+ const char* id, /*!< in: foreign constraint id as a
null-terminated string */
- dict_foreign_t* foreign)/* in: foreign constraint object */
+ dict_foreign_t* foreign)/*!< in: foreign constraint object */
{
dict_table_t* sys_foreign_cols;
dict_index_t* sys_index;
@@ -1186,17 +1177,17 @@ dict_load_foreign_cols(
mtr_commit(&mtr);
}
-/***************************************************************************
-Loads a foreign key constraint to the dictionary cache. */
+/***********************************************************************//**
+Loads a foreign key constraint to the dictionary cache.
+@return DB_SUCCESS or error code */
static
ulint
dict_load_foreign(
/*==============*/
- /* out: DB_SUCCESS or error code */
- const char* id, /* in: foreign constraint id as a
+ const char* id, /*!< in: foreign constraint id as a
null-terminated string */
ibool check_charsets)
- /* in: TRUE=check charset compatibility */
+ /*!< in: TRUE=check charset compatibility */
{
dict_foreign_t* foreign;
dict_table_t* sys_foreign;
@@ -1311,19 +1302,19 @@ dict_load_foreign(
return(dict_foreign_add_to_cache(foreign, check_charsets));
}
-/***************************************************************************
+/***********************************************************************//**
Loads foreign key constraints where the table is either the foreign key
holder or where the table is referenced by a foreign key. Adds these
constraints to the data dictionary. Note that we know that the dictionary
cache already contains all constraints where the other relevant table is
-already in the dictionary cache. */
+already in the dictionary cache.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_load_foreigns(
/*===============*/
- /* out: DB_SUCCESS or error code */
- const char* table_name, /* in: table name */
- ibool check_charsets) /* in: TRUE=check charset
+ const char* table_name, /*!< in: table name */
+ ibool check_charsets) /*!< in: TRUE=check charset
compatibility */
{
btr_pcur_t pcur;
@@ -1457,4 +1448,3 @@ load_next_index:
return(DB_SUCCESS);
}
-#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/dict/dict0mem.c b/storage/xtradb/dict/dict0mem.c
index 31c0c23f450..6458cbab92d 100644
--- a/storage/xtradb/dict/dict0mem.c
+++ b/storage/xtradb/dict/dict0mem.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file dict/dict0mem.c
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri
@@ -32,25 +33,27 @@ Created 1/8/1996 Heikki Tuuri
#include "data0type.h"
#include "mach0data.h"
#include "dict0dict.h"
-#include "lock0lock.h"
+#ifndef UNIV_HOTBACKUP
+# include "lock0lock.h"
+#endif /* !UNIV_HOTBACKUP */
-#define DICT_HEAP_SIZE 100 /* initial memory heap size when
+#define DICT_HEAP_SIZE 100 /*!< initial memory heap size when
creating a table or index object */
-/**************************************************************************
-Creates a table memory object. */
+/**********************************************************************//**
+Creates a table memory object.
+@return own: table object */
UNIV_INTERN
dict_table_t*
dict_mem_table_create(
/*==================*/
- /* out, own: table object */
- const char* name, /* in: table name */
- ulint space, /* in: space where the clustered index of
+ const char* name, /*!< in: table name */
+ ulint space, /*!< in: space where the clustered index of
the table is placed; this parameter is
ignored if the table is made a member of
a cluster */
- ulint n_cols, /* in: number of columns */
- ulint flags) /* in: table flags */
+ ulint n_cols, /*!< in: number of columns */
+ ulint flags) /*!< in: table flags */
{
dict_table_t* table;
mem_heap_t* heap;
@@ -72,6 +75,7 @@ dict_mem_table_create(
table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
* sizeof(dict_col_t));
+#ifndef UNIV_HOTBACKUP
table->autoinc_lock = mem_heap_alloc(heap, lock_get_size());
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
@@ -81,41 +85,42 @@ dict_mem_table_create(
/* The number of transactions that are either waiting on the
AUTOINC lock or have been granted the lock. */
table->n_waiting_or_granted_auto_inc_locks = 0;
+#endif /* !UNIV_HOTBACKUP */
-#ifdef UNIV_DEBUG
- table->magic_n = DICT_TABLE_MAGIC_N;
-#endif /* UNIV_DEBUG */
+ ut_d(table->magic_n = DICT_TABLE_MAGIC_N);
return(table);
}
-/********************************************************************
+/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
void
dict_mem_table_free(
/*================*/
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_d(table->cached = FALSE);
+#ifndef UNIV_HOTBACKUP
mutex_free(&(table->autoinc_mutex));
+#endif /* UNIV_HOTBACKUP */
mem_heap_free(table->heap);
}
-/********************************************************************
-Append 'name' to 'col_names' (@see dict_table_t::col_names). */
+/****************************************************************//**
+Append 'name' to 'col_names'. @see dict_table_t::col_names
+@return new column names array */
static
const char*
dict_add_col_name(
/*==============*/
- /* out: new column names array */
- const char* col_names, /* in: existing column names, or
+ const char* col_names, /*!< in: existing column names, or
NULL */
- ulint cols, /* in: number of existing columns */
- const char* name, /* in: new column name */
- mem_heap_t* heap) /* in: heap */
+ ulint cols, /*!< in: number of existing columns */
+ const char* name, /*!< in: new column name */
+ mem_heap_t* heap) /*!< in: heap */
{
ulint old_len;
ulint new_len;
@@ -152,22 +157,24 @@ dict_add_col_name(
return(res);
}
-/**************************************************************************
+/**********************************************************************//**
Adds a column definition to a table. */
UNIV_INTERN
void
dict_mem_table_add_col(
/*===================*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap, /* in: temporary memory heap, or NULL */
- const char* name, /* in: column name, or NULL */
- ulint mtype, /* in: main datatype */
- ulint prtype, /* in: precise type */
- ulint len) /* in: precision */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap, /*!< in: temporary memory heap, or NULL */
+ const char* name, /*!< in: column name, or NULL */
+ ulint mtype, /*!< in: main datatype */
+ ulint prtype, /*!< in: precise type */
+ ulint len) /*!< in: precision */
{
dict_col_t* col;
+#ifndef UNIV_HOTBACKUP
ulint mbminlen;
ulint mbmaxlen;
+#endif /* !UNIV_HOTBACKUP */
ulint i;
ut_ad(table);
@@ -199,27 +206,29 @@ dict_mem_table_add_col(
col->prtype = (unsigned int) prtype;
col->len = (unsigned int) len;
+#ifndef UNIV_HOTBACKUP
dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
col->mbminlen = (unsigned int) mbminlen;
col->mbmaxlen = (unsigned int) mbmaxlen;
+#endif /* !UNIV_HOTBACKUP */
}
-/**************************************************************************
-Creates an index memory object. */
+/**********************************************************************//**
+Creates an index memory object.
+@return own: index object */
UNIV_INTERN
dict_index_t*
dict_mem_index_create(
/*==================*/
- /* out, own: index object */
- const char* table_name, /* in: table name */
- const char* index_name, /* in: index name */
- ulint space, /* in: space where the index tree is
+ const char* table_name, /*!< in: table name */
+ const char* index_name, /*!< in: index name */
+ ulint space, /*!< in: space where the index tree is
placed, ignored if the index is of
the clustered type */
- ulint type, /* in: DICT_UNIQUE,
+ ulint type, /*!< in: DICT_UNIQUE,
DICT_CLUSTERED, ... ORed */
- ulint n_fields) /* in: number of fields */
+ ulint n_fields) /*!< in: number of fields */
{
dict_index_t* index;
mem_heap_t* heap;
@@ -232,7 +241,9 @@ dict_mem_index_create(
index->heap = heap;
index->type = type;
+#ifndef UNIV_HOTBACKUP
index->space = (unsigned int) space;
+#endif /* !UNIV_HOTBACKUP */
index->name = mem_heap_strdup(heap, index_name);
index->table_name = table_name;
index->n_fields = (unsigned int) n_fields;
@@ -246,13 +257,13 @@ dict_mem_index_create(
return(index);
}
-/**************************************************************************
-Creates and initializes a foreign constraint memory object. */
+/**********************************************************************//**
+Creates and initializes a foreign constraint memory object.
+@return own: foreign constraint struct */
UNIV_INTERN
dict_foreign_t*
dict_mem_foreign_create(void)
/*=========================*/
- /* out, own: foreign constraint struct */
{
dict_foreign_t* foreign;
mem_heap_t* heap;
@@ -266,7 +277,7 @@ dict_mem_foreign_create(void)
return(foreign);
}
-/**************************************************************************
+/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
by the column name may be released only after publishing the index. */
@@ -274,9 +285,9 @@ UNIV_INTERN
void
dict_mem_index_add_field(
/*=====================*/
- dict_index_t* index, /* in: index */
- const char* name, /* in: column name */
- ulint prefix_len) /* in: 0 or the column prefix length
+ dict_index_t* index, /*!< in: index */
+ const char* name, /*!< in: column name */
+ ulint prefix_len) /*!< in: 0 or the column prefix length
in a MySQL index like
INDEX (textcol(25)) */
{
@@ -293,13 +304,13 @@ dict_mem_index_add_field(
field->prefix_len = (unsigned int) prefix_len;
}
-/**************************************************************************
+/**********************************************************************//**
Frees an index memory object. */
UNIV_INTERN
void
dict_mem_index_free(
/*================*/
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
diff --git a/storage/xtradb/dyn/dyn0dyn.c b/storage/xtradb/dyn/dyn0dyn.c
index 16e82eaed66..e1275f040f3 100644
--- a/storage/xtradb/dyn/dyn0dyn.c
+++ b/storage/xtradb/dyn/dyn0dyn.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file dyn/dyn0dyn.c
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
@@ -27,14 +28,14 @@ Created 2/5/1996 Heikki Tuuri
#include "dyn0dyn.ic"
#endif
-/****************************************************************
-Adds a new block to a dyn array. */
+/************************************************************//**
+Adds a new block to a dyn array.
+@return created block */
UNIV_INTERN
dyn_block_t*
dyn_array_add_block(
/*================*/
- /* out: created block */
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
mem_heap_t* heap;
dyn_block_t* block;
diff --git a/storage/xtradb/eval/eval0eval.c b/storage/xtradb/eval/eval0eval.c
index a2590c63c38..589b0fa1576 100644
--- a/storage/xtradb/eval/eval0eval.c
+++ b/storage/xtradb/eval/eval0eval.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file eval/eval0eval.c
SQL evaluator: evaluates simple data structures, like expressions, in
a query graph
@@ -32,29 +33,29 @@ Created 12/29/1997 Heikki Tuuri
#include "data0data.h"
#include "row0sel.h"
-/* The RND function seed */
+/** The RND function seed */
static ulint eval_rnd = 128367121;
-/* Dummy adress used when we should allocate a buffer of size 0 in
-the function below */
+/** Dummy adress used when we should allocate a buffer of size 0 in
+eval_node_alloc_val_buf */
static byte eval_dummy;
-/*********************************************************************
+/*****************************************************************//**
Allocate a buffer from global dynamic memory for a value of a que_node.
NOTE that this memory must be explicitly freed when the query graph is
freed. If the node already has an allocated buffer, that buffer is freed
here. NOTE that this is the only function where dynamic memory should be
-allocated for a query node val field. */
+allocated for a query node val field.
+@return pointer to allocated buffer */
UNIV_INTERN
byte*
eval_node_alloc_val_buf(
/*====================*/
- /* out: pointer to allocated buffer */
- que_node_t* node, /* in: query graph node; sets the val field
+ que_node_t* node, /*!< in: query graph node; sets the val field
data field to point to the new buffer, and
len field equal to size */
- ulint size) /* in: buffer size */
+ ulint size) /*!< in: buffer size */
{
dfield_t* dfield;
byte* data;
@@ -83,7 +84,7 @@ eval_node_alloc_val_buf(
return(data);
}
-/*********************************************************************
+/*****************************************************************//**
Free the buffer from global dynamic memory for a value of a que_node,
if it has been allocated in the above function. The freeing for pushed
column values is done in sel_col_prefetch_buf_free. */
@@ -91,7 +92,7 @@ UNIV_INTERN
void
eval_node_free_val_buf(
/*===================*/
- que_node_t* node) /* in: query graph node */
+ que_node_t* node) /*!< in: query graph node */
{
dfield_t* dfield;
byte* data;
@@ -110,14 +111,14 @@ eval_node_free_val_buf(
}
}
-/*********************************************************************
-Evaluates a comparison node. */
+/*****************************************************************//**
+Evaluates a comparison node.
+@return the result of the comparison */
UNIV_INTERN
ibool
eval_cmp(
/*=====*/
- /* out: the result of the comparison */
- func_node_t* cmp_node) /* in: comparison node */
+ func_node_t* cmp_node) /*!< in: comparison node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -169,13 +170,13 @@ eval_cmp(
return(val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a logical operation node. */
UNIV_INLINE
void
eval_logical(
/*=========*/
- func_node_t* logical_node) /* in: logical operation node */
+ func_node_t* logical_node) /*!< in: logical operation node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -210,13 +211,13 @@ eval_logical(
eval_node_set_ibool_val(logical_node, val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates an arithmetic operation node. */
UNIV_INLINE
void
eval_arith(
/*=======*/
- func_node_t* arith_node) /* in: arithmetic operation node */
+ func_node_t* arith_node) /*!< in: arithmetic operation node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -254,13 +255,13 @@ eval_arith(
eval_node_set_int_val(arith_node, val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates an aggregate operation node. */
UNIV_INLINE
void
eval_aggregate(
/*===========*/
- func_node_t* node) /* in: aggregate operation node */
+ func_node_t* node) /*!< in: aggregate operation node */
{
que_node_t* arg;
lint val;
@@ -288,14 +289,14 @@ eval_aggregate(
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 */
+ func_node_t* func_node) /*!< in: predefined function node */
{
que_node_t* arg;
que_node_t* arg1;
@@ -375,13 +376,13 @@ eval_predefined_2(
}
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a notfound-function node. */
UNIV_INLINE
void
eval_notfound(
/*==========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -417,13 +418,13 @@ eval_notfound(
eval_node_set_ibool_val(func_node, ibool_val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a substr-function node. */
UNIV_INLINE
void
eval_substr(
/*========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -450,13 +451,13 @@ eval_substr(
dfield_set_data(dfield, str1 + len1, len2);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a replstr-procedure node. */
static
void
eval_replstr(
/*=========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -490,13 +491,13 @@ eval_replstr(
ut_memcpy(str1 + len1, str2, len2);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates an instr-function node. */
static
void
eval_instr(
/*=======*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -562,13 +563,13 @@ match_found:
eval_node_set_int_val(func_node, int_val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node. */
UNIV_INLINE
void
eval_binary_to_number(
/*==================*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
dfield_t* dfield;
@@ -600,13 +601,13 @@ eval_binary_to_number(
eval_node_copy_and_alloc_val(func_node, str2, 4);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node. */
static
void
eval_concat(
/*========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg;
dfield_t* dfield;
@@ -642,7 +643,7 @@ eval_concat(
}
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node. If the first argument is an integer,
this function looks at the second argument which is the integer length in
bytes, and converts the integer to a VARCHAR.
@@ -652,7 +653,7 @@ UNIV_INLINE
void
eval_to_binary(
/*===========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -690,13 +691,13 @@ eval_to_binary(
dfield_set_data(dfield, str1 + (4 - len1), len1);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node. */
UNIV_INLINE
void
eval_predefined(
/*============*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
lint int_val;
@@ -782,13 +783,13 @@ eval_predefined(
eval_node_set_int_val(func_node, int_val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a function node. */
UNIV_INTERN
void
eval_func(
/*======*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg;
ulint class;
diff --git a/storage/xtradb/eval/eval0proc.c b/storage/xtradb/eval/eval0proc.c
index 9c7563e8c7d..3a4218d92bf 100644
--- a/storage/xtradb/eval/eval0proc.c
+++ b/storage/xtradb/eval/eval0proc.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file eval/eval0proc.c
Executes SQL stored procedures and their control structures
Created 1/20/1998 Heikki Tuuri
@@ -28,14 +29,14 @@ Created 1/20/1998 Heikki Tuuri
#include "eval0proc.ic"
#endif
-/**************************************************************************
-Performs an execution step of an if-statement node. */
+/**********************************************************************//**
+Performs an execution step of an if-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
if_step(
/*====*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
if_node_t* node;
elsif_node_t* elsif_node;
@@ -104,14 +105,14 @@ if_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of a while-statement node. */
+/**********************************************************************//**
+Performs an execution step of a while-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
while_step(
/*=======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
while_node_t* node;
@@ -140,14 +141,14 @@ while_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of an assignment statement node. */
+/**********************************************************************//**
+Performs an execution step of an assignment statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
assign_step(
/*========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
assign_node_t* node;
@@ -167,14 +168,14 @@ assign_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of a for-loop node. */
+/**********************************************************************//**
+Performs an execution step of a for-loop node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
for_step(
/*=====*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
for_node_t* node;
que_node_t* parent;
@@ -229,14 +230,14 @@ for_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of an exit statement node. */
+/**********************************************************************//**
+Performs an execution step of an exit statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
exit_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
exit_node_t* node;
que_node_t* loop_node;
@@ -261,14 +262,14 @@ exit_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of a return-statement node. */
+/**********************************************************************//**
+Performs an execution step of a return-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
return_step(
/*========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
return_node_t* node;
que_node_t* parent;
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index c60136e27c0..b6eed68fc7f 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file fil/fil0fil.c
The tablespace memory cache
Created 10/25/1995 Heikki Tuuri
@@ -25,15 +26,11 @@ Created 10/25/1995 Heikki Tuuri
#include "fil0fil.h"
#include "mem0mem.h"
-#include "sync0sync.h"
#include "hash0hash.h"
#include "os0file.h"
-#include "os0sync.h"
#include "mach0data.h"
-#include "ibuf0ibuf.h"
#include "buf0buf.h"
#include "buf0flu.h"
-#include "buf0lru.h"
#include "log0recv.h"
#include "fsp0fsp.h"
#include "srv0srv.h"
@@ -48,7 +45,14 @@ Created 10/25/1995 Heikki Tuuri
#include "row0row.h"
#include "row0mysql.h"
#include "que0que.h"
-
+#ifndef UNIV_HOTBACKUP
+# include "buf0lru.h"
+# include "ibuf0ibuf.h"
+# include "sync0sync.h"
+# include "os0sync.h"
+#else /* !UNIV_HOTBACKUP */
+static ulint srv_data_read, srv_data_written;
+#endif /* !UNIV_HOTBACKUP */
/*
IMPLEMENTATION OF THE TABLESPACE MEMORY CACHE
@@ -106,131 +110,144 @@ out of the LRU-list and keep a count of pending operations. When an operation
completes, we decrement the count and return the file node to the LRU-list if
the count drops to zero. */
-/* When mysqld is run, the default directory "." is the mysqld datadir,
+/** When mysqld is run, the default directory "." is the mysqld datadir,
but in the MySQL Embedded Server Library and ibbackup it is not the default
directory, and we must set the base file path explicitly */
UNIV_INTERN const char* fil_path_to_mysql_datadir = ".";
-/* The number of fsyncs done to the log */
+/** The number of fsyncs done to the log */
UNIV_INTERN ulint fil_n_log_flushes = 0;
+/** Number of pending redo log flushes */
UNIV_INTERN ulint fil_n_pending_log_flushes = 0;
+/** Number of pending tablespace flushes */
UNIV_INTERN ulint fil_n_pending_tablespace_flushes = 0;
-/* Null file address */
+/** The null file address */
UNIV_INTERN fil_addr_t fil_addr_null = {FIL_NULL, 0};
-/* File node of a tablespace or the log data space */
+/** File node of a tablespace or the log data space */
struct fil_node_struct {
- fil_space_t* space; /* backpointer to the space where this node
+ fil_space_t* space; /*!< backpointer to the space where this node
belongs */
- char* name; /* path to the file */
- ibool open; /* TRUE if file open */
- os_file_t handle; /* OS handle to the file, if file open */
- ibool is_raw_disk;/* TRUE if the 'file' is actually a raw
+ char* name; /*!< path to the file */
+ ibool open; /*!< TRUE if file open */
+ os_file_t handle; /*!< OS handle to the file, if file open */
+ ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
device or a raw disk partition */
- ulint size; /* size of the file in database pages, 0 if
+ ulint size; /*!< size of the file in database pages, 0 if
not known yet; the possible last incomplete
megabyte may be ignored if space == 0 */
ulint n_pending;
- /* count of pending i/o's on this file;
+ /*!< count of pending i/o's on this file;
closing of the file is not allowed if
this is > 0 */
ulint n_pending_flushes;
- /* count of pending flushes on this file;
+ /*!< count of pending flushes on this file;
closing of the file is not allowed if
this is > 0 */
- ib_int64_t modification_counter;/* when we write to the file we
+ ib_int64_t modification_counter;/*!< when we write to the file we
increment this by one */
- ib_int64_t flush_counter;/* up to what modification_counter value
- we have flushed the modifications to disk */
+ ib_int64_t flush_counter;/*!< up to what
+ modification_counter value we have
+ flushed the modifications to disk */
UT_LIST_NODE_T(fil_node_t) chain;
- /* link field for the file chain */
+ /*!< link field for the file chain */
UT_LIST_NODE_T(fil_node_t) LRU;
- /* link field for the LRU list */
- ulint magic_n;
+ /*!< link field for the LRU list */
+ ulint magic_n;/*!< FIL_NODE_MAGIC_N */
};
+/** Value of fil_node_struct::magic_n */
#define FIL_NODE_MAGIC_N 89389
-/* Tablespace or log data space: let us call them by a common name space */
+/** Tablespace or log data space: let us call them by a common name space */
struct fil_space_struct {
- char* name; /* space name = the path to the first file in
+ char* name; /*!< space name = the path to the first file in
it */
- ulint id; /* space id */
+ ulint id; /*!< space id */
ib_int64_t tablespace_version;
- /* in DISCARD/IMPORT this timestamp is used to
- check if we should ignore an insert buffer
- merge request for a page because it actually
- was for the previous incarnation of the
- space */
- ibool mark; /* this is set to TRUE at database startup if
+ /*!< in DISCARD/IMPORT this timestamp
+ is used to check if we should ignore
+ an insert buffer merge request for a
+ page because it actually was for the
+ previous incarnation of the space */
+ ibool mark; /*!< this is set to TRUE at database startup if
the space corresponds to a table in the InnoDB
data dictionary; so we can print a warning of
orphaned tablespaces */
- ibool stop_ios;/* TRUE if we want to rename the .ibd file of
- tablespace and want to stop temporarily
- posting of new i/o requests on the file */
+ ibool stop_ios;/*!< TRUE if we want to rename the
+ .ibd file of tablespace and want to
+ stop temporarily posting of new i/o
+ requests on the file */
ibool stop_ibuf_merges;
- /* we set this TRUE when we start deleting a
- single-table tablespace */
+ /*!< we set this TRUE when we start
+ deleting a single-table tablespace */
ibool is_being_deleted;
- /* this is set to TRUE when we start
+ /*!< this is set to TRUE when we start
deleting a single-table tablespace and its
file; when this flag is set no further i/o
or flush requests can be placed on this space,
though there may be such requests still being
processed on this space */
- ulint purpose;/* FIL_TABLESPACE, FIL_LOG, or FIL_ARCH_LOG */
+ ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
+ FIL_ARCH_LOG */
UT_LIST_BASE_NODE_T(fil_node_t) chain;
- /* base node for the file chain */
- ulint size; /* space size in pages; 0 if a single-table
+ /*!< base node for the file chain */
+ ulint size; /*!< space size in pages; 0 if a single-table
tablespace whose size we do not know yet;
last incomplete megabytes in data files may be
ignored if space == 0 */
- ulint flags; /* in: compressed page size
- and file format, or 0 */
+ ulint flags; /*!< compressed page size and file format, or 0 */
ulint n_reserved_extents;
- /* number of reserved free extents for
+ /*!< number of reserved free extents for
ongoing operations like B-tree page split */
- ulint n_pending_flushes; /* this is > 0 when flushing
+ ulint n_pending_flushes; /*!< this is positive when flushing
the tablespace to disk; dropping of the
- tablespace is forbidden if this is > 0 */
- ulint n_pending_ibuf_merges;/* this is > 0 when merging
- insert buffer entries to a page so that we
- may need to access the ibuf bitmap page in the
- tablespade: dropping of the tablespace is
- forbidden if this is > 0 */
- hash_node_t hash; /* hash chain node */
- hash_node_t name_hash;/* hash chain the name_hash table */
- rw_lock_t latch; /* latch protecting the file space storage
+ tablespace is forbidden if this is positive */
+ ulint n_pending_ibuf_merges;/*!< this is positive
+ when merging insert buffer entries to
+ a page so that we may need to access
+ the ibuf bitmap page in the
+ tablespade: dropping of the tablespace
+ is forbidden if this is positive */
+ hash_node_t hash; /*!< hash chain node */
+ hash_node_t name_hash;/*!< hash chain the name_hash table */
+#ifndef UNIV_HOTBACKUP
+ rw_lock_t latch; /*!< latch protecting the file space storage
allocation */
+#endif /* !UNIV_HOTBACKUP */
UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
- /* list of spaces with at least one unflushed
+ /*!< list of spaces with at least one unflushed
file we have written to */
- ibool is_in_unflushed_spaces; /* TRUE if this space is
- currently in the list above */
+ ibool is_in_unflushed_spaces; /*!< TRUE if this space is
+ currently in unflushed_spaces */
UT_LIST_NODE_T(fil_space_t) space_list;
- /* list of all spaces */
- ulint magic_n;
+ /*!< list of all spaces */
+ ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
};
+/** Value of fil_space_struct::magic_n */
#define FIL_SPACE_MAGIC_N 89472
-/* The tablespace memory cache; also the totality of logs = the log data space,
-is stored here; below we talk about tablespaces, but also the ib_logfiles
-form a 'space' and it is handled here */
-
+/** The tablespace memory cache */
typedef struct fil_system_struct fil_system_t;
+
+/** The tablespace memory cache; also the totality of logs (the log
+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_struct {
- mutex_t mutex; /* The mutex protecting the cache */
- hash_table_t* spaces; /* The hash table of spaces in the
+#ifndef UNIV_HOTBACKUP
+ mutex_t mutex; /*!< The mutex protecting the cache */
+#endif /* !UNIV_HOTBACKUP */
+ hash_table_t* spaces; /*!< The hash table of spaces in the
system; they are hashed on the space
id */
- hash_table_t* name_hash; /* hash table based on the space
+ hash_table_t* name_hash; /*!< hash table based on the space
name */
UT_LIST_BASE_NODE_T(fil_node_t) LRU;
- /* base node for the LRU list of the
+ /*!< base node for the LRU list of the
most recently used open files with no
pending i/o's; if we start an i/o on
the file, we first remove it from this
@@ -241,24 +258,24 @@ struct fil_system_struct {
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
+ /*!< base node for the list of those
tablespaces whose files contain
unflushed writes; those spaces have
at least one file node where
modification_counter > flush_counter */
- ulint n_open; /* number of files currently open */
- ulint max_n_open; /* n_open is not allowed to exceed
+ ulint n_open; /*!< number of files currently open */
+ ulint max_n_open; /*!< n_open is not allowed to exceed
this */
- ib_int64_t modification_counter;/* when we write to a file we
+ ib_int64_t modification_counter;/*!< when we write to a file we
increment this by one */
- ulint max_assigned_id;/* maximum space id in the existing
+ ulint max_assigned_id;/*!< maximum space id in the existing
tables, or assigned during the time
mysqld has been up; at an InnoDB
startup we scan the data dictionary
and set here the maximum of the
space id's of the tables there */
ib_int64_t tablespace_version;
- /* a counter which is incremented for
+ /*!< a counter which is incremented for
every space object memory creation;
every space mem object gets a
'timestamp' from this; in DISCARD/
@@ -266,15 +283,15 @@ struct fil_system_struct {
should ignore an insert buffer merge
request */
UT_LIST_BASE_NODE_T(fil_space_t) space_list;
- /* list of all file spaces */
+ /*!< list of all file spaces */
};
-/* The tablespace memory cache. This variable is NULL before the module is
+/** The tablespace memory cache. This variable is NULL before the module is
initialized. */
-UNIV_INTERN fil_system_t* fil_system = NULL;
+static fil_system_t* fil_system = NULL;
-/************************************************************************
+/********************************************************************//**
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
Prepares a file node for i/o. Opens the file if it is closed. Updates the
@@ -285,99 +302,107 @@ static
void
fil_node_prepare_for_io(
/*====================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- fil_space_t* space); /* in: space */
-/************************************************************************
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ fil_space_t* space); /*!< in: space */
+/********************************************************************//**
Updates the data structures when an i/o operation finishes. Updates the
pending i/o's field in the node appropriately. */
static
void
fil_node_complete_io(
/*=================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- ulint type); /* in: OS_FILE_WRITE or OS_FILE_READ; marks
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ ulint type); /*!< in: OS_FILE_WRITE or OS_FILE_READ; marks
the node as modified if
type == OS_FILE_WRITE */
-/***********************************************************************
+/*******************************************************************//**
Checks if a single-table tablespace for a given table name exists in the
-tablespace memory cache. */
+tablespace memory cache.
+@return space id, ULINT_UNDEFINED if not found */
static
ulint
fil_get_space_id_for_table(
/*=======================*/
- /* out: space id, ULINT_UNDEFINED if not
- found */
- const char* name); /* in: table name in the standard
+ const char* name); /*!< in: table name in the standard
'databasename/tablename' format */
-/************************************************************************
+/*******************************************************************//**
+Frees a space object from the tablespace memory cache. Closes the files in
+the chain but does not delete them. There must not be any pending i/o's or
+flushes on the files. */
+static
+ibool
+fil_space_free(
+/*===========*/
+ /* out: TRUE if success */
+ ulint id, /* in: space id */
+ ibool own_mutex);/* in: TRUE if own system->mutex */
+/********************************************************************//**
Reads data from a space to a buffer. Remember that the possible incomplete
blocks at the end of file are ignored: they are not taken into account when
-calculating the byte offset within a space. */
+calculating the byte offset within a space.
+@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
+i/o on a tablespace which does not exist */
UNIV_INLINE
ulint
fil_read(
/*=====*/
- /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
- if we are trying to do i/o on a tablespace
- which does not exist */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes;
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint block_offset, /* in: offset in number of blocks */
- ulint byte_offset, /* in: remainder of offset in bytes; in aio
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in aio
this must be divisible by the OS block size */
- ulint len, /* in: how many bytes to read; this must not
+ ulint len, /*!< in: how many bytes to read; this must not
cross a file boundary; in aio this must be a
block size multiple */
- void* buf, /* in/out: buffer where to store data read;
+ void* buf, /*!< in/out: buffer where to store data read;
in aio this must be appropriately aligned */
- void* message) /* in: message for aio handler if non-sync
+ void* message) /*!< in: message for aio handler if non-sync
aio used, else ignored */
{
return(fil_io(OS_FILE_READ, sync, space_id, zip_size, block_offset,
byte_offset, len, buf, message));
}
-/************************************************************************
+/********************************************************************//**
Writes data to a space from a buffer. Remember that the possible incomplete
blocks at the end of file are ignored: they are not taken into account when
-calculating the byte offset within a space. */
+calculating the byte offset within a space.
+@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
+i/o on a tablespace which does not exist */
UNIV_INLINE
ulint
fil_write(
/*======*/
- /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
- if we are trying to do i/o on a tablespace
- which does not exist */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes;
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint block_offset, /* in: offset in number of blocks */
- ulint byte_offset, /* in: remainder of offset in bytes; in aio
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in aio
this must be divisible by the OS block size */
- ulint len, /* in: how many bytes to write; this must
+ ulint len, /*!< in: how many bytes to write; this must
not cross a file boundary; in aio this must
be a block size multiple */
- void* buf, /* in: buffer from which to write; in aio
+ void* buf, /*!< in: buffer from which to write; in aio
this must be appropriately aligned */
- void* message) /* in: message for aio handler if non-sync
+ void* message) /*!< in: message for aio handler if non-sync
aio used, else ignored */
{
return(fil_io(OS_FILE_WRITE, sync, space_id, zip_size, block_offset,
byte_offset, len, buf, message));
}
-/***********************************************************************
+/*******************************************************************//**
Returns the table space by a given id, NULL if not found. */
UNIV_INLINE
fil_space_t*
fil_space_get_by_id(
/*================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
fil_space_t* space;
@@ -391,13 +416,13 @@ fil_space_get_by_id(
return(space);
}
-/***********************************************************************
+/*******************************************************************//**
Returns the table space by a given name, NULL if not found. */
UNIV_INLINE
fil_space_t*
fil_space_get_by_name(
/*==================*/
- const char* name) /* in: space name */
+ const char* name) /*!< in: space name */
{
fil_space_t* space;
ulint fold;
@@ -414,23 +439,23 @@ fil_space_get_by_name(
return(space);
}
-/***********************************************************************
-Returns the version number of a tablespace, -1 if not found. */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Returns the version number of a tablespace, -1 if not found.
+@return version number, -1 if the tablespace does not exist in the
+memory cache */
UNIV_INTERN
ib_int64_t
fil_space_get_version(
/*==================*/
- /* out: version number, -1 if the tablespace does not
- exist in the memory cache */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ib_int64_t version = -1;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -438,27 +463,26 @@ fil_space_get_version(
version = space->tablespace_version;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(version);
}
-/***********************************************************************
-Returns the latch of a file space. */
+/*******************************************************************//**
+Returns the latch of a file space.
+@return latch protecting storage allocation */
UNIV_INTERN
rw_lock_t*
fil_space_get_latch(
/*================*/
- /* out: latch protecting storage allocation */
- ulint id, /* in: space id */
- ulint* flags) /* out: tablespace flags */
+ ulint id, /*!< in: space id */
+ ulint* flags) /*!< out: tablespace flags */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -468,49 +492,49 @@ fil_space_get_latch(
*flags = space->flags;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(&(space->latch));
}
-/***********************************************************************
-Returns the type of a file space. */
+/*******************************************************************//**
+Returns the type of a file space.
+@return FIL_TABLESPACE or FIL_LOG */
UNIV_INTERN
ulint
fil_space_get_type(
/*===============*/
- /* out: FIL_TABLESPACE or FIL_LOG */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
ut_a(space);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(space->purpose);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Checks if all the file nodes in a space are flushed. The caller must hold
-the fil_system mutex. */
+the fil_system mutex.
+@return TRUE if all are flushed */
static
ibool
fil_space_is_flushed(
/*=================*/
- /* out: TRUE if all are flushed */
- fil_space_t* space) /* in: space */
+ fil_space_t* space) /*!< in: space */
{
fil_node_t* node;
- ut_ad(mutex_own(&(fil_system->mutex)));
+ ut_ad(mutex_own(&fil_system->mutex));
node = UT_LIST_GET_FIRST(space->chain);
@@ -526,27 +550,26 @@ fil_space_is_flushed(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Appends a new file to the chain of files of a space. File must be closed. */
UNIV_INTERN
void
fil_node_create(
/*============*/
- const char* name, /* in: file name (file must be closed) */
- ulint size, /* in: file size in database blocks, rounded
+ const char* name, /*!< in: file name (file must be closed) */
+ ulint size, /*!< in: file size in database blocks, rounded
downwards to an integer */
- ulint id, /* in: space id where to append */
- ibool is_raw) /* in: TRUE if a raw device or
+ ulint id, /*!< in: space id where to append */
+ ibool is_raw) /*!< in: TRUE if a raw device or
a raw disk partition */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
- ut_a(system);
+ ut_a(fil_system);
ut_a(name);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
node = mem_alloc(sizeof(fil_node_t));
@@ -577,7 +600,7 @@ fil_node_create(
mem_free(node);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return;
}
@@ -588,31 +611,34 @@ fil_node_create(
UT_LIST_ADD_LAST(chain, space->chain, node);
- mutex_exit(&(system->mutex));
+ if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
+
+ fil_system->max_assigned_id = id;
+ }
+
+ mutex_exit(&fil_system->mutex);
}
-/************************************************************************
+/********************************************************************//**
Opens a the file of a node of a tablespace. The caller must own the fil_system
mutex. */
static
void
fil_node_open_file(
/*===============*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- fil_space_t* space) /* in: space */
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ fil_space_t* space) /*!< in: space */
{
ib_int64_t size_bytes;
ulint size_low;
ulint size_high;
ibool ret;
ibool success;
-#ifndef UNIV_HOTBACKUP
byte* buf2;
byte* page;
ulint space_id;
ulint flags;
-#endif /* !UNIV_HOTBACKUP */
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->n_pending == 0);
@@ -648,9 +674,12 @@ fil_node_open_file(
size_bytes = (((ib_int64_t)size_high) << 32)
+ (ib_int64_t)size_low;
#ifdef UNIV_HOTBACKUP
- node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
- /* TODO: adjust to zip_size, like below? */
-#else
+ if (space->id == 0) {
+ node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
+ os_file_close(node->handle);
+ goto add_size;
+ }
+#endif /* UNIV_HOTBACKUP */
ut_a(space->purpose != FIL_LOG);
ut_a(space->id != 0);
@@ -729,7 +758,10 @@ fil_node_open_file(
(size_bytes
/ dict_table_flags_to_zip_size(flags));
}
-#endif
+
+#ifdef UNIV_HOTBACKUP
+add_size:
+#endif /* UNIV_HOTBACKUP */
space->size += node->size;
}
@@ -763,14 +795,14 @@ fil_node_open_file(
}
}
-/**************************************************************************
+/**********************************************************************//**
Closes a file. */
static
void
fil_node_close_file(
/*================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system) /* in: tablespace memory cache */
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system) /*!< in: tablespace memory cache */
{
ibool ret;
@@ -798,41 +830,38 @@ fil_node_close_file(
}
}
-/************************************************************************
+/********************************************************************//**
Tries to close a file in the LRU list. The caller must hold the fil_sys
-mutex. */
+mutex.
+@return TRUE if success, FALSE if should retry later; since i/o's
+generally complete in < 100 ms, and as InnoDB writes at most 128 pages
+from the buffer pool in a batch, and then immediately flushes the
+files, there is a good chance that the next time we find a suitable
+node from the LRU list */
static
ibool
fil_try_to_close_file_in_LRU(
/*=========================*/
- /* out: TRUE if success, FALSE if should retry
- later; since i/o's generally complete in <
- 100 ms, and as InnoDB writes at most 128 pages
- from the buffer pool in a batch, and then
- immediately flushes the files, there is a good
- chance that the next time we find a suitable
- node from the LRU list */
- ibool print_info) /* in: if TRUE, prints information why it
+ ibool print_info) /*!< in: if TRUE, prints information why it
cannot close a file */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
- ut_ad(mutex_own(&(system->mutex)));
+ ut_ad(mutex_own(&fil_system->mutex));
- node = UT_LIST_GET_LAST(system->LRU);
+ node = UT_LIST_GET_LAST(fil_system->LRU);
if (print_info) {
fprintf(stderr,
"InnoDB: fil_sys open file LRU len %lu\n",
- (ulong) UT_LIST_GET_LEN(system->LRU));
+ (ulong) UT_LIST_GET_LEN(fil_system->LRU));
}
while (node != NULL) {
if (node->modification_counter == node->flush_counter
&& node->n_pending_flushes == 0) {
- fil_node_close_file(node, system);
+ fil_node_close_file(node, fil_system);
return(TRUE);
}
@@ -860,7 +889,7 @@ fil_try_to_close_file_in_LRU(
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Reserves the fil_system mutex and tries to make sure we can open at least one
file while holding it. This should be called before calling
fil_node_prepare_for_io(), because that function may need to open a file. */
@@ -868,18 +897,16 @@ static
void
fil_mutex_enter_and_prepare_for_io(
/*===============================*/
- ulint space_id) /* in: space id */
+ ulint space_id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ibool success;
ibool print_info = FALSE;
ulint count = 0;
ulint count2 = 0;
- ut_ad(!mutex_own(&(system->mutex)));
retry:
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
if (space_id == 0 || space_id >= SRV_LOG_SPACE_FIRST_ID) {
/* We keep log files and system tablespace files always open;
@@ -891,7 +918,7 @@ retry:
return;
}
- if (system->n_open < system->max_n_open) {
+ if (fil_system->n_open < fil_system->max_n_open) {
return;
}
@@ -910,7 +937,7 @@ retry:
(ulong) count2);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
@@ -936,12 +963,12 @@ retry:
close_more:
success = fil_try_to_close_file_in_LRU(print_info);
- if (success && system->n_open >= system->max_n_open) {
+ if (success && fil_system->n_open >= fil_system->max_n_open) {
goto close_more;
}
- if (system->n_open < system->max_n_open) {
+ if (fil_system->n_open < fil_system->max_n_open) {
/* Ok */
return;
@@ -954,14 +981,15 @@ close_more:
" while the maximum\n"
"InnoDB: allowed value would be %lu.\n"
"InnoDB: You may need to raise the value of"
- " innodb_max_files_open in\n"
+ " innodb_open_files in\n"
"InnoDB: my.cnf.\n",
- (ulong) system->n_open, (ulong) system->max_n_open);
+ (ulong) fil_system->n_open,
+ (ulong) fil_system->max_n_open);
return;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
/* Wake the i/o-handler threads to make sure pending i/o's are
@@ -980,15 +1008,15 @@ close_more:
goto retry;
}
-/***********************************************************************
+/*******************************************************************//**
Frees a file node object from a tablespace memory cache. */
static
void
fil_node_free(
/*==========*/
- fil_node_t* node, /* in, own: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- fil_space_t* space) /* in: space where the file node is chained */
+ fil_node_t* node, /*!< in, own: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ fil_space_t* space) /*!< in: space where the file node is chained */
{
ut_ad(node && system && space);
ut_ad(mutex_own(&(system->mutex)));
@@ -1023,23 +1051,22 @@ fil_node_free(
}
#ifdef UNIV_LOG_ARCHIVE
-/********************************************************************
+/****************************************************************//**
Drops files from the start of a file space, so that its size is cut by
the amount given. */
UNIV_INTERN
void
fil_space_truncate_start(
/*=====================*/
- ulint id, /* in: space id */
- ulint trunc_len) /* in: truncate by this much; it is an error
+ ulint id, /*!< in: space id */
+ ulint trunc_len) /*!< in: truncate by this much; it is an error
if this does not equal to the combined size of
some initial files in the space */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1052,28 +1079,27 @@ fil_space_truncate_start(
trunc_len -= node->size * UNIV_PAGE_SIZE;
- fil_node_free(node, system, space);
+ fil_node_free(node, fil_system, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
#endif /* UNIV_LOG_ARCHIVE */
-/***********************************************************************
+/*******************************************************************//**
Creates a space memory object and puts it to the tablespace memory cache. If
-there is an error, prints an error message to the .err log. */
+there is an error, prints an error message to the .err log.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_space_create(
/*=============*/
- /* out: TRUE if success */
- const char* name, /* in: space name */
- ulint id, /* in: space id */
- ulint flags, /* in: compressed page size
+ const char* name, /*!< in: space name */
+ ulint id, /*!< in: space id */
+ ulint flags, /*!< in: compressed page size
and file format, or 0 */
- ulint purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */
+ ulint purpose)/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
@@ -1087,10 +1113,10 @@ try_again:
"InnoDB: Adding tablespace %lu of name %s, purpose %lu\n", id, name,
purpose);*/
- ut_a(system);
+ ut_a(fil_system);
ut_a(name);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_name(name);
@@ -1111,7 +1137,7 @@ try_again:
if (id == 0 || purpose != FIL_TABLESPACE) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -1133,9 +1159,9 @@ try_again:
namesake_id = space->id;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
- fil_space_free(namesake_id);
+ fil_space_free(namesake_id, FALSE);
goto try_again;
}
@@ -1155,7 +1181,7 @@ try_again:
fputs(" already exists in the tablespace\n"
"InnoDB: memory cache!\n", stderr);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -1165,12 +1191,12 @@ try_again:
space->name = mem_strdup(name);
space->id = id;
- system->tablespace_version++;
- space->tablespace_version = system->tablespace_version;
+ fil_system->tablespace_version++;
+ space->tablespace_version = fil_system->tablespace_version;
space->mark = FALSE;
- if (purpose == FIL_TABLESPACE && id > system->max_assigned_id) {
- system->max_assigned_id = id;
+ if (purpose == FIL_TABLESPACE && id > fil_system->max_assigned_id) {
+ fil_system->max_assigned_id = id;
}
space->stop_ios = FALSE;
@@ -1190,38 +1216,36 @@ try_again:
rw_lock_create(&space->latch, SYNC_FSP);
- HASH_INSERT(fil_space_t, hash, system->spaces, id, space);
+ HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space);
- HASH_INSERT(fil_space_t, name_hash, system->name_hash,
+ HASH_INSERT(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(name), space);
space->is_in_unflushed_spaces = FALSE;
- UT_LIST_ADD_LAST(space_list, system->space_list, space);
+ UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Assigns a new space id for a new single-table tablespace. This works simply by
incrementing the global counter. If 4 billion id's is not enough, we may need
-to recycle id's. */
+to recycle id's.
+@return new tablespace id; ULINT_UNDEFINED if could not assign an id */
static
ulint
fil_assign_new_space_id(void)
/*=========================*/
- /* out: new tablespace id; ULINT_UNDEFINED if could
- not assign an id */
{
- fil_system_t* system = fil_system;
ulint id;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- system->max_assigned_id++;
+ fil_system->max_assigned_id++;
- id = system->max_assigned_id;
+ id = fil_system->max_assigned_id;
if (id > (SRV_LOG_SPACE_FIRST_ID / 2) && (id % 1000000UL == 0)) {
ut_print_timestamp(stderr);
@@ -1247,33 +1271,36 @@ fil_assign_new_space_id(void)
" have to dump all your tables and\n"
"InnoDB: recreate the whole InnoDB installation.\n",
(ulong) id);
- system->max_assigned_id--;
+ fil_system->max_assigned_id--;
id = ULINT_UNDEFINED;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(id);
}
-/***********************************************************************
+/*******************************************************************//**
Frees a space object from the tablespace memory cache. Closes the files in
the chain but does not delete them. There must not be any pending i/o's or
-flushes on the files. */
-UNIV_INTERN
+flushes on the files.
+@return TRUE if success */
+static
ibool
fil_space_free(
/*===========*/
- /* out: TRUE if success */
- ulint id) /* in: space id */
+ /* out: TRUE if success */
+ ulint id, /* in: space id */
+ ibool own_mutex) /* in: TRUE if own system->mutex */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_space_t* namespace;
fil_node_t* fil_node;
- mutex_enter(&(system->mutex));
+ if (!own_mutex) {
+ mutex_enter(&fil_system->mutex);
+ }
space = fil_space_get_by_id(id);
@@ -1284,28 +1311,28 @@ fil_space_free(
" from the cache but\n"
"InnoDB: it is not there.\n", (ulong) id);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
- HASH_DELETE(fil_space_t, hash, system->spaces, id, space);
+ HASH_DELETE(fil_space_t, hash, fil_system->spaces, id, space);
namespace = fil_space_get_by_name(space->name);
ut_a(namespace);
ut_a(space == namespace);
- HASH_DELETE(fil_space_t, name_hash, system->name_hash,
+ HASH_DELETE(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(space->name), space);
if (space->is_in_unflushed_spaces) {
space->is_in_unflushed_spaces = FALSE;
- UT_LIST_REMOVE(unflushed_spaces, system->unflushed_spaces,
+ UT_LIST_REMOVE(unflushed_spaces, fil_system->unflushed_spaces,
space);
}
- UT_LIST_REMOVE(space_list, system->space_list, space);
+ UT_LIST_REMOVE(space_list, fil_system->space_list, space);
ut_a(space->magic_n == FIL_SPACE_MAGIC_N);
ut_a(0 == space->n_pending_flushes);
@@ -1313,14 +1340,16 @@ fil_space_free(
fil_node = UT_LIST_GET_FIRST(space->chain);
while (fil_node != NULL) {
- fil_node_free(fil_node, system, space);
+ fil_node_free(fil_node, fil_system, space);
fil_node = UT_LIST_GET_FIRST(space->chain);
}
ut_a(0 == UT_LIST_GET_LEN(space->chain));
- mutex_exit(&(system->mutex));
+ if (!own_mutex) {
+ mutex_exit(&fil_system->mutex);
+ }
rw_lock_free(&(space->latch));
@@ -1330,52 +1359,28 @@ fil_space_free(
return(TRUE);
}
-#ifdef UNIV_HOTBACKUP
-/***********************************************************************
-Returns the tablespace object for a given id, or NULL if not found from the
-tablespace memory cache. */
-static
-fil_space_t*
-fil_get_space_for_id_low(
-/*=====================*/
- /* out: tablespace object or NULL; NOTE that you must
- own &(fil_system->mutex) to call this function! */
- ulint id) /* in: space id */
-{
- fil_system_t* system = fil_system;
- fil_space_t* space;
-
- ut_ad(system);
-
- space = fil_space_get_by_id(id);
-
- return(space);
-}
-#endif
-
-/***********************************************************************
+/*******************************************************************//**
Returns the size of the space in pages. The tablespace must be cached in the
-memory cache. */
+memory cache.
+@return space size, 0 if space not found */
UNIV_INTERN
ulint
fil_space_get_size(
/*===============*/
- /* out: space size, 0 if space not found */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
ulint size;
- ut_ad(system);
+ ut_ad(fil_system);
fil_mutex_enter_and_prepare_for_io(id);
space = fil_space_get_by_id(id);
if (space == NULL) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(0);
}
@@ -1391,33 +1396,32 @@ fil_space_get_size(
the file yet; the following calls will open it and update the
size fields */
- fil_node_prepare_for_io(node, system, space);
- fil_node_complete_io(node, system, OS_FILE_READ);
+ fil_node_prepare_for_io(node, fil_system, space);
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
}
size = space->size;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(size);
}
-/***********************************************************************
+/*******************************************************************//**
Returns the flags of the space. The tablespace must be cached
-in the memory cache. */
+in the memory cache.
+@return flags, ULINT_UNDEFINED if space not found */
UNIV_INTERN
ulint
fil_space_get_flags(
/*================*/
- /* out: flags, ULINT_UNDEFINED if space not found */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
ulint flags;
- ut_ad(system);
+ ut_ad(fil_system);
if (UNIV_UNLIKELY(!id)) {
return(0);
@@ -1428,7 +1432,7 @@ fil_space_get_flags(
space = fil_space_get_by_id(id);
if (space == NULL) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(ULINT_UNDEFINED);
}
@@ -1444,27 +1448,26 @@ fil_space_get_flags(
the file yet; the following calls will open it and update the
size fields */
- fil_node_prepare_for_io(node, system, space);
- fil_node_complete_io(node, system, OS_FILE_READ);
+ fil_node_prepare_for_io(node, fil_system, space);
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
}
flags = space->flags;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(flags);
}
-/***********************************************************************
+/*******************************************************************//**
Returns the compressed page size of the space, or 0 if the space
-is not compressed. The tablespace must be cached in the memory cache. */
+is not compressed. The tablespace must be cached in the memory cache.
+@return compressed page size, ULINT_UNDEFINED if space not found */
UNIV_INTERN
ulint
fil_space_get_zip_size(
/*===================*/
- /* out: compressed page size, ULINT_UNDEFINED
- if space not found */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
ulint flags;
@@ -1478,16 +1481,16 @@ 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. */
+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(
/*===========================*/
- /* out: TRUE if the address is meaningful */
- ulint id, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint id, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
if (fil_space_get_size(id) > page_no) {
@@ -1497,67 +1500,42 @@ fil_check_adress_in_tablespace(
return(FALSE);
}
-/********************************************************************
-Creates a the tablespace memory cache. */
-static
-fil_system_t*
-fil_system_create(
-/*==============*/
- /* out, own: tablespace memory cache */
- ulint hash_size, /* in: hash table size */
- ulint max_n_open) /* in: maximum number of open files; must be
- > 10 */
+/****************************************************************//**
+Initializes the tablespace memory cache. */
+UNIV_INTERN
+void
+fil_init(
+/*=====*/
+ ulint hash_size, /*!< in: hash table size */
+ ulint max_n_open) /*!< in: max number of open files */
{
- fil_system_t* system;
+ ut_a(fil_system == NULL);
ut_a(hash_size > 0);
ut_a(max_n_open > 0);
- system = mem_alloc(sizeof(fil_system_t));
+ fil_system = mem_alloc(sizeof(fil_system_t));
- mutex_create(&system->mutex, SYNC_ANY_LATCH);
+ mutex_create(&fil_system->mutex, SYNC_ANY_LATCH);
- system->spaces = hash_create(hash_size);
- system->name_hash = hash_create(hash_size);
+ fil_system->spaces = hash_create(hash_size);
+ fil_system->name_hash = hash_create(hash_size);
- UT_LIST_INIT(system->LRU);
+ UT_LIST_INIT(fil_system->LRU);
- system->n_open = 0;
- system->max_n_open = max_n_open;
+ fil_system->n_open = 0;
+ fil_system->max_n_open = max_n_open;
- system->modification_counter = 0;
- system->max_assigned_id = 0;
+ fil_system->modification_counter = 0;
+ fil_system->max_assigned_id = 0;
- system->tablespace_version = 0;
+ fil_system->tablespace_version = 0;
- UT_LIST_INIT(system->unflushed_spaces);
- UT_LIST_INIT(system->space_list);
-
- return(system);
+ UT_LIST_INIT(fil_system->unflushed_spaces);
+ UT_LIST_INIT(fil_system->space_list);
}
-/********************************************************************
-Initializes the tablespace memory cache. */
-UNIV_INTERN
-void
-fil_init(
-/*=====*/
- ulint max_n_open) /* in: max number of open files */
-{
- ulint hash_size;
-
- ut_a(fil_system == NULL);
-
- if (srv_file_per_table) {
- hash_size = 50000;
- } else {
- hash_size = 5000;
- }
-
- fil_system = fil_system_create(hash_size, max_n_open);
-}
-
-/***********************************************************************
+/*******************************************************************//**
Opens all log files and system tablespace data files. They stay open until the
database server shutdown. This should be called at a server startup after the
space objects for the log and the system tablespace have been created. The
@@ -1568,13 +1546,12 @@ void
fil_open_log_and_system_tablespace_files(void)
/*==========================================*/
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_node_t* node;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
if (space->purpose != FIL_TABLESPACE || space->id == 0) {
@@ -1582,14 +1559,15 @@ fil_open_log_and_system_tablespace_files(void)
while (node != NULL) {
if (!node->open) {
- fil_node_open_file(node, system,
+ fil_node_open_file(node, fil_system,
space);
}
- if (system->max_n_open < 10 + system->n_open) {
+ if (fil_system->max_n_open
+ < 10 + fil_system->n_open) {
fprintf(stderr,
"InnoDB: Warning: you must"
" raise the value of"
- " innodb_max_open_files in\n"
+ " innodb_open_files in\n"
"InnoDB: my.cnf! Remember that"
" InnoDB keeps all log files"
" and all system\n"
@@ -1603,8 +1581,8 @@ fil_open_log_and_system_tablespace_files(void)
" Current open files %lu,"
" max allowed"
" open files %lu.\n",
- (ulong) system->n_open,
- (ulong) system->max_n_open);
+ (ulong) fil_system->n_open,
+ (ulong) fil_system->max_n_open);
}
node = UT_LIST_GET_NEXT(chain, node);
}
@@ -1612,10 +1590,10 @@ fil_open_log_and_system_tablespace_files(void)
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Closes all open files. There must not be any pending i/o's or not flushed
modifications in the files. */
UNIV_INTERN
@@ -1623,58 +1601,58 @@ void
fil_close_all_files(void)
/*=====================*/
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_node_t* node;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
+ fil_space_t* prev_space = space;
+
node = UT_LIST_GET_FIRST(space->chain);
while (node != NULL) {
if (node->open) {
- fil_node_close_file(node, system);
+ fil_node_close_file(node, fil_system);
}
node = UT_LIST_GET_NEXT(chain, node);
}
space = UT_LIST_GET_NEXT(space_list, space);
+ fil_space_free(prev_space->id, TRUE);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Sets the max tablespace id counter if the given number is bigger than the
previous value. */
UNIV_INTERN
void
fil_set_max_space_id_if_bigger(
/*===========================*/
- ulint max_id) /* in: maximum known id */
+ ulint max_id) /*!< in: maximum known id */
{
- fil_system_t* system = fil_system;
-
if (max_id >= SRV_LOG_SPACE_FIRST_ID) {
fprintf(stderr,
"InnoDB: Fatal error: max tablespace id"
" is too high, %lu\n", (ulong) max_id);
- ut_a(0);
+ ut_error;
}
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- if (system->max_assigned_id < max_id) {
+ if (fil_system->max_assigned_id < max_id) {
- system->max_assigned_id = max_id;
+ fil_system->max_assigned_id = max_id;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/********************************************************************
+/****************************************************************//**
Writes the flushed lsn and the latest archived log number to the page header
of the first page of a data file of the system tablespace (space 0),
which is uncompressed. */
@@ -1682,11 +1660,11 @@ static
ulint
fil_write_lsn_and_arch_no_to_file(
/*==============================*/
- ulint sum_of_sizes, /* in: combined size of previous files
+ ulint sum_of_sizes, /*!< in: combined size of previous files
in space, in database pages */
- ib_uint64_t lsn, /* in: lsn to write */
- ulint arch_log_no /* in: archived log number to write */
- __attribute__((unused)))
+ ib_uint64_t lsn, /*!< in: lsn to write */
+ ulint arch_log_no __attribute__((unused)))
+ /*!< in: archived log number to write */
{
byte* buf1;
byte* buf;
@@ -1705,16 +1683,16 @@ fil_write_lsn_and_arch_no_to_file(
return(DB_SUCCESS);
}
-/********************************************************************
+/****************************************************************//**
Writes the flushed lsn and the latest archived log number to the page
-header of the first page of each data file in the system tablespace. */
+header of the first page of each data file in the system tablespace.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
fil_write_flushed_lsn_to_data_files(
/*================================*/
- /* out: DB_SUCCESS or error number */
- ib_uint64_t lsn, /* in: lsn to write */
- ulint arch_log_no) /* in: latest archived log
+ ib_uint64_t lsn, /*!< in: lsn to write */
+ ulint arch_log_no) /*!< in: latest archived log
file number */
{
fil_space_t* space;
@@ -1722,7 +1700,7 @@ fil_write_flushed_lsn_to_data_files(
ulint sum_of_sizes;
ulint err;
- mutex_enter(&(fil_system->mutex));
+ mutex_enter(&fil_system->mutex);
space = UT_LIST_GET_FIRST(fil_system->space_list);
@@ -1739,7 +1717,7 @@ fil_write_flushed_lsn_to_data_files(
node = UT_LIST_GET_FIRST(space->chain);
while (node) {
- mutex_exit(&(fil_system->mutex));
+ mutex_exit(&fil_system->mutex);
err = fil_write_lsn_and_arch_no_to_file(
sum_of_sizes, lsn, arch_log_no);
@@ -1748,7 +1726,7 @@ fil_write_flushed_lsn_to_data_files(
return(err);
}
- mutex_enter(&(fil_system->mutex));
+ mutex_enter(&fil_system->mutex);
sum_of_sizes += node->size;
node = UT_LIST_GET_NEXT(chain, node);
@@ -1757,28 +1735,28 @@ fil_write_flushed_lsn_to_data_files(
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(fil_system->mutex));
+ mutex_exit(&fil_system->mutex);
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Reads the flushed lsn and arch no fields from a data file at database
startup. */
UNIV_INTERN
void
fil_read_flushed_lsn_and_arch_log_no(
/*=================================*/
- os_file_t data_file, /* in: open data file */
- ibool one_read_already, /* in: TRUE if min and max
+ os_file_t data_file, /*!< in: open data file */
+ ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
#ifdef UNIV_LOG_ARCHIVE
- ulint* min_arch_log_no, /* in/out: */
- ulint* max_arch_log_no, /* in/out: */
+ ulint* min_arch_log_no, /*!< in/out: */
+ ulint* max_arch_log_no, /*!< in/out: */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t* min_flushed_lsn, /* in/out: */
- ib_uint64_t* max_flushed_lsn) /* in/out: */
+ ib_uint64_t* min_flushed_lsn, /*!< in/out: */
+ ib_uint64_t* max_flushed_lsn) /*!< in/out: */
{
byte* buf;
byte* buf2;
@@ -1822,21 +1800,20 @@ fil_read_flushed_lsn_and_arch_log_no(
/*================ SINGLE-TABLE TABLESPACES ==========================*/
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Increments the count of pending insert buffer page merges, if space is not
-being deleted. */
+being deleted.
+@return TRUE if being deleted, and ibuf merges should be skipped */
UNIV_INTERN
ibool
fil_inc_pending_ibuf_merges(
/*========================*/
- /* out: TRUE if being deleted, and ibuf merges should
- be skipped */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1848,30 +1825,29 @@ fil_inc_pending_ibuf_merges(
}
if (space == NULL || space->stop_ibuf_merges) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
space->n_pending_ibuf_merges++;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Decrements the count of pending insert buffer page merges. */
UNIV_INTERN
void
fil_decr_pending_ibuf_merges(
/*=========================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1886,16 +1862,17 @@ fil_decr_pending_ibuf_merges(
space->n_pending_ibuf_merges--;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
+/********************************************************//**
Creates the database directory for a table if it does not exist yet. */
static
void
fil_create_directory_for_tablename(
/*===============================*/
- const char* name) /* in: name in the standard
+ const char* name) /*!< in: name in the standard
'databasename/tablename' format */
{
const char* namend;
@@ -1919,28 +1896,30 @@ fil_create_directory_for_tablename(
}
#ifndef UNIV_HOTBACKUP
-/************************************************************
+/********************************************************//**
Writes a log record about an .ibd file create/rename/delete. */
static
void
fil_op_write_log(
/*=============*/
- ulint type, /* in: MLOG_FILE_CREATE,
+ ulint type, /*!< in: MLOG_FILE_CREATE,
MLOG_FILE_CREATE2,
MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
- ulint space_id, /* in: space id */
- ulint flags, /* in: compressed page size
+ ulint space_id, /*!< in: space id */
+ ulint log_flags, /*!< in: redo log flags (stored
+ in the page number field) */
+ ulint flags, /*!< in: compressed page size
and file format
if type==MLOG_FILE_CREATE2, or 0 */
- const char* name, /* in: table name in the familiar
+ const char* name, /*!< in: table name in the familiar
'databasename/tablename' format, or
the file path in the case of
MLOG_FILE_DELETE */
- const char* new_name, /* in: if type is MLOG_FILE_RENAME,
+ const char* new_name, /*!< in: if type is MLOG_FILE_RENAME,
the new table name in the
'databasename/tablename' format */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
ulint len;
@@ -1953,8 +1932,8 @@ fil_op_write_log(
return;
}
- log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0,
- log_ptr, mtr);
+ log_ptr = mlog_write_initial_log_record_for_file_op(
+ type, space_id, log_flags, log_ptr, mtr);
if (type == MLOG_FILE_CREATE2) {
mach_write_to_4(log_ptr, flags);
log_ptr += 4;
@@ -1983,7 +1962,7 @@ fil_op_write_log(
}
#endif
-/***********************************************************************
+/*******************************************************************//**
Parses the body of a log record written about an .ibd file operation. That is,
the log record part after the standard (type, space id, page no) header of the
log record.
@@ -1994,22 +1973,23 @@ at that path does not exist yet. If the database directory for the file to be
created does not exist, then we create the directory, too.
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
-datadir that we should use in replaying the file operations. */
+datadir that we should use in replaying the file operations.
+@return end of log record, or NULL if the record was not completely
+contained between ptr and end_ptr */
UNIV_INTERN
byte*
fil_op_log_parse_or_replay(
/*=======================*/
- /* out: end of log record, or NULL if the
- record was not completely contained between
- ptr and end_ptr */
- byte* ptr, /* in: buffer containing the log record body,
+ byte* ptr, /*!< in: buffer containing the log record body,
or an initial segment of it, if the record does
not fir completely between ptr and end_ptr */
- byte* end_ptr, /* in: buffer end */
- ulint type, /* in: the type of this log record */
- ulint space_id) /* in: the space id of the tablespace in
+ byte* end_ptr, /*!< in: buffer end */
+ ulint type, /*!< in: the type of this log record */
+ ulint space_id, /*!< in: the space id of the tablespace in
question, or 0 if the log record should
only be parsed but not replayed */
+ ulint log_flags) /*!< in: redo log flags
+ (stored in the page number parameter) */
{
ulint name_len;
ulint new_name_len;
@@ -2129,6 +2109,8 @@ fil_op_log_parse_or_replay(
} else if (fil_get_space_id_for_table(name)
!= ULINT_UNDEFINED) {
/* Do nothing */
+ } else if (log_flags & MLOG_FILE_FLAG_TEMP) {
+ /* Temporary table, do nothing */
} else {
/* Create the database directory for name, if it does
not exist yet */
@@ -2150,17 +2132,16 @@ fil_op_log_parse_or_replay(
return(ptr);
}
-/***********************************************************************
+/*******************************************************************//**
Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache. */
+memory cache.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_delete_tablespace(
/*==================*/
- /* out: TRUE if success */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
ibool success;
fil_space_t* space;
fil_node_t* node;
@@ -2169,7 +2150,7 @@ fil_delete_tablespace(
ut_a(id != 0);
stop_ibuf_merges:
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -2177,7 +2158,7 @@ stop_ibuf_merges:
space->stop_ibuf_merges = TRUE;
if (space->n_pending_ibuf_merges == 0) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
count = 0;
@@ -2196,7 +2177,7 @@ stop_ibuf_merges:
(ulong) count);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
count++;
@@ -2205,11 +2186,11 @@ stop_ibuf_merges:
}
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
count = 0;
try_again:
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -2221,7 +2202,7 @@ try_again:
" tablespace memory cache.\n",
(ulong) id);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -2248,7 +2229,7 @@ try_again:
(ulong) node->n_pending,
(ulong) count);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
count++;
@@ -2258,7 +2239,7 @@ try_again:
path = mem_strdup(space->name);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
/* Invalidate in the buffer pool all pages belonging to the
tablespace. Since we have set space->is_being_deleted = TRUE, readahead
@@ -2271,7 +2252,7 @@ try_again:
#endif
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
- success = fil_space_free(id);
+ success = fil_space_free(id, FALSE);
if (success) {
success = os_file_delete(path);
@@ -2293,7 +2274,7 @@ try_again:
to write any log record */
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr);
+ fil_op_write_log(MLOG_FILE_DELETE, id, 0, 0, path, NULL, &mtr);
mtr_commit(&mtr);
#endif
mem_free(path);
@@ -2306,20 +2287,21 @@ try_again:
return(FALSE);
}
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Discards a single-table tablespace. The tablespace must be cached in the
memory cache. Discarding is like deleting a tablespace, but
1) we do not drop the table from the data dictionary;
2) we remove all insert buffer entries for the tablespace immediately; in DROP
TABLE they are only removed gradually in the background;
3) when the user does IMPORT TABLESPACE, the tablespace will have the same id
-as it originally had. */
+as it originally had.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_discard_tablespace(
/*===================*/
- /* out: TRUE if success */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
ibool success;
@@ -2340,22 +2322,24 @@ fil_discard_tablespace(
return(success);
}
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
-Renames the memory cache structures of a single-table tablespace. */
+/*******************************************************************//**
+Renames the memory cache structures of a single-table tablespace.
+@return TRUE if success */
static
ibool
fil_rename_tablespace_in_mem(
/*=========================*/
- /* out: TRUE if success */
- fil_space_t* space, /* in: tablespace memory object */
- fil_node_t* node, /* in: file node of that tablespace */
- const char* path) /* in: new name */
+ fil_space_t* space, /*!< in: tablespace memory object */
+ fil_node_t* node, /*!< in: file node of that tablespace */
+ const char* path) /*!< in: new name */
{
- fil_system_t* system = fil_system;
fil_space_t* space2;
const char* old_name = space->name;
+ ut_ad(mutex_own(&fil_system->mutex));
+
space2 = fil_space_get_by_name(old_name);
if (space != space2) {
fputs("InnoDB: Error: cannot find ", stderr);
@@ -2374,7 +2358,7 @@ fil_rename_tablespace_in_mem(
return(FALSE);
}
- HASH_DELETE(fil_space_t, name_hash, system->name_hash,
+ HASH_DELETE(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(space->name), space);
mem_free(space->name);
mem_free(node->name);
@@ -2382,22 +2366,22 @@ fil_rename_tablespace_in_mem(
space->name = mem_strdup(path);
node->name = mem_strdup(path);
- HASH_INSERT(fil_space_t, name_hash, system->name_hash,
+ HASH_INSERT(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(path), space);
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Allocates a file name for a single-table tablespace. The string must be freed
-by caller with mem_free(). */
+by caller with mem_free().
+@return own: file name */
static
char*
fil_make_ibd_name(
/*==============*/
- /* out, own: file name */
- const char* name, /* in: table name or a dir path of a
+ const char* name, /*!< in: table name or a dir path of a
TEMPORARY table */
- ibool is_temp) /* in: TRUE if it is a dir path */
+ ibool is_temp) /*!< in: TRUE if it is a dir path */
{
ulint namelen = strlen(name);
ulint dirlen = strlen(fil_path_to_mysql_datadir);
@@ -2419,24 +2403,23 @@ fil_make_ibd_name(
return(filename);
}
-/***********************************************************************
+/*******************************************************************//**
Renames a single-table tablespace. The tablespace must be cached in the
-tablespace memory cache. */
+tablespace memory cache.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_rename_tablespace(
/*==================*/
- /* out: TRUE if success */
- const char* old_name, /* in: old table name in the standard
+ const char* old_name, /*!< in: old table name in the standard
databasename/tablename format of
InnoDB, or NULL if we do the rename
based on the space id only */
- ulint id, /* in: space id */
- const char* new_name) /* in: new table name in the standard
+ ulint id, /*!< in: space id */
+ const char* new_name) /*!< in: new table name in the standard
databasename/tablename format
of InnoDB */
{
- fil_system_t* system = fil_system;
ibool success;
fil_space_t* space;
fil_node_t* node;
@@ -2463,7 +2446,7 @@ retry:
fprintf(stderr, ", %lu iterations\n", (ulong) count);
}
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -2474,14 +2457,14 @@ retry:
"InnoDB: though the table ", (ulong) id);
ut_print_filename(stderr, old_name);
fputs(" in a rename operation should have that id\n", stderr);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
if (count > 25000) {
space->stop_ios = FALSE;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -2499,7 +2482,7 @@ retry:
/* There are pending i/o's or flushes, sleep for a while and
retry */
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
@@ -2508,7 +2491,7 @@ retry:
} else if (node->modification_counter > node->flush_counter) {
/* Flush the space */
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
@@ -2519,7 +2502,7 @@ retry:
} else if (node->open) {
/* Close the file */
- fil_node_close_file(node, system);
+ fil_node_close_file(node, fil_system);
}
/* Check that the old name in the space is right */
@@ -2554,7 +2537,7 @@ retry:
space->stop_ios = FALSE;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
if (success) {
@@ -2562,7 +2545,7 @@ retry:
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name,
+ fil_op_write_log(MLOG_FILE_RENAME, id, 0, 0, old_name, new_name,
&mtr);
mtr_commit(&mtr);
}
@@ -2570,28 +2553,28 @@ retry:
return(success);
}
-/***********************************************************************
+/*******************************************************************//**
Creates a new single-table tablespace to a database directory of MySQL.
Database directories are under the 'datadir' of MySQL. The datadir is the
directory of a running mysqld program. We can refer to it by simply the
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
-dir of the mysqld server. */
+dir of the mysqld server.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
fil_create_new_single_table_tablespace(
/*===================================*/
- /* out: DB_SUCCESS or error code */
- ulint* space_id, /* in/out: space id; if this is != 0,
+ ulint* space_id, /*!< in/out: space id; if this is != 0,
then this is an input parameter,
otherwise output */
- const char* tablename, /* in: the table name in the usual
+ const char* tablename, /*!< in: the table name in the usual
databasename/tablename format
of InnoDB, or a dir path to a temp
table */
- ibool is_temp, /* in: TRUE if a table created with
+ ibool is_temp, /*!< in: TRUE if a table created with
CREATE TEMPORARY TABLE */
- ulint flags, /* in: tablespace flags */
- ulint size) /* in: the initial size of the
+ ulint flags, /*!< in: tablespace flags */
+ ulint size) /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
{
@@ -2766,7 +2749,9 @@ error_exit2:
fil_op_write_log(flags
? MLOG_FILE_CREATE2
: MLOG_FILE_CREATE,
- *space_id, flags,
+ *space_id,
+ is_temp ? MLOG_FILE_FLAG_TEMP : 0,
+ flags,
tablename, NULL, &mtr);
mtr_commit(&mtr);
@@ -2776,7 +2761,8 @@ error_exit2:
return(DB_SUCCESS);
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
It is possible, though very improbable, that the lsn's in the tablespace to be
imported have risen above the current system lsn, if a lengthy purge, ibuf
merge, or rollback was performed on a backup taken with ibbackup. If that is
@@ -2784,15 +2770,15 @@ the case, reset page lsn's in the file. We assume that mysqld was shut down
after it performed these cleanup operations on the .ibd file, so that it at
the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the
first page of the .ibd file, and we can determine whether we need to reset the
-lsn's just by looking at that flush lsn. */
+lsn's just by looking at that flush lsn.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_reset_too_high_lsns(
/*====================*/
- /* out: TRUE if success */
- const char* name, /* in: table name in the
+ const char* name, /*!< in: table name in the
databasename/tablename format */
- ib_uint64_t current_lsn) /* in: reset lsn's if the lsn stamped
+ ib_uint64_t current_lsn) /*!< in: reset lsn's if the lsn stamped
to FIL_PAGE_FILE_FLUSH_LSN in the
first page is too high */
{
@@ -2939,7 +2925,7 @@ func_exit:
return(success);
}
-/************************************************************************
+/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
function is used to open a tablespace when we start up mysqld, and also in
@@ -2947,22 +2933,22 @@ IMPORT TABLESPACE.
NOTE that we assume this operation is used either at the database startup
or under the protection of the dictionary mutex, so that two users cannot
race here. This operation does not leave the file associated with the
-tablespace open, but closes it after we have looked at the space id in it. */
+tablespace open, but closes it after we have looked at the space id in it.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_open_single_table_tablespace(
/*=============================*/
- /* out: TRUE if success */
- ibool check_space_id, /* in: should we check that the space
+ ibool check_space_id, /*!< in: should we check that the space
id in the file is right; we assume
that this function runs much faster
if no check is made, since accessing
the file inode probably is much
faster (the OS caches them) than
accessing the first page of the file */
- ulint id, /* in: space id */
- ulint flags, /* in: tablespace flags */
- const char* name) /* in: table name in the
+ ulint id, /*!< in: space id */
+ ulint flags, /*!< in: tablespace flags */
+ const char* name) /*!< in: table name in the
databasename/tablename format */
{
os_file_t file;
@@ -2972,7 +2958,6 @@ fil_open_single_table_tablespace(
byte* page;
ulint space_id;
ulint space_flags;
- ibool ret = TRUE;
filepath = fil_make_ibd_name(name, FALSE);
@@ -3003,8 +2988,7 @@ fil_open_single_table_tablespace(
" a temporary table #sql...,\n"
"InnoDB: and MySQL removed the .ibd file for this.\n"
"InnoDB: Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n", stderr);
mem_free(filepath);
@@ -3043,8 +3027,8 @@ fil_open_single_table_tablespace(
ib_uint64_t current_lsn;
ulint size_low, size_high, size;
ib_int64_t size_bytes;
- dict_table_t* table;
- dict_index_t* index;
+ dict_table_t* table;
+ dict_index_t* index;
fil_system_t* system;
fil_node_t* node = NULL;
fil_space_t* space;
@@ -3078,7 +3062,6 @@ fil_open_single_table_tablespace(
index = dict_table_get_first_index(table);
ut_a(index->page==3);
-
/* read metadata from .exp file */
n_index = 0;
memset(old_id, 0, sizeof(old_id));
@@ -3133,23 +3116,59 @@ skip_info:
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
- ib_int64_t offset;
+ ib_int64_t offset;
+
size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
/* over write space id of all pages */
-
rec_offs_init(offsets_);
fprintf(stderr, "%s", "InnoDB: Progress in %:");
for (offset = 0; offset < size_bytes; offset += UNIV_PAGE_SIZE) {
+ ulint checksum_field;
+ ulint old_checksum_field;
+
success = os_file_read(file, page,
(ulint)(offset & 0xFFFFFFFFUL),
(ulint)(offset >> 32), UNIV_PAGE_SIZE);
+
+ /* skip inconsistent pages, it may be free page. */
+ if (memcmp(page + FIL_PAGE_LSN + 4,
+ page + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) {
+
+ goto skip_write;
+ }
+
+ checksum_field = mach_read_from_4(page
+ + FIL_PAGE_SPACE_OR_CHKSUM);
+
+ old_checksum_field = mach_read_from_4(
+ page + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM);
+
+ if (old_checksum_field != mach_read_from_4(page
+ + FIL_PAGE_LSN)
+ && old_checksum_field != BUF_NO_CHECKSUM_MAGIC
+ && old_checksum_field
+ != buf_calc_page_old_checksum(page)) {
+
+ goto skip_write;
+ }
+
+ if (checksum_field != 0
+ && checksum_field != BUF_NO_CHECKSUM_MAGIC
+ && checksum_field
+ != buf_calc_page_new_checksum(page)) {
+
+ goto skip_write;
+ }
+
if (mach_read_from_4(page + FIL_PAGE_OFFSET) || !offset) {
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
- for (i = 0; i < n_index; i++) {
- if (offset / UNIV_PAGE_SIZE == root_page[i]) {
+ for (i = 0; (ulint) i < n_index; i++) {
+ if ((ulint) (offset / UNIV_PAGE_SIZE) == root_page[i]) {
/* this is index root page */
mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
+ FSEG_HDR_SPACE, id);
@@ -3174,13 +3193,30 @@ skip_info:
n_recs = page_get_n_recs(page);
while (rec && rec != supremum && n_recs > 0) {
+ ulint n_fields;
+ ulint i;
ulint offset = index->trx_id_offset;
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ n_fields = rec_offs_n_fields(offsets);
if (!offset) {
- offsets = rec_get_offsets(rec, index, offsets,
- ULINT_UNDEFINED, &heap);
offset = row_get_trx_id_offset(rec, index, offsets);
}
trx_write_trx_id(rec + offset, ut_dulint_create(0, 1));
+
+ for (i = 0; i < n_fields; i++) {
+ if (rec_offs_nth_extern(offsets, i)) {
+ ulint local_len;
+ byte* data;
+
+ data = rec_get_nth_field(rec, offsets, i, &local_len);
+
+ local_len -= BTR_EXTERN_FIELD_REF_SIZE;
+
+ mach_write_to_4(data + local_len + BTR_EXTERN_SPACE_ID, id);
+ }
+ }
+
rec = page_rec_get_next(rec);
n_recs--;
}
@@ -3214,6 +3250,7 @@ skip_info:
(ulint)(offset >> 32), UNIV_PAGE_SIZE);
}
+skip_write:
if (size_bytes
&& ((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / size_bytes)
!= ((offset * 100) / size_bytes)) {
@@ -3316,13 +3353,12 @@ skip_info:
"InnoDB: commands DISCARD TABLESPACE and"
" IMPORT TABLESPACE?\n"
"InnoDB: Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n",
(ulong) space_id, (ulong) space_flags,
(ulong) id, (ulong) flags);
- ret = FALSE;
+ success = FALSE;
goto func_exit;
}
@@ -3342,19 +3378,20 @@ func_exit:
os_file_close(file);
mem_free(filepath);
- return(ret);
+ return(success);
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_HOTBACKUP
-/***********************************************************************
+/*******************************************************************//**
Allocates a file name for an old version of a single-table tablespace.
-The string must be freed by caller with mem_free()! */
+The string must be freed by caller with mem_free()!
+@return own: file name */
static
char*
fil_make_ibbackup_old_name(
/*=======================*/
- /* out, own: file name */
- const char* name) /* in: original file name */
+ const char* name) /*!< in: original file name */
{
static const char suffix[] = "_ibbackup_old_vers_";
ulint len = strlen(name);
@@ -3367,15 +3404,15 @@ fil_make_ibbackup_old_name(
}
#endif /* UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Opens an .ibd file and adds the associated single-table tablespace to the
InnoDB fil0fil.c data structures. */
static
void
fil_load_single_table_tablespace(
/*=============================*/
- const char* dbname, /* in: database name */
- const char* filename) /* in: file name (not a path),
+ const char* dbname, /*!< in: database name */
+ const char* filename) /*!< in: file name (not a path),
including the .ibd extension */
{
os_file_t file;
@@ -3557,7 +3594,7 @@ fil_load_single_table_tablespace(
fprintf(stderr,
"InnoDB: Renaming tablespace %s of id %lu,\n"
"InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
- "InnoDB: because its size %lld is too small"
+ "InnoDB: because its size %" PRId64 " is too small"
" (< 4 pages 16 kB each),\n"
"InnoDB: or the space id in the file header"
" is not sensible.\n"
@@ -3583,9 +3620,9 @@ fil_load_single_table_tablespace(
file than delete it, because if there is a bug, we do not want to
destroy valuable data. */
- mutex_enter(&(fil_system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = fil_get_space_for_id_low(space_id);
+ space = fil_space_get_by_id(space_id);
if (space) {
char* new_path;
@@ -3603,7 +3640,7 @@ fil_load_single_table_tablespace(
new_path = fil_make_ibbackup_old_name(filepath);
- mutex_exit(&(fil_system->mutex));
+ mutex_exit(&fil_system->mutex);
ut_a(os_file_rename(filepath, new_path));
@@ -3613,13 +3650,23 @@ fil_load_single_table_tablespace(
return;
}
- mutex_exit(&(fil_system->mutex));
+ mutex_exit(&fil_system->mutex);
#endif
success = fil_space_create(filepath, space_id, flags, FIL_TABLESPACE);
if (!success) {
- goto func_exit;
+ if (srv_force_recovery > 0) {
+ fprintf(stderr,
+ "InnoDB: innodb_force_recovery"
+ " was set to %lu. Continuing crash recovery\n"
+ "InnoDB: even though the tablespace creation"
+ " of this table failed.\n",
+ srv_force_recovery);
+ goto func_exit;
+ }
+
+ exit(1);
}
/* We do not use the size information we have about the file, because
@@ -3633,21 +3680,21 @@ func_exit:
mem_free(filepath);
}
-/***************************************************************************
+/***********************************************************************//**
A fault-tolerant function that tries to read the next file name in the
directory. We retry 100 times if os_file_readdir_next_file() returns -1. The
-idea is to read as much good data as we can and jump over bad data. */
+idea is to read as much good data as we can and jump over bad data.
+@return 0 if ok, -1 if error even after the retries, 1 if at the end
+of the directory */
static
int
fil_file_readdir_next_file(
/*=======================*/
- /* out: 0 if ok, -1 if error even after the
- retries, 1 if at the end of the directory */
- ulint* err, /* out: this is set to DB_ERROR if an error
+ ulint* err, /*!< out: this is set to DB_ERROR if an error
was encountered, otherwise not changed */
- const char* dirname,/* in: directory name or path */
- os_file_dir_t dir, /* in: directory stream */
- os_file_stat_t* info) /* in/out: buffer where the info is returned */
+ const char* dirname,/*!< in: directory name or path */
+ os_file_dir_t dir, /*!< in: directory stream */
+ os_file_stat_t* info) /*!< in/out: buffer where the info is returned */
{
ulint i;
int ret;
@@ -3673,18 +3720,18 @@ fil_file_readdir_next_file(
return(-1);
}
-/************************************************************************
+/********************************************************************//**
At the server startup, if we need crash recovery, scans the database
directories under the MySQL datadir, looking for .ibd files. Those files are
single-table tablespaces. We need to know the space id in each of them so that
we know into which file we should look to check the contents of a page stored
in the doublewrite buffer, also to know where to apply log records where the
-space id is != 0. */
+space id is != 0.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
fil_load_single_table_tablespaces(void)
/*===================================*/
- /* out: DB_SUCCESS or error number */
{
int ret;
char* dbpath = NULL;
@@ -3802,7 +3849,7 @@ next_datadir_item:
return(err);
}
-/************************************************************************
+/********************************************************************//**
If we need crash recovery, and we have called
fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
we can call this function to print an error message of orphaned .ibd files
@@ -3813,12 +3860,11 @@ void
fil_print_orphaned_tablespaces(void)
/*================================*/
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space) {
if (space->purpose == FIL_TABLESPACE && space->id != 0
@@ -3833,115 +3879,104 @@ fil_print_orphaned_tablespaces(void)
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if a single-table tablespace does not exist in the memory cache,
-or is being deleted there. */
+or is being deleted there.
+@return TRUE if does not exist or is being\ deleted */
UNIV_INTERN
ibool
fil_tablespace_deleted_or_being_deleted_in_mem(
/*===========================================*/
- /* out: TRUE if does not exist or is being\
- deleted */
- ulint id, /* in: space id */
- ib_int64_t version)/* in: tablespace_version should be this; if
+ ulint id, /*!< in: space id */
+ ib_int64_t version)/*!< in: tablespace_version should be this; if
you pass -1 as the value of this, then this
parameter is ignored */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
if (space == NULL || space->is_being_deleted) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
if (version != ((ib_int64_t)-1)
&& space->tablespace_version != version) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
-/***********************************************************************
-Returns TRUE if a single-table tablespace exists in the memory cache. */
+/*******************************************************************//**
+Returns TRUE if a single-table tablespace exists in the memory cache.
+@return TRUE if exists */
UNIV_INTERN
ibool
fil_tablespace_exists_in_mem(
/*=========================*/
- /* out: TRUE if exists */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
- if (space == NULL) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
- return(FALSE);
- }
-
- mutex_exit(&(system->mutex));
-
- return(TRUE);
+ return(space != NULL);
}
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
cache. Note that if we have not done a crash recovery at the database startup,
-there may be many tablespaces which are not yet in the memory cache. */
+there may be many tablespaces which are not yet in the memory cache.
+@return TRUE if a matching tablespace exists in the memory cache */
UNIV_INTERN
ibool
fil_space_for_table_exists_in_mem(
/*==============================*/
- /* out: TRUE if a matching tablespace
- exists in the memory cache */
- ulint id, /* in: space id */
- const char* name, /* in: table name in the standard
+ ulint id, /*!< in: space id */
+ const char* name, /*!< in: table name in the standard
'databasename/tablename' format or
the dir path to a temp table */
- ibool is_temp, /* in: TRUE if created with CREATE
+ ibool is_temp, /*!< in: TRUE if created with CREATE
TEMPORARY TABLE */
- ibool mark_space, /* in: in crash recovery, at database
+ ibool mark_space, /*!< in: in crash recovery, at database
startup we mark all spaces which have
an associated table in the InnoDB
data dictionary, so that
we can print a warning about orphaned
tablespaces */
ibool print_error_if_does_not_exist)
- /* in: print detailed error
+ /*!< in: print detailed error
information to the .err log if a
matching tablespace is not found from
memory */
{
- fil_system_t* system = fil_system;
fil_space_t* namespace;
fil_space_t* space;
char* path;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
path = fil_make_ibd_name(name, is_temp);
@@ -3961,7 +3996,7 @@ fil_space_for_table_exists_in_mem(
}
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
@@ -3969,7 +4004,7 @@ fil_space_for_table_exists_in_mem(
if (!print_error_if_does_not_exist) {
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -4009,12 +4044,11 @@ fil_space_for_table_exists_in_mem(
}
error_exit:
fputs("InnoDB: Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n", stderr);
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -4044,31 +4078,29 @@ error_exit:
}
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if a single-table tablespace for a given table name exists in the
-tablespace memory cache. */
+tablespace memory cache.
+@return space id, ULINT_UNDEFINED if not found */
static
ulint
fil_get_space_id_for_table(
/*=======================*/
- /* out: space id, ULINT_UNDEFINED if not
- found */
- const char* name) /* in: table name in the standard
+ const char* name) /*!< in: table name in the standard
'databasename/tablename' format */
{
- fil_system_t* system = fil_system;
fil_space_t* namespace;
ulint id = ULINT_UNDEFINED;
char* path;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
path = fil_make_ibd_name(name, FALSE);
@@ -4083,29 +4115,28 @@ fil_get_space_id_for_table(
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(id);
}
-/**************************************************************************
+/**********************************************************************//**
Tries to extend a data file so that it would accommodate the number of pages
given. The tablespace must be cached in the memory cache. If the space is big
-enough already, does nothing. */
+enough already, does nothing.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_extend_space_to_desired_size(
/*=============================*/
- /* out: TRUE if success */
- ulint* actual_size, /* out: size of the space after extension;
+ ulint* actual_size, /*!< out: size of the space after extension;
if we ran out of disk space this may be lower
than the desired size */
- ulint space_id, /* in: space id */
- ulint size_after_extend)/* in: desired size in pages after the
+ ulint space_id, /*!< in: space id */
+ ulint size_after_extend)/*!< in: desired size in pages after the
extension; if the current space size is bigger
than this already, the function does nothing */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
byte* buf2;
@@ -4128,7 +4159,7 @@ fil_extend_space_to_desired_size(
*actual_size = space->size;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
@@ -4140,7 +4171,7 @@ fil_extend_space_to_desired_size(
node = UT_LIST_GET_LAST(space->chain);
- fil_node_prepare_for_io(node, system, space);
+ fil_node_prepare_for_io(node, fil_system, space);
start_page_no = space->size;
file_start_page_no = space->size - node->size;
@@ -4170,7 +4201,7 @@ fil_extend_space_to_desired_size(
node->name, node->handle, buf,
offset_low, offset_high,
page_size * n_pages,
- NULL, NULL);
+ NULL, NULL, NULL);
#endif
if (success) {
node->size += n_pages;
@@ -4197,7 +4228,7 @@ fil_extend_space_to_desired_size(
mem_free(buf2);
- fil_node_complete_io(node, system, OS_FILE_WRITE);
+ fil_node_complete_io(node, fil_system, OS_FILE_WRITE);
*actual_size = space->size;
@@ -4216,7 +4247,7 @@ fil_extend_space_to_desired_size(
/*
printf("Extended %s to %lu, actual size %lu pages\n", space->name,
size_after_extend, *actual_size); */
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
fil_flush(space_id);
@@ -4224,7 +4255,7 @@ fil_extend_space_to_desired_size(
}
#ifdef UNIV_HOTBACKUP
-/************************************************************************
+/********************************************************************//**
Extends all tablespaces to the size stored in the space header. During the
ibbackup --apply-log phase we extended the spaces on-demand so that log records
could be applied, but that may have left spaces still too small compared to
@@ -4234,7 +4265,6 @@ void
fil_extend_tablespaces_to_stored_len(void)
/*======================================*/
{
- fil_system_t* system = fil_system;
fil_space_t* space;
byte* buf;
ulint actual_size;
@@ -4244,17 +4274,18 @@ fil_extend_tablespaces_to_stored_len(void)
buf = mem_alloc(UNIV_PAGE_SIZE);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space) {
ut_a(space->purpose == FIL_TABLESPACE);
- mutex_exit(&(system->mutex)); /* no need to protect with a
+ mutex_exit(&fil_system->mutex); /* no need to protect with a
mutex, because this is a
single-threaded operation */
- error = fil_read(TRUE, space->id, space->zip_size,
+ error = fil_read(TRUE, space->id,
+ dict_table_flags_to_zip_size(space->flags),
0, 0, UNIV_PAGE_SIZE, buf, NULL);
ut_a(error == DB_SUCCESS);
@@ -4275,12 +4306,12 @@ fil_extend_tablespaces_to_stored_len(void)
exit(1);
}
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
mem_free(buf);
}
@@ -4288,24 +4319,23 @@ fil_extend_tablespaces_to_stored_len(void)
/*========== RESERVE FREE EXTENTS (for a B-tree split, for example) ===*/
-/***********************************************************************
-Tries to reserve free extents in a file space. */
+/*******************************************************************//**
+Tries to reserve free extents in a file space.
+@return TRUE if succeed */
UNIV_INTERN
ibool
fil_space_reserve_free_extents(
/*===========================*/
- /* out: TRUE if succeed */
- ulint id, /* in: space id */
- ulint n_free_now, /* in: number of free extents now */
- ulint n_to_reserve) /* in: how many one wants to reserve */
+ ulint id, /*!< in: space id */
+ ulint n_free_now, /*!< in: number of free extents now */
+ ulint n_to_reserve) /*!< in: how many one wants to reserve */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ibool success;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -4318,26 +4348,25 @@ fil_space_reserve_free_extents(
success = TRUE;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(success);
}
-/***********************************************************************
+/*******************************************************************//**
Releases free extents in a file space. */
UNIV_INTERN
void
fil_space_release_free_extents(
/*===========================*/
- ulint id, /* in: space id */
- ulint n_reserved) /* in: how many one reserved */
+ ulint id, /*!< in: space id */
+ ulint n_reserved) /*!< in: how many one reserved */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -4346,25 +4375,24 @@ fil_space_release_free_extents(
space->n_reserved_extents -= n_reserved;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Gets the number of reserved extents. If the database is silent, this number
should be zero. */
UNIV_INTERN
ulint
fil_space_get_n_reserved_extents(
/*=============================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ulint n;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -4372,14 +4400,14 @@ fil_space_get_n_reserved_extents(
n = space->n_reserved_extents;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(n);
}
/*============================ FILE I/O ================================*/
-/************************************************************************
+/********************************************************************//**
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
Prepares a file node for i/o. Opens the file if it is closed. Updates the
@@ -4390,9 +4418,9 @@ static
void
fil_node_prepare_for_io(
/*====================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- fil_space_t* space) /* in: space */
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ fil_space_t* space) /*!< in: space */
{
ut_ad(node && system && space);
ut_ad(mutex_own(&(system->mutex)));
@@ -4425,16 +4453,16 @@ fil_node_prepare_for_io(
node->n_pending++;
}
-/************************************************************************
+/********************************************************************//**
Updates the data structures when an i/o operation finishes. Updates the
pending i/o's field in the node appropriately. */
static
void
fil_node_complete_io(
/*=================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- ulint type) /* in: OS_FILE_WRITE or OS_FILE_READ; marks
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ ulint type) /*!< in: OS_FILE_WRITE or OS_FILE_READ; marks
the node as modified if
type == OS_FILE_WRITE */
{
@@ -4466,18 +4494,18 @@ fil_node_complete_io(
}
}
-/************************************************************************
+/********************************************************************//**
Report information about an invalid page access. */
static
void
fil_report_invalid_page_access(
/*===========================*/
- ulint block_offset, /* in: block offset */
- ulint space_id, /* in: space id */
- const char* space_name, /* in: space name */
- ulint byte_offset, /* in: byte offset */
- ulint len, /* in: I/O length */
- ulint type) /* in: I/O type */
+ ulint block_offset, /*!< in: block offset */
+ ulint space_id, /*!< in: space id */
+ const char* space_name, /*!< in: space name */
+ ulint byte_offset, /*!< in: byte offset */
+ ulint len, /*!< in: I/O length */
+ ulint type) /*!< in: I/O type */
{
fprintf(stderr,
"InnoDB: Error: trying to access page number %lu"
@@ -4494,16 +4522,15 @@ fil_report_invalid_page_access(
(ulong) byte_offset, (ulong) len, (ulong) type);
}
-/************************************************************************
-Reads or writes data. This operation is asynchronous (aio). */
+/********************************************************************//**
+Reads or writes data. This operation is asynchronous (aio).
+@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
+i/o on a tablespace which does not exist */
UNIV_INTERN
ulint
-fil_io(
+_fil_io(
/*===*/
- /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
- if we are trying to do i/o on a tablespace
- which does not exist */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE,
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
and ORed to OS_AIO_SIMULATED_WAKE_LATER
if simulated aio and we want to post a
@@ -4512,24 +4539,24 @@ fil_io(
because i/os are not actually handled until
all have been posted: use with great
caution! */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes;
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint block_offset, /* in: offset in number of blocks */
- ulint byte_offset, /* in: remainder of offset in bytes; in
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
aio this must be divisible by the OS block
size */
- ulint len, /* in: how many bytes to read or write; this
+ ulint len, /*!< in: how many bytes to read or write; this
must not cross a file boundary; in aio this
must be a block size multiple */
- void* buf, /* in/out: buffer where to store read data
+ void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
- void* message) /* in: message for aio handler if non-sync
+ void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
+ trx_t* trx)
{
- fil_system_t* system = fil_system;
ulint mode;
fil_space_t* space;
fil_node_t* node;
@@ -4554,14 +4581,15 @@ fil_io(
# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
#endif
ut_ad(fil_validate());
-#ifndef UNIV_LOG_DEBUG
+#ifndef UNIV_HOTBACKUP
+# ifndef UNIV_LOG_DEBUG
/* ibuf bitmap pages must be read in the sync aio mode: */
ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
|| !ibuf_bitmap_page(zip_size, block_offset)
|| sync || is_log);
ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
|| ibuf_page(space_id, zip_size, block_offset, NULL));
-#endif
+# endif /* UNIV_LOG_DEBUG */
if (sync) {
mode = OS_AIO_SYNC;
} else if (is_log) {
@@ -4573,6 +4601,10 @@ fil_io(
} else {
mode = OS_AIO_NORMAL;
}
+#else /* !UNIV_HOTBACKUP */
+ ut_a(sync);
+ mode = OS_AIO_SYNC;
+#endif /* !UNIV_HOTBACKUP */
if (type == OS_FILE_READ) {
srv_data_read+= len;
@@ -4588,7 +4620,7 @@ fil_io(
space = fil_space_get_by_id(space_id);
if (!space) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -4632,7 +4664,7 @@ fil_io(
}
/* Open file if closed */
- fil_node_prepare_for_io(node, system, space);
+ fil_node_prepare_for_io(node, fil_system, space);
/* Check that at least the start offset is within the bounds of a
single-table tablespace */
@@ -4646,8 +4678,8 @@ fil_io(
ut_error;
}
- /* Now we have made the changes in the data structures of system */
- mutex_exit(&(system->mutex));
+ /* Now we have made the changes in the data structures of fil_system */
+ mutex_exit(&fil_system->mutex);
/* Calculate the low 32 bits and the high 32 bits of the file offset */
@@ -4693,7 +4725,7 @@ fil_io(
#else
/* Queue the aio request */
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
- offset_low, offset_high, len, node, message);
+ offset_low, offset_high, len, node, message, trx);
#endif
ut_a(ret);
@@ -4701,11 +4733,11 @@ fil_io(
/* The i/o operation is already completed when we return from
os_aio: */
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- fil_node_complete_io(node, system, type);
+ fil_node_complete_io(node, fil_system, type);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
ut_ad(fil_validate());
}
@@ -4713,7 +4745,80 @@ fil_io(
return(DB_SUCCESS);
}
-/**************************************************************************
+/********************************************************************//**
+Confirm whether the parameters are valid or not */
+UNIV_INTERN
+ibool
+fil_area_is_exist(
+/*==============*/
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
+ 0 for uncompressed pages */
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
+ aio this must be divisible by the OS block
+ size */
+ ulint len) /*!< in: how many bytes to read or write; this
+ must not cross a file boundary; in aio this
+ must be a block size multiple */
+{
+ fil_space_t* space;
+ fil_node_t* node;
+
+ /* Reserve the fil_system mutex and make sure that we can open at
+ least one file while holding it, if the file is not already open */
+
+ fil_mutex_enter_and_prepare_for_io(space_id);
+
+ space = fil_space_get_by_id(space_id);
+
+ if (!space) {
+ mutex_exit(&fil_system->mutex);
+ return(FALSE);
+ }
+
+ node = UT_LIST_GET_FIRST(space->chain);
+
+ for (;;) {
+ if (UNIV_UNLIKELY(node == NULL)) {
+ mutex_exit(&fil_system->mutex);
+ return(FALSE);
+ }
+
+ if (space->id != 0 && node->size == 0) {
+ /* We do not know the size of a single-table tablespace
+ before we open the file */
+
+ break;
+ }
+
+ if (node->size > block_offset) {
+ /* Found! */
+ break;
+ } else {
+ block_offset -= node->size;
+ node = UT_LIST_GET_NEXT(chain, node);
+ }
+ }
+
+ /* Open file if closed */
+ fil_node_prepare_for_io(node, fil_system, space);
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
+
+ /* Check that at least the start offset is within the bounds of a
+ single-table tablespace */
+ if (UNIV_UNLIKELY(node->size <= block_offset)
+ && space->id != 0 && space->purpose == FIL_TABLESPACE) {
+ mutex_exit(&fil_system->mutex);
+ return(FALSE);
+ }
+
+ mutex_exit(&fil_system->mutex);
+ return(TRUE);
+}
+
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
into segments (see os0file.c for more info). The thread specifies which
@@ -4722,10 +4827,9 @@ UNIV_INTERN
void
fil_aio_wait(
/*=========*/
- ulint segment) /* in: the number of the segment in the aio
+ ulint segment) /*!< in: the number of the segment in the aio
array to wait for */
{
- fil_system_t* system = fil_system;
ibool ret;
fil_node_t* fil_node;
void* message;
@@ -4753,11 +4857,11 @@ fil_aio_wait(
srv_set_io_thread_op_info(segment, "complete io for fil node");
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
fil_node_complete_io(fil_node, fil_system, type);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
ut_ad(fil_validate());
@@ -4775,34 +4879,34 @@ fil_aio_wait(
log_io_complete(message);
}
}
+#endif /* UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Flushes to disk possible writes cached by the OS. If the space does not exist
or is being dropped, does not do anything. */
UNIV_INTERN
void
fil_flush(
/*======*/
- ulint space_id) /* in: file space id (this can be a group of
+ ulint space_id) /*!< in: file space id (this can be a group of
log files or a tablespace of the database) */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_node_t* node;
os_file_t file;
ib_int64_t old_mod_counter;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(space_id);
if (!space || space->is_being_deleted) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return;
}
- space->n_pending_flushes++; /* prevent dropping of the space while
+ space->n_pending_flushes++; /*!< prevent dropping of the space while
we are flushing */
node = UT_LIST_GET_FIRST(space->chain);
@@ -4833,11 +4937,11 @@ retry:
not know what bugs OS's may contain in file
i/o; sleep for a while */
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
if (node->flush_counter >= old_mod_counter) {
@@ -4851,14 +4955,14 @@ retry:
file = node->handle;
node->n_pending_flushes++;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
/* fprintf(stderr, "Flushing to file %s\n",
node->name); */
os_file_flush(file);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
node->n_pending_flushes--;
skip_flush:
@@ -4872,7 +4976,7 @@ skip_flush:
UT_LIST_REMOVE(
unflushed_spaces,
- system->unflushed_spaces,
+ fil_system->unflushed_spaces,
space);
}
}
@@ -4889,42 +4993,41 @@ skip_flush:
space->n_pending_flushes--;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Flushes to disk the writes in file spaces of the given type possibly cached by
the OS. */
UNIV_INTERN
void
fil_flush_file_spaces(
/*==================*/
- ulint purpose) /* in: FIL_TABLESPACE, FIL_LOG */
+ ulint purpose) /*!< in: FIL_TABLESPACE, FIL_LOG */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ulint* space_ids;
ulint n_space_ids;
ulint i;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- n_space_ids = UT_LIST_GET_LEN(system->unflushed_spaces);
+ n_space_ids = UT_LIST_GET_LEN(fil_system->unflushed_spaces);
if (n_space_ids == 0) {
- mutex_exit(&system->mutex);
+ mutex_exit(&fil_system->mutex);
return;
}
/* Assemble a list of space ids to flush. Previously, we
- traversed system->unflushed_spaces and called UT_LIST_GET_NEXT()
+ 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 = mem_alloc(n_space_ids * sizeof *space_ids);
n_space_ids = 0;
- for (space = UT_LIST_GET_FIRST(system->unflushed_spaces);
+ for (space = UT_LIST_GET_FIRST(fil_system->unflushed_spaces);
space;
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
@@ -4934,7 +5037,7 @@ fil_flush_file_spaces(
}
}
- mutex_exit(&system->mutex);
+ mutex_exit(&fil_system->mutex);
/* Flush the spaces. It will not hurt to call fil_flush() on
a non-existing space id. */
@@ -4946,30 +5049,31 @@ fil_flush_file_spaces(
mem_free(space_ids);
}
-/**********************************************************************
-Checks the consistency of the tablespace cache. */
+/******************************************************************//**
+Checks the consistency of the tablespace cache.
+@return TRUE if ok */
UNIV_INTERN
ibool
fil_validate(void)
/*==============*/
- /* out: TRUE if ok */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_node_t* fil_node;
ulint n_open = 0;
ulint i;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
/* Look for spaces in the hash table */
- for (i = 0; i < hash_get_n_cells(system->spaces); i++) {
+ for (i = 0; i < hash_get_n_cells(fil_system->spaces); i++) {
- space = HASH_GET_FIRST(system->spaces, i);
+ space = HASH_GET_FIRST(fil_system->spaces, i);
while (space != NULL) {
- UT_LIST_VALIDATE(chain, fil_node_t, space->chain);
+ UT_LIST_VALIDATE(chain, fil_node_t, space->chain,
+ ut_a(ut_list_node_313->open
+ || !ut_list_node_313->n_pending));
fil_node = UT_LIST_GET_FIRST(space->chain);
@@ -4987,11 +5091,11 @@ fil_validate(void)
}
}
- ut_a(system->n_open == n_open);
+ ut_a(fil_system->n_open == n_open);
- UT_LIST_VALIDATE(LRU, fil_node_t, system->LRU);
+ UT_LIST_VALIDATE(LRU, fil_node_t, fil_system->LRU, (void) 0);
- fil_node = UT_LIST_GET_FIRST(system->LRU);
+ fil_node = UT_LIST_GET_FIRST(fil_system->LRU);
while (fil_node != NULL) {
ut_a(fil_node->n_pending == 0);
@@ -5002,69 +5106,99 @@ fil_validate(void)
fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
-/************************************************************************
-Returns TRUE if file address is undefined. */
+/********************************************************************//**
+Returns TRUE if file address is undefined.
+@return TRUE if undefined */
UNIV_INTERN
ibool
fil_addr_is_null(
/*=============*/
- /* out: TRUE if undefined */
- fil_addr_t addr) /* in: address */
+ fil_addr_t addr) /*!< in: address */
{
return(addr.page == FIL_NULL);
}
-/************************************************************************
-Accessor functions for a file page */
+/********************************************************************//**
+Get the predecessor of a file page.
+@return FIL_PAGE_PREV */
UNIV_INTERN
ulint
-fil_page_get_prev(const byte* page)
+fil_page_get_prev(
+/*==============*/
+ const byte* page) /*!< in: file page */
{
return(mach_read_from_4(page + FIL_PAGE_PREV));
}
+/********************************************************************//**
+Get the successor of a file page.
+@return FIL_PAGE_NEXT */
UNIV_INTERN
ulint
-fil_page_get_next(const byte* page)
+fil_page_get_next(
+/*==============*/
+ const byte* page) /*!< in: file page */
{
return(mach_read_from_4(page + FIL_PAGE_NEXT));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the file page type. */
UNIV_INTERN
void
fil_page_set_type(
/*==============*/
- byte* page, /* in: file page */
- ulint type) /* in: type */
+ byte* page, /*!< in/out: file page */
+ ulint type) /*!< in: type */
{
ut_ad(page);
mach_write_to_2(page + FIL_PAGE_TYPE, type);
}
-/*************************************************************************
-Gets the file page type. */
+/*********************************************************************//**
+Gets the file page type.
+@return type; NOTE that if the type has not been written to page, the
+return value not defined */
UNIV_INTERN
ulint
fil_page_get_type(
/*==============*/
- /* out: type; NOTE that if the type
- has not been written to page, the return value
- not defined */
- const byte* page) /* in: file page */
+ const byte* page) /*!< in: file page */
{
ut_ad(page);
return(mach_read_from_2(page + FIL_PAGE_TYPE));
}
+/********************************************************************
+Initializes the tablespace memory cache. */
+UNIV_INTERN
+void
+fil_close(void)
+/*===========*/
+{
+ /* The mutex should already have been freed. */
+ ut_ad(fil_system->mutex.magic_n == 0);
+
+ hash_table_free(fil_system->spaces);
+
+ 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(UT_LIST_GET_LEN(fil_system->space_list) == 0);
+
+ mem_free(fil_system);
+
+ fil_system = NULL;
+}
+
/*************************************************************************
Return local hash table informations. */
diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c
index 25d260daeea..3cc4318fc06 100644
--- a/storage/xtradb/fsp/fsp0fsp.c
+++ b/storage/xtradb/fsp/fsp0fsp.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file fsp/fsp0fsp.c
File space management
Created 11/29/1995 Heikki Tuuri
@@ -30,18 +31,23 @@ Created 11/29/1995 Heikki Tuuri
#include "buf0buf.h"
#include "fil0fil.h"
-#include "sync0sync.h"
#include "mtr0log.h"
-#include "fut0fut.h"
#include "ut0byte.h"
-#include "srv0srv.h"
+#include "page0page.h"
#include "page0zip.h"
-#include "ibuf0ibuf.h"
-#include "btr0btr.h"
-#include "btr0sea.h"
-#include "dict0boot.h"
+#ifdef UNIV_HOTBACKUP
+# include "fut0lst.h"
+#else /* UNIV_HOTBACKUP */
+# include "sync0sync.h"
+# include "fut0fut.h"
+# include "srv0srv.h"
+# include "ibuf0ibuf.h"
+# include "btr0btr.h"
+# include "btr0sea.h"
+# include "dict0boot.h"
+# include "log0log.h"
+#endif /* UNIV_HOTBACKUP */
#include "dict0mem.h"
-#include "log0log.h"
#define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header
@@ -225,69 +231,73 @@ the extent are free and which contain old tuple version to clean. */
/* Offset of the descriptor array on a descriptor page */
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/* Flag to indicate if we have printed the tablespace full error. */
+static ibool fsp_tbs_full_error_printed = FALSE;
+
+/**********************************************************************//**
Returns an extent to the free list of a space. */
static
void
fsp_free_extent(
/*============*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset in the extent */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ ulint page, /*!< in: page offset in the extent */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Frees an extent of a segment to the space free list. */
static
void
fseg_free_extent(
/*=============*/
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset in the extent */
- mtr_t* mtr); /* in: mtr handle */
-/**************************************************************************
+ ulint page, /*!< in: page offset in the extent */
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how
-many pages are currently used. */
+many pages are currently used.
+@return number of reserved pages */
static
ulint
fseg_n_reserved_pages_low(
/*======================*/
- /* out: number of reserved pages */
- fseg_inode_t* header, /* in: segment inode */
- ulint* used, /* out: number of pages used (<= reserved) */
- mtr_t* mtr); /* in: mtr handle */
-/************************************************************************
+ fseg_inode_t* header, /*!< in: segment inode */
+ ulint* used, /*!< out: number of pages used (not
+ more than reserved) */
+ mtr_t* mtr); /*!< in: mtr handle */
+/********************************************************************//**
Marks a page used. The page must reside within the extents of the given
segment. */
static
void
fseg_mark_page_used(
/*================*/
- fseg_inode_t* seg_inode,/* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode,/*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Returns the first extent descriptor for a segment. We think of the extent
lists of the segment catenated in the order FSEG_FULL -> FSEG_NOT_FULL
--> FSEG_FREE. */
+-> FSEG_FREE.
+@return the first extent descriptor, or NULL if none */
static
xdes_t*
fseg_get_first_extent(
/*==================*/
- /* out: the first extent descriptor, or NULL if
- none */
- fseg_inode_t* inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Puts new extents to the free list if
there are free extents above the free limit. If an extent happens
to contain an extent descriptor page, the extent is put to
@@ -296,60 +306,60 @@ static
void
fsp_fill_free_list(
/*===============*/
- ibool init_space, /* in: TRUE if this is a single-table
+ ibool init_space, /*!< in: TRUE if this is a single-table
tablespace and we are only initing
the tablespace's first extent
descriptor page and ibuf bitmap page;
then we do not allocate more extents */
- ulint space, /* in: space */
- fsp_header_t* header, /* in: space header */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ ulint space, /*!< in: space */
+ fsp_header_t* header, /*!< in: space header */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return the allocated page number, FIL_NULL if no page could be allocated */
static
ulint
fseg_alloc_free_page_low(
/*=====================*/
- /* out: the allocated page number, FIL_NULL
- if no page could be allocated */
- ulint space, /* in: space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction, /* in: if the new page is needed because
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction, /*!< in: 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 */
- mtr_t* mtr); /* in: mtr handle */
-
+ mtr_t* mtr); /*!< in: mtr handle */
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Reads the file space size stored in the header page. */
+/**********************************************************************//**
+Reads the file space size stored in the header page.
+@return tablespace size stored in the space header */
UNIV_INTERN
ulint
fsp_get_size_low(
/*=============*/
- /* out: tablespace size stored in the space header */
- page_t* page) /* in: header page (page 0 in the tablespace) */
+ page_t* page) /*!< in: header page (page 0 in the tablespace) */
{
return(mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SIZE));
}
-/**************************************************************************
-Gets a pointer to the space header and x-locks its page. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Gets a pointer to the space header and x-locks its page.
+@return pointer to the space header, page x-locked */
UNIV_INLINE
fsp_header_t*
fsp_get_space_header(
/*=================*/
- /* out: pointer to the space header, page x-locked */
- ulint id, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint id, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
fsp_header_t* header;
@@ -369,18 +379,18 @@ fsp_get_space_header(
return(header);
}
-/**************************************************************************
-Gets a descriptor bit of a page. */
+/**********************************************************************//**
+Gets a descriptor bit of a page.
+@return TRUE if free */
UNIV_INLINE
ibool
xdes_get_bit(
/*=========*/
- /* out: TRUE if free */
- xdes_t* descr, /* in: descriptor */
- ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
- ulint offset, /* in: page offset within extent:
+ xdes_t* descr, /*!< in: descriptor */
+ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ulint offset, /*!< in: page offset within extent:
0 ... FSP_EXTENT_SIZE - 1 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint index;
ulint byte_index;
@@ -400,18 +410,18 @@ xdes_get_bit(
bit_index));
}
-/**************************************************************************
+/**********************************************************************//**
Sets a descriptor bit of a page. */
UNIV_INLINE
void
xdes_set_bit(
/*=========*/
- xdes_t* descr, /* in: descriptor */
- ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
- ulint offset, /* in: page offset within extent:
+ xdes_t* descr, /*!< in: descriptor */
+ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ulint offset, /*!< in: page offset within extent:
0 ... FSP_EXTENT_SIZE - 1 */
- ibool val, /* in: bit value */
- mtr_t* mtr) /* in: mtr */
+ ibool val, /*!< in: bit value */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint index;
ulint byte_index;
@@ -435,21 +445,20 @@ xdes_set_bit(
MLOG_1BYTE, mtr);
}
-/**************************************************************************
+/**********************************************************************//**
Looks for a descriptor bit having the desired value. Starts from hint
and scans upward; at the end of the extent the search is wrapped to
-the start of the extent. */
+the start of the extent.
+@return bit index of the bit, ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
xdes_find_bit(
/*==========*/
- /* out: bit index of the bit, ULINT_UNDEFINED if not
- found */
- xdes_t* descr, /* in: descriptor */
- ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
- ibool val, /* in: desired bit value */
- ulint hint, /* in: hint of which bit position would be desirable */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ibool val, /*!< in: desired bit value */
+ ulint hint, /*!< in: hint of which bit position would be desirable */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
@@ -474,20 +483,19 @@ xdes_find_bit(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
+/**********************************************************************//**
Looks for a descriptor bit having the desired value. Scans the extent in
-a direction opposite to xdes_find_bit. */
+a direction opposite to xdes_find_bit.
+@return bit index of the bit, ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
xdes_find_bit_downward(
/*===================*/
- /* out: bit index of the bit, ULINT_UNDEFINED if not
- found */
- xdes_t* descr, /* in: descriptor */
- ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
- ibool val, /* in: desired bit value */
- ulint hint, /* in: hint of which bit position would be desirable */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ibool val, /*!< in: desired bit value */
+ ulint hint, /*!< in: hint of which bit position would be desirable */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
@@ -512,15 +520,15 @@ xdes_find_bit_downward(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Returns the number of used pages in a descriptor. */
+/**********************************************************************//**
+Returns the number of used pages in a descriptor.
+@return number of pages used */
UNIV_INLINE
ulint
xdes_get_n_used(
/*============*/
- /* out: number of pages used */
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
ulint count = 0;
@@ -536,15 +544,15 @@ xdes_get_n_used(
return(count);
}
-/**************************************************************************
-Returns true if extent contains no used pages. */
+/**********************************************************************//**
+Returns true if extent contains no used pages.
+@return TRUE if totally free */
UNIV_INLINE
ibool
xdes_is_free(
/*=========*/
- /* out: TRUE if totally free */
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
if (0 == xdes_get_n_used(descr, mtr)) {
@@ -554,15 +562,15 @@ xdes_is_free(
return(FALSE);
}
-/**************************************************************************
-Returns true if extent contains no free pages. */
+/**********************************************************************//**
+Returns true if extent contains no free pages.
+@return TRUE if full */
UNIV_INLINE
ibool
xdes_is_full(
/*=========*/
- /* out: TRUE if full */
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) {
@@ -572,15 +580,15 @@ xdes_is_full(
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Sets the state of an xdes. */
UNIV_INLINE
void
xdes_set_state(
/*===========*/
- xdes_t* descr, /* in: descriptor */
- ulint state, /* in: state to set */
- mtr_t* mtr) /* in: mtr handle */
+ xdes_t* descr, /*!< in: descriptor */
+ ulint state, /*!< in: state to set */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ut_ad(descr && mtr);
ut_ad(state >= XDES_FREE);
@@ -590,15 +598,15 @@ xdes_set_state(
mlog_write_ulint(descr + XDES_STATE, state, MLOG_4BYTES, mtr);
}
-/**************************************************************************
-Gets the state of an xdes. */
+/**********************************************************************//**
+Gets the state of an xdes.
+@return state */
UNIV_INLINE
ulint
xdes_get_state(
/*===========*/
- /* out: state */
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr handle */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint state;
@@ -610,14 +618,14 @@ xdes_get_state(
return(state);
}
-/**************************************************************************
+/**********************************************************************//**
Inits an extent descriptor to the free and clean state. */
UNIV_INLINE
void
xdes_init(
/*======*/
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
@@ -632,25 +640,27 @@ xdes_init(
xdes_set_state(descr, XDES_FREE, mtr);
}
-/************************************************************************
-Calculates the page where the descriptor of a page resides. */
+/********************************************************************//**
+Calculates the page where the descriptor of a page resides.
+@return descriptor page offset */
UNIV_INLINE
ulint
xdes_calc_descriptor_page(
/*======================*/
- /* out: descriptor page offset */
- ulint zip_size, /* in: compressed page size in bytes;
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint offset) /* in: page offset */
+ ulint offset) /*!< in: page offset */
{
-#if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
+#ifndef DOXYGEN /* Doxygen gets confused of these */
+# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
+ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
-# error
-#endif
-#if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
+# error
+# endif
+# if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
+ (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
-# error
-#endif
+# error
+# endif
+#endif /* !DOXYGEN */
ut_ad(ut_is_2pow(zip_size));
if (!zip_size) {
@@ -662,16 +672,16 @@ xdes_calc_descriptor_page(
}
}
-/************************************************************************
-Calculates the descriptor index within a descriptor page. */
+/********************************************************************//**
+Calculates the descriptor index within a descriptor page.
+@return descriptor index */
UNIV_INLINE
ulint
xdes_calc_descriptor_index(
/*=======================*/
- /* out: descriptor index */
- ulint zip_size, /* in: compressed page size in bytes;
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint offset) /* in: page offset */
+ ulint offset) /*!< in: page offset */
{
ut_ad(ut_is_2pow(zip_size));
@@ -683,26 +693,25 @@ xdes_calc_descriptor_index(
}
}
-/************************************************************************
+/********************************************************************//**
Gets pointer to a the extent descriptor of a page. The page where the extent
descriptor resides is x-locked. If the page offset is equal to the free limit
of the space, adds new extents from above the free limit to the space free
list, if not free limit == space size. This adding is necessary to make the
-descriptor defined, as they are uninitialized above the free limit. */
+descriptor defined, as they are uninitialized above the free limit.
+@return pointer to the extent descriptor, NULL if the page does not
+exist in the space or if the offset exceeds the free limit */
UNIV_INLINE
xdes_t*
xdes_get_descriptor_with_space_hdr(
/*===============================*/
- /* out: pointer to the extent descriptor,
- NULL if the page does not exist in the
- space or if offset > free limit */
- fsp_header_t* sp_header,/* in: space header, x-latched */
- ulint space, /* in: space id */
- ulint offset, /* in: page offset;
+ fsp_header_t* sp_header,/*!< in: space header, x-latched */
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: page offset;
if equal to the free limit,
we try to add new extents to
the space free list */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint limit;
ulint size;
@@ -755,26 +764,25 @@ xdes_get_descriptor_with_space_hdr(
+ XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset));
}
-/************************************************************************
+/********************************************************************//**
Gets pointer to a the extent descriptor of a page. The page where the
extent descriptor resides is x-locked. If the page offset is equal to
the free limit of the space, adds new extents from above the free limit
to the space free list, if not free limit == space size. This adding
is necessary to make the descriptor defined, as they are uninitialized
-above the free limit. */
+above the free limit.
+@return pointer to the extent descriptor, NULL if the page does not
+exist in the space or if the offset exceeds the free limit */
static
xdes_t*
xdes_get_descriptor(
/*================*/
- /* out: pointer to the extent descriptor, NULL if the
- page does not exist in the space or if offset > free
- limit */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint offset, /* in: page offset; if equal to the free limit,
+ ulint offset, /*!< in: page offset; if equal to the free limit,
we try to add new extents to the space free list */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
buf_block_t* block;
fsp_header_t* sp_header;
@@ -787,21 +795,21 @@ xdes_get_descriptor(
mtr));
}
-/************************************************************************
+/********************************************************************//**
Gets pointer to a the extent descriptor if the file address
of the descriptor list node is known. The page where the
-extent descriptor resides is x-locked. */
+extent descriptor resides is x-locked.
+@return pointer to the extent descriptor */
UNIV_INLINE
xdes_t*
xdes_lst_get_descriptor(
/*====================*/
- /* out: pointer to the extent descriptor */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fil_addr_t lst_node,/* in: file address of the list node
+ fil_addr_t lst_node,/*!< in: file address of the list node
contained in the descriptor */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
xdes_t* descr;
@@ -814,14 +822,14 @@ xdes_lst_get_descriptor(
return(descr);
}
-/************************************************************************
-Returns page offset of the first page in extent described by a descriptor. */
+/********************************************************************//**
+Returns page offset of the first page in extent described by a descriptor.
+@return offset of the first page in extent */
UNIV_INLINE
ulint
xdes_get_offset(
/*============*/
- /* out: offset of the first page in extent */
- xdes_t* descr) /* in: extent descriptor */
+ xdes_t* descr) /*!< in: extent descriptor */
{
ut_ad(descr);
@@ -829,19 +837,22 @@ xdes_get_offset(
+ ((page_offset(descr) - XDES_ARR_OFFSET) / XDES_SIZE)
* FSP_EXTENT_SIZE);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
+/***********************************************************//**
Inits a file page whose prior contents should be ignored. */
static
void
fsp_init_file_page_low(
/*===================*/
- buf_block_t* block) /* in: pointer to a page */
+ buf_block_t* block) /*!< in: pointer to a page */
{
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip= buf_block_get_page_zip(block);
+#ifndef UNIV_HOTBACKUP
block->check_index_page_at_flush = FALSE;
+#endif /* !UNIV_HOTBACKUP */
if (UNIV_LIKELY_NULL(page_zip)) {
memset(page, 0, UNIV_PAGE_SIZE);
@@ -868,31 +879,33 @@ fsp_init_file_page_low(
memset(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, 0, 8);
}
-/***************************************************************
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
Inits a file page whose prior contents should be ignored. */
static
void
fsp_init_file_page(
/*===============*/
- buf_block_t* block, /* in: pointer to a page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: pointer to a page */
+ mtr_t* mtr) /*!< in: mtr */
{
fsp_init_file_page_low(block);
mlog_write_initial_log_record(buf_block_get_frame(block),
MLOG_INIT_FILE_PAGE, mtr);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of a file page init. */
+/***********************************************************//**
+Parses a redo log record of a file page init.
+@return end of log record or NULL */
UNIV_INTERN
byte*
fsp_parse_init_file_page(
/*=====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- buf_block_t* block) /* in: block or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ buf_block_t* block) /*!< in: block or NULL */
{
ut_ad(ptr && end_ptr);
@@ -903,7 +916,7 @@ fsp_parse_init_file_page(
return(ptr);
}
-/**************************************************************************
+/**********************************************************************//**
Initializes the fsp system. */
UNIV_INTERN
void
@@ -913,7 +926,7 @@ fsp_init(void)
/* Does nothing at the moment */
}
-/**************************************************************************
+/**********************************************************************//**
Writes the space id and compressed page size to a tablespace header.
This function is used past the buffer pool when we in fil0fil.c create
a new single-table tablespace. */
@@ -921,9 +934,9 @@ UNIV_INTERN
void
fsp_header_init_fields(
/*===================*/
- page_t* page, /* in/out: first page in the space */
- ulint space_id, /* in: space id */
- ulint flags) /* in: tablespace flags (FSP_SPACE_FLAGS):
+ page_t* page, /*!< in/out: first page in the space */
+ ulint space_id, /*!< in: space id */
+ ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */
{
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
@@ -938,16 +951,17 @@ fsp_header_init_fields(
flags);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Initializes the space header of a new created space and creates also the
insert buffer tree root if space == 0. */
UNIV_INTERN
void
fsp_header_init(
/*============*/
- ulint space, /* in: space id */
- ulint size, /* in: current size in blocks */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint space, /*!< in: space id */
+ ulint size, /*!< in: current size in blocks */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fsp_header_t* header;
buf_block_t* block;
@@ -994,20 +1008,21 @@ fsp_header_init(
fsp_fill_free_list(FALSE, space, header, mtr);
btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
0, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
} else {
fsp_fill_free_list(TRUE, space, header, mtr);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Reads the space id from the first page of a tablespace. */
+/**********************************************************************//**
+Reads the space id from the first page of a tablespace.
+@return space id, ULINT UNDEFINED if error */
UNIV_INTERN
ulint
fsp_header_get_space_id(
/*====================*/
- /* out: space id, ULINT UNDEFINED if error */
- const page_t* page) /* in: first page of a tablespace */
+ const page_t* page) /*!< in: first page of a tablespace */
{
ulint fsp_id;
ulint id;
@@ -1028,44 +1043,44 @@ fsp_header_get_space_id(
return(id);
}
-/**************************************************************************
-Reads the space flags from the first page of a tablespace. */
+/**********************************************************************//**
+Reads the space flags from the first page of a tablespace.
+@return flags */
UNIV_INTERN
ulint
fsp_header_get_flags(
/*=================*/
- /* out: flags */
- const page_t* page) /* in: first page of a tablespace */
+ const page_t* page) /*!< in: first page of a tablespace */
{
ut_ad(!page_offset(page));
return(mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page));
}
-/**************************************************************************
-Reads the compressed page size from the first page of a tablespace. */
+/**********************************************************************//**
+Reads the compressed page size from the first page of a tablespace.
+@return compressed page size in bytes, or 0 if uncompressed */
UNIV_INTERN
ulint
fsp_header_get_zip_size(
/*====================*/
- /* out: compressed page size in bytes,
- or 0 if uncompressed */
- const page_t* page) /* in: first page of a tablespace */
+ const page_t* page) /*!< in: first page of a tablespace */
{
ulint flags = fsp_header_get_flags(page);
return(dict_table_flags_to_zip_size(flags));
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Increases the space size field of a space. */
UNIV_INTERN
void
fsp_header_inc_size(
/*================*/
- ulint space, /* in: space id */
- ulint size_inc,/* in: size increment in pages */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint space, /*!< in: space id */
+ ulint size_inc,/*!< in: size increment in pages */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fsp_header_t* header;
ulint size;
@@ -1085,16 +1100,16 @@ fsp_header_inc_size(
mtr);
}
-/**************************************************************************
+/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
-means the place of the first page which has never been put to the the
+means the place of the first page which has never been put to the
free list for allocation. The space above that address is initialized
-to zero. Sets also the global variable log_fsp_current_free_limit. */
+to zero. Sets also the global variable log_fsp_current_free_limit.
+@return free limit in megabytes */
UNIV_INTERN
ulint
fsp_header_get_free_limit(void)
/*===========================*/
- /* out: free limit in megabytes */
{
fsp_header_t* header;
ulint limit;
@@ -1117,16 +1132,16 @@ fsp_header_get_free_limit(void)
return(limit);
}
-/**************************************************************************
+/**********************************************************************//**
Gets the size of the system tablespace from the tablespace header. If
we do not have an auto-extending data file, this should be equal to
the size of the data files. If there is an auto-extending data file,
-this can be smaller. */
+this can be smaller.
+@return size in pages */
UNIV_INTERN
ulint
fsp_header_get_tablespace_size(void)
/*================================*/
- /* out: size in pages */
{
fsp_header_t* header;
ulint size;
@@ -1145,18 +1160,18 @@ fsp_header_get_tablespace_size(void)
return(size);
}
-/***************************************************************************
+/***********************************************************************//**
Tries to extend a single-table tablespace so that a page would fit in the
-data file. */
+data file.
+@return TRUE if success */
static
ibool
fsp_try_extend_data_file_with_pages(
/*================================*/
- /* out: TRUE if success */
- ulint space, /* in: space */
- ulint page_no, /* in: page number */
- fsp_header_t* header, /* in: space header */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space */
+ ulint page_no, /*!< in: page number */
+ fsp_header_t* header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool success;
ulint actual_size;
@@ -1178,21 +1193,21 @@ fsp_try_extend_data_file_with_pages(
return(success);
}
-/***************************************************************************
-Tries to extend the last data file of a tablespace if it is auto-extending. */
+/***********************************************************************//**
+Tries to extend the last data file of a tablespace if it is auto-extending.
+@return FALSE if not auto-extending */
static
ibool
fsp_try_extend_data_file(
/*=====================*/
- /* out: FALSE if not auto-extending */
- ulint* actual_increase,/* out: actual increase in pages, where
+ ulint* actual_increase,/*!< out: actual increase in pages, where
we measure the tablespace size from
what the header field says; it may be
the actual file size rounded down to
megabyte */
- ulint space, /* in: space */
- fsp_header_t* header, /* in: space header */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space */
+ fsp_header_t* header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint size;
ulint zip_size;
@@ -1206,6 +1221,19 @@ fsp_try_extend_data_file(
if (space == 0 && !srv_auto_extend_last_data_file) {
+ /* We print the error message only once to avoid
+ spamming the error log. Note that we don't need
+ to reset the flag to FALSE as dealing with this
+ error requires server restart. */
+ if (fsp_tbs_full_error_printed == FALSE) {
+ fprintf(stderr,
+ "InnoDB: Error: Data file(s) ran"
+ " out of space.\n"
+ "Please add another data file or"
+ " use \'autoextend\' for the last"
+ " data file.\n");
+ fsp_tbs_full_error_printed = TRUE;
+ }
return(FALSE);
}
@@ -1241,7 +1269,7 @@ fsp_try_extend_data_file(
at a time, but for bigger tablespaces more. It is not
enough to extend always by one extent, because some
extents are frag page extents. */
- ulint extent_size; /* one megabyte, in pages */
+ ulint extent_size; /*!< one megabyte, in pages */
if (!zip_size) {
extent_size = FSP_EXTENT_SIZE;
@@ -1300,7 +1328,7 @@ fsp_try_extend_data_file(
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Puts new extents to the free list if there are free extents above the free
limit. If an extent happens to contain an extent descriptor page, the extent
is put to the FSP_FREE_FRAG list with the page marked as used. */
@@ -1308,14 +1336,14 @@ static
void
fsp_fill_free_list(
/*===============*/
- ibool init_space, /* in: TRUE if this is a single-table
+ ibool init_space, /*!< in: TRUE if this is a single-table
tablespace and we are only initing
the tablespace's first extent
descriptor page and ibuf bitmap page;
then we do not allocate more extents */
- ulint space, /* in: space */
- fsp_header_t* header, /* in: space header */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space */
+ fsp_header_t* header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint limit;
ulint size;
@@ -1463,21 +1491,20 @@ fsp_fill_free_list(
}
}
-/**************************************************************************
-Allocates a new free extent. */
+/**********************************************************************//**
+Allocates a new free extent.
+@return extent descriptor, NULL if cannot be allocated */
static
xdes_t*
fsp_alloc_free_extent(
/*==================*/
- /* out: extent descriptor, NULL if cannot be
- allocated */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint hint, /* in: hint of which extent would be desirable: any
+ ulint hint, /*!< in: hint of which extent would be desirable: any
page offset in the extent goes; the hint must not
be > FSP_FREE_LIMIT */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
fsp_header_t* header;
fil_addr_t first;
@@ -1514,19 +1541,18 @@ fsp_alloc_free_extent(
return(descr);
}
-/**************************************************************************
-Allocates a single free page from a space. The page is marked as used. */
+/**********************************************************************//**
+Allocates a single free page from a space. The page is marked as used.
+@return the page offset, FIL_NULL if no page could be allocated */
static
ulint
fsp_alloc_free_page(
/*================*/
- /* out: the page offset, FIL_NULL if no page could
- be allocated */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint hint, /* in: hint of which page would be desirable */
- mtr_t* mtr) /* in: mtr handle */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fsp_header_t* header;
fil_addr_t first;
@@ -1656,17 +1682,17 @@ fsp_alloc_free_page(
return(page_no);
}
-/**************************************************************************
+/**********************************************************************//**
Frees a single page of a space. The page is marked as free and clean. */
static
void
fsp_free_page(
/*==========*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset */
- mtr_t* mtr) /* in: mtr handle */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fsp_header_t* header;
xdes_t* descr;
@@ -1746,17 +1772,17 @@ fsp_free_page(
}
}
-/**************************************************************************
+/**********************************************************************//**
Returns an extent to the free list of a space. */
static
void
fsp_free_extent(
/*============*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset in the extent */
- mtr_t* mtr) /* in: mtr */
+ ulint page, /*!< in: page offset in the extent */
+ mtr_t* mtr) /*!< in: mtr */
{
fsp_header_t* header;
xdes_t* descr;
@@ -1780,19 +1806,19 @@ fsp_free_extent(
flst_add_last(header + FSP_FREE, descr + XDES_FLST_NODE, mtr);
}
-/**************************************************************************
-Returns the nth inode slot on an inode page. */
+/**********************************************************************//**
+Returns the nth inode slot on an inode page.
+@return segment inode */
UNIV_INLINE
fseg_inode_t*
fsp_seg_inode_page_get_nth_inode(
/*=============================*/
- /* out: segment inode */
- page_t* page, /* in: segment inode page */
- ulint i, /* in: inode index on page */
+ page_t* page, /*!< in: segment inode page */
+ ulint i, /*!< in: inode index on page */
ulint zip_size __attribute__((unused)),
- /* in: compressed page size, or 0 */
+ /*!< in: compressed page size, or 0 */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(i < FSP_SEG_INODES_PER_PAGE(zip_size));
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
@@ -1800,17 +1826,16 @@ fsp_seg_inode_page_get_nth_inode(
return(page + FSEG_ARR_OFFSET + FSEG_INODE_SIZE * i);
}
-/**************************************************************************
-Looks for a used segment inode on a segment inode page. */
+/**********************************************************************//**
+Looks for a used segment inode on a segment inode page.
+@return segment inode index, or ULINT_UNDEFINED if not found */
static
ulint
fsp_seg_inode_page_find_used(
/*=========================*/
- /* out: segment inode index, or ULINT_UNDEFINED
- if not found */
- page_t* page, /* in: segment inode page */
- ulint zip_size,/* in: compressed page size, or 0 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ page_t* page, /*!< in: segment inode page */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint i;
fseg_inode_t* inode;
@@ -1823,6 +1848,8 @@ fsp_seg_inode_page_find_used(
if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
/* This is used */
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
return(i);
}
}
@@ -1830,18 +1857,17 @@ fsp_seg_inode_page_find_used(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Looks for an unused segment inode on a segment inode page. */
+/**********************************************************************//**
+Looks for an unused segment inode on a segment inode page.
+@return segment inode index, or ULINT_UNDEFINED if not found */
static
ulint
fsp_seg_inode_page_find_free(
/*=========================*/
- /* out: segment inode index, or ULINT_UNDEFINED
- if not found */
- page_t* page, /* in: segment inode page */
- ulint i, /* in: search forward starting from this index */
- ulint zip_size,/* in: compressed page size, or 0 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ page_t* page, /*!< in: segment inode page */
+ ulint i, /*!< in: search forward starting from this index */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fseg_inode_t* inode;
@@ -1855,20 +1881,23 @@ fsp_seg_inode_page_find_free(
return(i);
}
+
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
}
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Allocates a new file segment inode page. */
+/**********************************************************************//**
+Allocates a new file segment inode page.
+@return TRUE if could be allocated */
static
ibool
fsp_alloc_seg_inode_page(
/*=====================*/
- /* out: TRUE if could be allocated */
- fsp_header_t* space_header, /* in: space header */
- mtr_t* mtr) /* in: mini-transaction handle */
+ fsp_header_t* space_header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fseg_inode_t* inode;
buf_block_t* block;
@@ -1914,16 +1943,15 @@ fsp_alloc_seg_inode_page(
return(TRUE);
}
-/**************************************************************************
-Allocates a new file segment inode. */
+/**********************************************************************//**
+Allocates a new file segment inode.
+@return segment inode, or NULL if not enough space */
static
fseg_inode_t*
fsp_alloc_seg_inode(
/*================*/
- /* out: segment inode, or NULL if
- not enough space */
- fsp_header_t* space_header, /* in: space header */
- mtr_t* mtr) /* in: mini-transaction handle */
+ fsp_header_t* space_header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint page_no;
buf_block_t* block;
@@ -1974,20 +2002,22 @@ fsp_alloc_seg_inode(
page + FSEG_INODE_PAGE_NODE, mtr);
}
+ ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))
+ || mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
return(inode);
}
-/**************************************************************************
+/**********************************************************************//**
Frees a file segment inode. */
static
void
fsp_free_seg_inode(
/*===============*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mini-transaction handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
page_t* page;
fsp_header_t* space_header;
@@ -2011,7 +2041,7 @@ fsp_free_seg_inode(
}
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
- mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
+ mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr);
if (ULINT_UNDEFINED
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
@@ -2025,18 +2055,18 @@ fsp_free_seg_inode(
}
}
-/**************************************************************************
-Returns the file segment inode, page x-latched. */
+/**********************************************************************//**
+Returns the file segment inode, page x-latched.
+@return segment inode, page x-latched; NULL if the inode is free */
static
fseg_inode_t*
-fseg_inode_get(
-/*===========*/
- /* out: segment inode, page x-latched */
- fseg_header_t* header, /* in: segment header */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+fseg_inode_try_get(
+/*===============*/
+ fseg_header_t* header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fil_addr_t inode_addr;
fseg_inode_t* inode;
@@ -2047,58 +2077,85 @@ fseg_inode_get(
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
- ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
+ if (UNIV_UNLIKELY
+ (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
+
+ inode = NULL;
+ } else {
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
+ }
return(inode);
}
-/**************************************************************************
-Gets the page number from the nth fragment page slot. */
+/**********************************************************************//**
+Returns the file segment inode, page x-latched.
+@return segment inode, page x-latched */
+static
+fseg_inode_t*
+fseg_inode_get(
+/*===========*/
+ fseg_header_t* header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
+ mtr_t* mtr) /*!< in: mtr handle */
+{
+ fseg_inode_t* inode
+ = fseg_inode_try_get(header, space, zip_size, mtr);
+ ut_a(inode);
+ return(inode);
+}
+
+/**********************************************************************//**
+Gets the page number from the nth fragment page slot.
+@return page number, FIL_NULL if not in use */
UNIV_INLINE
ulint
fseg_get_nth_frag_page_no(
/*======================*/
- /* out: page number, FIL_NULL if not in use */
- fseg_inode_t* inode, /* in: segment inode */
- ulint n, /* in: slot index */
- mtr_t* mtr __attribute__((unused))) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint n, /*!< in: slot index */
+ mtr_t* mtr __attribute__((unused))) /*!< in: mtr handle */
{
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
return(mach_read_from_4(inode + FSEG_FRAG_ARR
+ n * FSEG_FRAG_SLOT_SIZE));
}
-/**************************************************************************
+/**********************************************************************//**
Sets the page number in the nth fragment page slot. */
UNIV_INLINE
void
fseg_set_nth_frag_page_no(
/*======================*/
- fseg_inode_t* inode, /* in: segment inode */
- ulint n, /* in: slot index */
- ulint page_no,/* in: page number to set */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint n, /*!< in: slot index */
+ ulint page_no,/*!< in: page number to set */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
page_no, MLOG_4BYTES, mtr);
}
-/**************************************************************************
-Finds a fragment page slot which is free. */
+/**********************************************************************//**
+Finds a fragment page slot which is free.
+@return slot index; ULINT_UNDEFINED if none found */
static
ulint
fseg_find_free_frag_page_slot(
/*==========================*/
- /* out: slot index; ULINT_UNDEFINED if none
- found */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint i;
ulint page_no;
@@ -2117,16 +2174,15 @@ fseg_find_free_frag_page_slot(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Finds a fragment page slot which is used and last in the array. */
+/**********************************************************************//**
+Finds a fragment page slot which is used and last in the array.
+@return slot index; ULINT_UNDEFINED if none found */
static
ulint
fseg_find_last_used_frag_page_slot(
/*===============================*/
- /* out: slot index; ULINT_UNDEFINED if none
- found */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint i;
ulint page_no;
@@ -2146,15 +2202,15 @@ fseg_find_last_used_frag_page_slot(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Calculates reserved fragment page slots. */
+/**********************************************************************//**
+Calculates reserved fragment page slots.
+@return number of fragment pages */
static
ulint
fseg_get_n_frag_pages(
/*==================*/
- /* out: number of fragment pages */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint i;
ulint count = 0;
@@ -2170,29 +2226,28 @@ fseg_get_n_frag_pages(
return(count);
}
-/**************************************************************************
-Creates a new segment. */
+/**********************************************************************//**
+Creates a new segment.
+@return the block where the segment header is placed, x-latched, NULL
+if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create_general(
/*================*/
- /* out: the block where the segment header is placed,
- x-latched, NULL if could not create segment
- because of lack of space */
- ulint space, /* in: space id */
- ulint page, /* in: page where the segment header is placed: if
+ 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
+ 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
+ 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: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint flags;
ulint zip_size;
@@ -2305,38 +2360,38 @@ funct_exit:
return(block);
}
-/**************************************************************************
-Creates a new segment. */
+/**********************************************************************//**
+Creates a new segment.
+@return the block where the segment header is placed, x-latched, NULL
+if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create(
/*========*/
- /* out: the block where the segment header is placed,
- x-latched, NULL if could not create segment
- because of lack of space */
- ulint space, /* in: space id */
- ulint page, /* in: page where the segment header is placed: if
+ 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
+ ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
return(fseg_create_general(space, page, byte_offset, FALSE, mtr));
}
-/**************************************************************************
+/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
-currently used. */
+currently used.
+@return number of reserved pages */
static
ulint
fseg_n_reserved_pages_low(
/*======================*/
- /* out: number of reserved pages */
- fseg_inode_t* inode, /* in: segment inode */
- ulint* used, /* out: number of pages used (<= reserved) */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint* used, /*!< out: number of pages used (not
+ more than reserved) */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint ret;
@@ -2355,17 +2410,17 @@ fseg_n_reserved_pages_low(
return(ret);
}
-/**************************************************************************
+/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
-currently used. */
+currently used.
+@return number of reserved pages */
UNIV_INTERN
ulint
fseg_n_reserved_pages(
/*==================*/
- /* out: number of reserved pages */
- fseg_header_t* header, /* in: segment header */
- ulint* used, /* out: number of pages used (<= reserved) */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_header_t* header, /*!< in: segment header */
+ ulint* used, /*!< out: number of pages used (<= reserved) */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint ret;
fseg_inode_t* inode;
@@ -2390,7 +2445,7 @@ fseg_n_reserved_pages(
return(ret);
}
-/*************************************************************************
+/*********************************************************************//**
Tries to fill the free list of a segment with consecutive free extents.
This happens if the segment is big enough to allow extents in the free list,
the free list is empty, and the extents can be allocated consecutively from
@@ -2399,13 +2454,13 @@ static
void
fseg_fill_free_list(
/*================*/
- fseg_inode_t* inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint hint, /* in: hint which extent would be good as
+ ulint hint, /*!< in: hint which extent would be good as
the first extent */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
ulint i;
@@ -2447,6 +2502,8 @@ fseg_fill_free_list(
xdes_set_state(descr, XDES_FSEG, mtr);
seg_id = mtr_read_dulint(inode + FSEG_ID, mtr);
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
mlog_write_dulint(descr + XDES_ID, seg_id, mtr);
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
@@ -2454,28 +2511,28 @@ fseg_fill_free_list(
}
}
-/*************************************************************************
+/*********************************************************************//**
Allocates a free extent for the segment: looks first in the free list of the
segment, then tries to allocate from the space free list. NOTE that the extent
-returned still resides in the segment free list, it is not yet taken off it! */
+returned still resides in the segment free list, it is not yet taken off it!
+@return allocated extent, still placed in the segment free list, NULL
+if could not be allocated */
static
xdes_t*
fseg_alloc_free_extent(
/*===================*/
- /* out: allocated extent, still placed in the
- segment free list, NULL if could
- not be allocated */
- fseg_inode_t* inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
dulint seg_id;
fil_addr_t first;
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
/* Segment free list is not empty, allocate from it */
@@ -2507,37 +2564,36 @@ fseg_alloc_free_extent(
return(descr);
}
-/**************************************************************************
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return the allocated page number, FIL_NULL if no page could be allocated */
static
ulint
fseg_alloc_free_page_low(
/*=====================*/
- /* out: the allocated page number, FIL_NULL
- if no page could be allocated */
- ulint space, /* in: space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction, /* in: if the new page is needed because
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction, /*!< in: 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 */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fsp_header_t* space_header;
ulint space_size;
dulint seg_id;
ulint used;
ulint reserved;
- xdes_t* descr; /* extent of the hinted page */
- ulint ret_page; /* the allocated page offset, FIL_NULL
+ xdes_t* descr; /*!< extent of the hinted page */
+ ulint ret_page; /*!< the allocated page offset, FIL_NULL
if could not be allocated */
- xdes_t* ret_descr; /* the extent of the allocated page */
+ xdes_t* ret_descr; /*!< the extent of the allocated page */
ibool frag_page_allocated = FALSE;
ibool success;
ulint n;
@@ -2756,29 +2812,28 @@ fseg_alloc_free_page_low(
return(ret_page);
}
-/**************************************************************************
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return allocated page offset, FIL_NULL if no page could be allocated */
UNIV_INTERN
ulint
fseg_alloc_free_page_general(
/*=========================*/
- /* out: allocated page offset, FIL_NULL if no
- page could be allocated */
- fseg_header_t* seg_header,/* in: segment header */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction,/* in: if the new page is needed because
+ fseg_header_t* seg_header,/*!< in: segment header */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction,/*!< in: 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 */
- ibool has_done_reservation, /* in: TRUE if the caller has
+ ibool has_done_reservation, /*!< in: TRUE if the caller has
already done the reservation for the page
with fsp_reserve_free_extents, then there
is no need to do the check for this individual
page */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fseg_inode_t* inode;
ulint space;
@@ -2828,47 +2883,45 @@ fseg_alloc_free_page_general(
return(page_no);
}
-/**************************************************************************
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return allocated page offset, FIL_NULL if no page could be allocated */
UNIV_INTERN
ulint
fseg_alloc_free_page(
/*=================*/
- /* out: allocated page offset, FIL_NULL if no
- page could be allocated */
- fseg_header_t* seg_header,/* in: segment header */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction,/* in: if the new page is needed because
+ fseg_header_t* seg_header,/*!< in: segment header */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction,/*!< in: 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 */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
return(fseg_alloc_free_page_general(seg_header, hint, direction,
FALSE, mtr));
}
-/**************************************************************************
+/**********************************************************************//**
Checks that we have at least 2 frag pages free in the first extent of a
single-table tablespace, and they are also physically initialized to the data
file. That is we have already extended the data file so that those pages are
inside the data file. If not, this function extends the tablespace with
-pages. */
+pages.
+@return TRUE if there were >= 3 free pages, or we were able to extend */
static
ibool
fsp_reserve_free_pages(
/*===================*/
- /* out: TRUE if there were >= 3 free
- pages, or we were able to extend */
- ulint space, /* in: space id, must be != 0 */
- fsp_header_t* space_header, /* in: header of that space,
+ ulint space, /*!< in: space id, must be != 0 */
+ fsp_header_t* space_header, /*!< in: header of that space,
x-latched */
- ulint size, /* in: size of the tablespace in pages,
+ ulint size, /*!< in: size of the tablespace in pages,
must be < FSP_EXTENT_SIZE / 2 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
ulint n_used;
@@ -2891,7 +2944,7 @@ fsp_reserve_free_pages(
space_header, mtr));
}
-/**************************************************************************
+/**********************************************************************//**
Reserves free pages from a tablespace. All mini-transactions which may
use several pages from the tablespace should call this function beforehand
and reserve enough free extents so that they certainly will be able
@@ -2915,19 +2968,19 @@ Single-table tablespaces whose size is < 32 pages are a special case. In this
function we would liberally reserve several 64 page extents for every page
split or merge in a B-tree. But we do not want to waste disk space if the table
only occupies < 32 pages. That is why we apply different rules in that special
-case, just ensuring that there are 3 free pages available. */
+case, just ensuring that there are 3 free pages available.
+@return TRUE if we were able to make the reservation */
UNIV_INTERN
ibool
fsp_reserve_free_extents(
/*=====================*/
- /* out: TRUE if we were able to make the reservation */
- ulint* n_reserved,/* out: number of extents actually reserved; if we
+ ulint* n_reserved,/*!< out: number of extents actually reserved; if we
return TRUE and the tablespace size is < 64 pages,
then this can be 0, otherwise it is n_ext */
- ulint space, /* in: space id */
- ulint n_ext, /* in: number of extents to reserve */
- ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space id */
+ ulint n_ext, /*!< in: number of extents to reserve */
+ ulint alloc_type,/*!< in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
+ mtr_t* mtr) /*!< in: mtr */
{
fsp_header_t* space_header;
rw_lock_t* latch;
@@ -3027,17 +3080,17 @@ try_to_extend:
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
This function should be used to get information on how much we still
will be able to insert new data to the database without running out the
tablespace. Only free extents are taken into account and we also subtract
-the safety margin required by the above function fsp_reserve_free_extents. */
+the safety margin required by the above function fsp_reserve_free_extents.
+@return available space in kB */
UNIV_INTERN
ullint
fsp_get_available_space_in_free_extents(
/*====================================*/
- /* out: available space in kB */
- ulint space) /* in: space id */
+ ulint space) /*!< in: space id */
{
fsp_header_t* space_header;
ulint n_free_list_ext;
@@ -3118,25 +3171,27 @@ fsp_get_available_space_in_free_extents(
}
}
-/************************************************************************
+/********************************************************************//**
Marks a page used. The page must reside within the extents of the given
segment. */
static
void
fseg_mark_page_used(
/*================*/
- fseg_inode_t* seg_inode,/* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode,/*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset */
- mtr_t* mtr) /* in: mtr */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
ulint not_full_n_used;
ut_ad(seg_inode && mtr);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
+ ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
descr = xdes_get_descriptor(space, zip_size, page, mtr);
@@ -3176,18 +3231,18 @@ fseg_mark_page_used(
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees a single page of a segment. */
static
void
fseg_free_page_low(
/*===============*/
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset */
- mtr_t* mtr) /* in: mtr handle */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr) /*!< in: mtr handle */
{
xdes_t* descr;
ulint not_full_n_used;
@@ -3225,8 +3280,7 @@ fseg_free_page_low(
"InnoDB: database!\n", (ulong) page);
crash:
fputs("InnoDB: Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
ut_error;
}
@@ -3316,16 +3370,16 @@ crash:
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees a single page of a segment. */
UNIV_INTERN
void
fseg_free_page(
/*===========*/
- fseg_header_t* seg_header, /* in: segment header */
- ulint space, /* in: space id */
- ulint page, /* in: page offset */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_header_t* seg_header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint flags;
ulint zip_size;
@@ -3349,18 +3403,18 @@ fseg_free_page(
#endif
}
-/**************************************************************************
+/**********************************************************************//**
Frees an extent of a segment to the space free list. */
static
void
fseg_free_extent(
/*=============*/
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: a page in the extent */
- mtr_t* mtr) /* in: mtr handle */
+ ulint page, /*!< in: a page in the extent */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint first_page_in_extent;
xdes_t* descr;
@@ -3375,6 +3429,8 @@ fseg_free_extent(
ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
mtr_read_dulint(seg_inode + FSEG_ID, mtr)));
+ ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
@@ -3420,21 +3476,21 @@ fseg_free_extent(
#endif
}
-/**************************************************************************
+/**********************************************************************//**
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. */
+mini-transaction.
+@return TRUE if freeing completed */
UNIV_INTERN
ibool
fseg_free_step(
/*===========*/
- /* out: TRUE if freeing completed */
- fseg_header_t* header, /* in, own: segment header; NOTE: if the header
+ 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 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint n;
ulint page;
@@ -3465,7 +3521,13 @@ fseg_free_step(
ut_a(descr);
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
- inode = fseg_inode_get(header, space, zip_size, mtr);
+ inode = fseg_inode_try_get(header, space, zip_size, mtr);
+
+ if (UNIV_UNLIKELY(inode == NULL)) {
+ fprintf(stderr, "double free of inode from %u:%u\n",
+ (unsigned) space, (unsigned) header_page);
+ return(TRUE);
+ }
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
@@ -3503,18 +3565,17 @@ fseg_free_step(
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Frees part of a segment. Differs from fseg_free_step because this function
-leaves the header page unfreed. */
+leaves the header page unfreed.
+@return TRUE if freeing completed, except the header page */
UNIV_INTERN
ibool
fseg_free_step_not_header(
/*======================*/
- /* out: TRUE if freeing completed, except the
- header page */
- fseg_header_t* header, /* in: segment header which must reside on
+ fseg_header_t* header, /*!< in: segment header which must reside on
the first fragment page of the segment */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint n;
ulint page;
@@ -3569,60 +3630,20 @@ fseg_free_step_not_header(
return(FALSE);
}
-/***********************************************************************
-Frees a segment. The freeing is performed in several mini-transactions,
-so that there is no danger of bufferfixing too many buffer pages. */
-UNIV_INTERN
-void
-fseg_free(
-/*======*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
- or 0 for uncompressed pages */
- ulint page_no,/* in: page number where the segment header is
- placed */
- ulint offset) /* in: byte offset of the segment header on that
- page */
-{
- mtr_t mtr;
- ibool finished;
- fseg_header_t* header;
- fil_addr_t addr;
-
- addr.page = page_no;
- addr.boffset = offset;
-
- for (;;) {
- mtr_start(&mtr);
-
- header = fut_get_ptr(space, zip_size, addr, RW_X_LATCH, &mtr);
-
- finished = fseg_free_step(header, &mtr);
-
- mtr_commit(&mtr);
-
- if (finished) {
-
- return;
- }
- }
-}
-
-/**************************************************************************
+/**********************************************************************//**
Returns the first extent descriptor for a segment. We think of the extent
lists of the segment catenated in the order FSEG_FULL -> FSEG_NOT_FULL
--> FSEG_FREE. */
+-> FSEG_FREE.
+@return the first extent descriptor, or NULL if none */
static
xdes_t*
fseg_get_first_extent(
/*==================*/
- /* out: the first extent descriptor, or NULL if
- none */
- fseg_inode_t* inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
fil_addr_t first;
xdes_t* descr;
@@ -3630,6 +3651,7 @@ fseg_get_first_extent(
ut_ad(inode && mtr);
ut_ad(space == page_get_space_id(page_align(inode)));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
first = fil_addr_null;
@@ -3655,15 +3677,15 @@ fseg_get_first_extent(
return(descr);
}
-/***********************************************************************
-Validates a segment. */
+/*******************************************************************//**
+Validates a segment.
+@return TRUE if ok */
static
ibool
fseg_validate_low(
/*==============*/
- /* out: TRUE if ok */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr2) /* in: mtr */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr2) /*!< in: mtr */
{
ulint space;
dulint seg_id;
@@ -3764,15 +3786,16 @@ fseg_validate_low(
return(TRUE);
}
-/***********************************************************************
-Validates a segment. */
+#ifdef UNIV_DEBUG
+/*******************************************************************//**
+Validates a segment.
+@return TRUE if ok */
UNIV_INTERN
ibool
fseg_validate(
/*==========*/
- /* out: TRUE if ok */
- fseg_header_t* header, /* in: segment header */
- mtr_t* mtr) /* in: mtr */
+ fseg_header_t* header, /*!< in: segment header */
+ mtr_t* mtr) /*!< in: mtr */
{
fseg_inode_t* inode;
ibool ret;
@@ -3791,15 +3814,16 @@ fseg_validate(
return(ret);
}
+#endif /* UNIV_DEBUG */
-/***********************************************************************
+/*******************************************************************//**
Writes info of a segment. */
static
void
fseg_print_low(
/*===========*/
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mtr */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint seg_id_low;
@@ -3842,17 +3866,18 @@ fseg_print_low(
(ulong) reserved, (ulong) used, (ulong) n_full,
(ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
(ulong) n_used);
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
}
#ifdef UNIV_BTR_PRINT
-/***********************************************************************
+/*******************************************************************//**
Writes info of a segment. */
UNIV_INTERN
void
fseg_print(
/*=======*/
- fseg_header_t* header, /* in: segment header */
- mtr_t* mtr) /* in: mtr */
+ fseg_header_t* header, /*!< in: segment header */
+ mtr_t* mtr) /*!< in: mtr */
{
fseg_inode_t* inode;
ulint space;
@@ -3870,14 +3895,14 @@ fseg_print(
}
#endif /* UNIV_BTR_PRINT */
-/***********************************************************************
-Validates the file space system and its segments. */
+/*******************************************************************//**
+Validates the file space system and its segments.
+@return TRUE if ok */
UNIV_INTERN
ibool
fsp_validate(
/*=========*/
- /* out: TRUE if ok */
- ulint space) /* in: space id */
+ ulint space) /*!< in: space id */
{
fsp_header_t* header;
fseg_inode_t* seg_inode;
@@ -4125,13 +4150,13 @@ fsp_validate(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Prints info of a file space. */
UNIV_INTERN
void
fsp_print(
/*======*/
- ulint space) /* in: space id */
+ ulint space) /*!< in: space id */
{
fsp_header_t* header;
fseg_inode_t* seg_inode;
@@ -4282,3 +4307,4 @@ fsp_print(
fprintf(stderr, "NUMBER of file segments: %lu\n", (ulong) n_segs);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/fut/fut0fut.c b/storage/xtradb/fut/fut0fut.c
index 41ee0cb6715..20b45a575e6 100644
--- a/storage/xtradb/fut/fut0fut.c
+++ b/storage/xtradb/fut/fut0fut.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file fut/fut0fut.c
File-based utilities
Created 12/13/1995 Heikki Tuuri
diff --git a/storage/xtradb/fut/fut0lst.c b/storage/xtradb/fut/fut0lst.c
index bea27ab70d1..a1e21c22725 100644
--- a/storage/xtradb/fut/fut0lst.c
+++ b/storage/xtradb/fut/fut0lst.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file fut/fut0lst.c
File-based list utilities
Created 11/28/1995 Heikki Tuuri
@@ -31,16 +32,16 @@ Created 11/28/1995 Heikki Tuuri
#include "buf0buf.h"
#include "page0page.h"
-/************************************************************************
+/********************************************************************//**
Adds a node to an empty list. */
static
void
flst_add_to_empty(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of
+ flst_base_node_t* base, /*!< in: pointer to base node of
empty list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@@ -67,15 +68,15 @@ flst_add_to_empty(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Adds a node as the last node in a list. */
UNIV_INTERN
void
flst_add_last(
/*==========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@@ -110,15 +111,15 @@ flst_add_last(
}
}
-/************************************************************************
+/********************************************************************//**
Adds a node as the first node in a list. */
UNIV_INTERN
void
flst_add_first(
/*===========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@@ -153,16 +154,16 @@ flst_add_first(
}
}
-/************************************************************************
+/********************************************************************//**
Inserts a node after another in a list. */
UNIV_INTERN
void
flst_insert_after(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node1, /* in: node to insert after */
- flst_node_t* node2, /* in: node to add */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node1, /*!< in: node to insert after */
+ flst_node_t* node2, /*!< in: node to add */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node1_addr;
@@ -208,16 +209,16 @@ flst_insert_after(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Inserts a node before another in a list. */
UNIV_INTERN
void
flst_insert_before(
/*===============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: node to insert */
- flst_node_t* node3, /* in: node to insert before */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: node to insert */
+ flst_node_t* node3, /*!< in: node to insert before */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
flst_node_t* node1;
@@ -262,15 +263,15 @@ flst_insert_before(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Removes a node. */
UNIV_INTERN
void
flst_remove(
/*========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: node to remove */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: node to remove */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
ulint zip_size;
@@ -337,7 +338,7 @@ flst_remove(
mlog_write_ulint(base + FLST_LEN, len - 1, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Cuts off the tail of the list, including the node given. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@@ -345,11 +346,11 @@ UNIV_INTERN
void
flst_cut_end(
/*=========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: first node to remove */
- ulint n_nodes,/* in: number of nodes to remove,
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: first node to remove */
+ ulint n_nodes,/*!< in: number of nodes to remove,
must be >= 1 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
flst_node_t* node1;
@@ -394,7 +395,7 @@ flst_cut_end(
mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Cuts off the tail of the list, not including the given node. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@@ -402,10 +403,10 @@ UNIV_INTERN
void
flst_truncate_end(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: first node not to remove */
- ulint n_nodes,/* in: number of nodes to remove */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: first node not to remove */
+ ulint n_nodes,/*!< in: number of nodes to remove */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fil_addr_t node2_addr;
ulint len;
@@ -435,15 +436,15 @@ flst_truncate_end(
mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr);
}
-/************************************************************************
-Validates a file-based list. */
+/********************************************************************//**
+Validates a file-based list.
+@return TRUE if ok */
UNIV_INTERN
ibool
flst_validate(
/*==========*/
- /* out: TRUE if ok */
- const flst_base_node_t* base, /* in: pointer to base node of list */
- mtr_t* mtr1) /* in: mtr */
+ const flst_base_node_t* base, /*!< in: pointer to base node of list */
+ mtr_t* mtr1) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -502,14 +503,14 @@ flst_validate(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Prints info of a file-based list. */
UNIV_INTERN
void
flst_print(
/*=======*/
- const flst_base_node_t* base, /* in: pointer to base node of list */
- mtr_t* mtr) /* in: mtr */
+ const flst_base_node_t* base, /*!< in: pointer to base node of list */
+ mtr_t* mtr) /*!< in: mtr */
{
const buf_frame_t* frame;
ulint len;
diff --git a/storage/xtradb/ha/ha0ha.c b/storage/xtradb/ha/ha0ha.c
index 1ecba3df663..cb5e541b55d 100644
--- a/storage/xtradb/ha/ha0ha.c
+++ b/storage/xtradb/ha/ha0ha.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file ha/ha0ha.c
The hash table with external chains
Created 8/22/1994 Heikki Tuuri
@@ -35,29 +36,34 @@ Created 8/22/1994 Heikki Tuuri
#endif /* UNIV_SYNC_DEBUG */
#include "page0page.h"
-/*****************************************************************
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n. */
+/*************************************************************//**
+Creates a hash table with at least n array cells. The actual number
+of cells is chosen to be a prime number slightly bigger than n.
+@return own: created table */
UNIV_INTERN
hash_table_t*
ha_create_func(
/*===========*/
- /* out, own: created table */
- ulint n, /* in: number of array cells */
+ ulint n, /*!< in: number of array cells */
#ifdef UNIV_SYNC_DEBUG
- ulint mutex_level, /* in: level of the mutexes in the latching
+ ulint mutex_level, /*!< in: level of the mutexes in the latching
order: this is used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes) /* in: number of mutexes to protect the
+ ulint n_mutexes) /*!< in: number of mutexes to protect the
hash table: must be a power of 2, or 0 */
{
hash_table_t* table;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
+ ut_ad(ut_is_2pow(n_mutexes));
table = hash_create(n);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
table->adaptive = TRUE;
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
/* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
but in practise it never should in this case, hence the asserts. */
@@ -70,6 +76,7 @@ ha_create_func(
return(table);
}
+#ifndef UNIV_HOTBACKUP
hash_create_mutexes(table, n_mutexes, mutex_level);
table->heaps = mem_alloc(n_mutexes * sizeof(void*));
@@ -78,17 +85,18 @@ ha_create_func(
table->heaps[i] = mem_heap_create_in_btr_search(4096);
ut_a(table->heaps[i]);
}
+#endif /* !UNIV_HOTBACKUP */
return(table);
}
-/*****************************************************************
+/*************************************************************//**
Empties a hash table and frees the memory heaps. */
UNIV_INTERN
void
ha_clear(
/*=====*/
- hash_table_t* table) /* in, own: hash table */
+ hash_table_t* table) /*!< in, own: hash table */
{
ulint i;
ulint n;
@@ -97,12 +105,14 @@ ha_clear(
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */
+#ifndef UNIV_HOTBACKUP
/* Free the memory heaps. */
n = table->n_mutexes;
for (i = 0; i < n; i++) {
mem_heap_free(table->heaps[i]);
}
+#endif /* !UNIV_HOTBACKUP */
/* Clear the hash table. */
n = hash_get_n_cells(table);
@@ -112,25 +122,24 @@ ha_clear(
}
}
-/*****************************************************************
+/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
-is inserted. */
+is inserted.
+@return TRUE if succeed, FALSE if no more memory could be allocated */
UNIV_INTERN
ibool
ha_insert_for_fold_func(
/*====================*/
- /* out: TRUE if succeed, FALSE if no more
- memory could be allocated */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of data; if a node with
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of data; if a node with
the same fold value already exists, it is
updated to point to the same data, and no new
node is created! */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* block, /* in: buffer block containing the data */
+ buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* data) /* in: data, must not be NULL */
+ void* data) /*!< in: data, must not be NULL */
{
hash_cell_t* cell;
ha_node_t* node;
@@ -141,7 +150,7 @@ ha_insert_for_fold_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(block->frame == page_align(data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
hash = hash_calc_hash(fold, table);
@@ -152,6 +161,7 @@ ha_insert_for_fold_func(
while (prev_node != NULL) {
if (prev_node->fold == fold) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
buf_block_t* prev_block = prev_node->block;
ut_a(prev_block->frame
@@ -160,6 +170,7 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
+# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -187,10 +198,13 @@ ha_insert_for_fold_func(
ha_node_set_data(node, block, data);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
block->n_pointers++;
}
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+
node->fold = fold;
node->next = NULL;
@@ -214,65 +228,46 @@ ha_insert_for_fold_func(
return(TRUE);
}
-/***************************************************************
+/***********************************************************//**
Deletes a hash node. */
UNIV_INTERN
void
ha_delete_hash_node(
/*================*/
- hash_table_t* table, /* in: hash table */
- ha_node_t* del_node) /* in: node to be deleted */
+ hash_table_t* table, /*!< in: hash table */
+ ha_node_t* del_node) /*!< in: node to be deleted */
{
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(del_node->block->frame = page_align(del_node->data));
ut_a(del_node->block->n_pointers > 0);
del_node->block->n_pointers--;
}
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
-}
-/*****************************************************************
-Deletes an entry from a hash table. */
-UNIV_INTERN
-void
-ha_delete(
-/*======*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of data */
- void* data) /* in: data, must not be NULL and must exist
- in the hash table */
-{
- ha_node_t* node;
-
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
-
- node = ha_search_with_data(table, fold, data);
-
- ut_a(node);
-
- ha_delete_hash_node(table, node);
+ HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
}
-/*************************************************************
+/*********************************************************//**
Looks for an element when we know the pointer to the data, and updates
the pointer to data, if found. */
UNIV_INTERN
void
ha_search_and_update_if_found_func(
/*===============================*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data, /* in: pointer to the data */
+ hash_table_t* table, /*!< in/out: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data, /*!< in: pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* new_block,/* in: block containing new_data */
+ buf_block_t* new_block,/*!< in: block containing new_data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* new_data)/* in: new pointer to the data */
+ void* new_data)/*!< in: new pointer to the data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(new_block->frame == page_align(new_data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -281,11 +276,13 @@ ha_search_and_update_if_found_func(
if (node) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(node->block->n_pointers > 0);
node->block->n_pointers--;
new_block->n_pointers++;
}
+# endif /* !UNIV_HOTBACKUP */
node->block = new_block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -293,20 +290,21 @@ ha_search_and_update_if_found_func(
}
}
-/*********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
points to the page given. */
UNIV_INTERN
void
ha_remove_all_nodes_to_page(
/*========================*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: fold value */
- const page_t* page) /* in: buffer page */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: fold value */
+ const page_t* page) /*!< in: buffer page */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@@ -339,16 +337,16 @@ ha_remove_all_nodes_to_page(
#endif
}
-/*****************************************************************
-Validates a given range of the cells in hash table. */
+/*************************************************************//**
+Validates a given range of the cells in hash table.
+@return TRUE if ok */
UNIV_INTERN
ibool
ha_validate(
/*========*/
- /* out: TRUE if ok */
- hash_table_t* table, /* in: hash table */
- ulint start_index, /* in: start index */
- ulint end_index) /* in: end index */
+ hash_table_t* table, /*!< in: hash table */
+ ulint start_index, /*!< in: start index */
+ ulint end_index) /*!< in: end index */
{
hash_cell_t* cell;
ha_node_t* node;
@@ -384,14 +382,14 @@ ha_validate(
return(ok);
}
-/*****************************************************************
+/*************************************************************//**
Prints info of a hash table. */
UNIV_INTERN
void
ha_print_info(
/*==========*/
- FILE* file, /* in: file where to print */
- hash_table_t* table) /* in: hash table */
+ FILE* file, /*!< in: file where to print */
+ hash_table_t* table) /*!< in: hash table */
{
#ifdef UNIV_DEBUG
/* Some of the code here is disabled for performance reasons in production
@@ -440,3 +438,4 @@ builds, see http://bugs.mysql.com/36941 */
(ulong) n_bufs);
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/ha/ha0storage.c b/storage/xtradb/ha/ha0storage.c
index e7e09591193..698e34f1166 100644
--- a/storage/xtradb/ha/ha0storage.c
+++ b/storage/xtradb/ha/ha0storage.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file ha/ha0storage.c
Hash storage.
Provides a data structure that stores chunks of data in
its own storage, avoiding duplicates.
@@ -34,16 +35,16 @@ Created September 22, 2007 Vasil Dimov
#include "ha0storage.ic"
#endif
-/***********************************************************************
+/*******************************************************************//**
Retrieves a data from a storage. If it is present, a pointer to the
stored copy of data is returned, otherwise NULL is returned. */
static
const void*
ha_storage_get(
/*===========*/
- ha_storage_t* storage, /* in: hash storage */
- const void* data, /* in: data to check for */
- ulint data_len) /* in: data length */
+ ha_storage_t* storage, /*!< in: hash storage */
+ const void* data, /*!< in: data to check for */
+ ulint data_len) /*!< in: data length */
{
ha_storage_node_t* node;
ulint fold;
@@ -73,7 +74,7 @@ ha_storage_get(
return(node->data);
}
-/***********************************************************************
+/*******************************************************************//**
Copies data into the storage and returns a pointer to the copy. If the
same data chunk is already present, then pointer to it is returned.
Data chunks are considered to be equal if len1 == len2 and
@@ -86,10 +87,10 @@ UNIV_INTERN
const void*
ha_storage_put_memlim(
/*==================*/
- ha_storage_t* storage, /* in/out: hash storage */
- const void* data, /* in: data to store */
- ulint data_len, /* in: data length */
- ulint memlim) /* in: memory limit to obey */
+ ha_storage_t* storage, /*!< in/out: hash storage */
+ const void* data, /*!< in: data to store */
+ ulint data_len, /*!< in: data length */
+ ulint memlim) /*!< in: memory limit to obey */
{
void* raw;
ha_storage_node_t* node;
diff --git a/storage/xtradb/ha/hash0hash.c b/storage/xtradb/ha/hash0hash.c
index 9694a288c99..2800d7793f8 100644
--- a/storage/xtradb/ha/hash0hash.c
+++ b/storage/xtradb/ha/hash0hash.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file ha/hash0hash.c
The simple hash table utility
Created 5/20/1997 Heikki Tuuri
@@ -29,37 +30,38 @@ Created 5/20/1997 Heikki Tuuri
#include "mem0mem.h"
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Reserves the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_enter(
/*=============*/
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
mutex_enter(hash_get_mutex(table, fold));
}
-/****************************************************************
+/************************************************************//**
Releases the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_exit(
/*============*/
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
mutex_exit(hash_get_mutex(table, fold));
}
-/****************************************************************
+/************************************************************//**
Reserves all the mutexes of a hash table, in an ascending order. */
UNIV_INTERN
void
hash_mutex_enter_all(
/*=================*/
- hash_table_t* table) /* in: hash table */
+ hash_table_t* table) /*!< in: hash table */
{
ulint i;
@@ -69,13 +71,13 @@ hash_mutex_enter_all(
}
}
-/****************************************************************
+/************************************************************//**
Releases all the mutexes of a hash table. */
UNIV_INTERN
void
hash_mutex_exit_all(
/*================*/
- hash_table_t* table) /* in: hash table */
+ hash_table_t* table) /*!< in: hash table */
{
ulint i;
@@ -84,16 +86,17 @@ hash_mutex_exit_all(
mutex_exit(table->mutexes + i);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n. */
+chosen to be a prime number slightly bigger than n.
+@return own: created table */
UNIV_INTERN
hash_table_t*
hash_create(
/*========*/
- /* out, own: created table */
- ulint n) /* in: number of array cells */
+ ulint n) /*!< in: number of array cells */
{
hash_cell_t* array;
ulint prime;
@@ -105,14 +108,16 @@ hash_create(
array = ut_malloc(sizeof(hash_cell_t) * prime);
-#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- table->adaptive = FALSE;
-#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
table->array = array;
table->n_cells = prime;
+#ifndef UNIV_HOTBACKUP
+# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ table->adaptive = FALSE;
+# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
table->n_mutexes = 0;
table->mutexes = NULL;
table->heaps = NULL;
+#endif /* !UNIV_HOTBACKUP */
table->heap = NULL;
table->magic_n = HASH_TABLE_MAGIC_N;
@@ -122,32 +127,35 @@ hash_create(
return(table);
}
-/*****************************************************************
+/*************************************************************//**
Frees a hash table. */
UNIV_INTERN
void
hash_table_free(
/*============*/
- hash_table_t* table) /* in, own: hash table */
+ hash_table_t* table) /*!< in, own: hash table */
{
+#ifndef UNIV_HOTBACKUP
ut_a(table->mutexes == NULL);
+#endif /* !UNIV_HOTBACKUP */
ut_free(table->array);
mem_free(table);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Creates a mutex array to protect a hash table. */
UNIV_INTERN
void
hash_create_mutexes_func(
/*=====================*/
- hash_table_t* table, /* in: hash table */
+ hash_table_t* table, /*!< in: hash table */
#ifdef UNIV_SYNC_DEBUG
- ulint sync_level, /* in: latching order level of the
+ ulint sync_level, /*!< in: latching order level of the
mutexes: used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes) /* in: number of mutexes, must be a
+ ulint n_mutexes) /*!< in: number of mutexes, must be a
power of 2 */
{
ulint i;
@@ -163,3 +171,4 @@ hash_create_mutexes_func(
table->n_mutexes = n_mutexes;
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 411234d172d..db25b39caab 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009 Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,6 +22,32 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free 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
+
+***********************************************************************/
/* TODO list for the InnoDB handler in 5.0:
- Remove the flag trx->active_trans and look at trx->conc_state
@@ -35,7 +61,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma implementation // gcc: Class implementation
#endif
+#ifndef MYSQL_SERVER
#define MYSQL_SERVER
+#endif
#include <mysql_priv.h>
#ifdef MYSQL_SERVER
@@ -46,42 +74,44 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <mysys_err.h>
#include <mysql/plugin.h>
+/** @file ha_innodb.cc */
+
/* Include necessary InnoDB headers */
extern "C" {
-#include "../storage/xtradb/include/univ.i"
-#include "../storage/xtradb/include/btr0sea.h"
-#include "../storage/xtradb/include/os0file.h"
-#include "../storage/xtradb/include/os0thread.h"
-#include "../storage/xtradb/include/srv0start.h"
-#include "../storage/xtradb/include/srv0srv.h"
-#include "../storage/xtradb/include/trx0roll.h"
-#include "../storage/xtradb/include/trx0trx.h"
-#include "../storage/xtradb/include/trx0sys.h"
-#include "../storage/xtradb/include/mtr0mtr.h"
-#include "../storage/xtradb/include/row0ins.h"
-#include "../storage/xtradb/include/row0mysql.h"
-#include "../storage/xtradb/include/row0sel.h"
-#include "../storage/xtradb/include/row0upd.h"
-#include "../storage/xtradb/include/log0log.h"
-#include "../storage/xtradb/include/lock0lock.h"
-#include "../storage/xtradb/include/dict0crea.h"
-#include "../storage/xtradb/include/btr0cur.h"
-#include "../storage/xtradb/include/btr0btr.h"
-#include "../storage/xtradb/include/fsp0fsp.h"
-#include "../storage/xtradb/include/sync0sync.h"
-#include "../storage/xtradb/include/fil0fil.h"
-#include "../storage/xtradb/include/trx0xa.h"
-#include "../storage/xtradb/include/row0merge.h"
-#include "../storage/xtradb/include/thr0loc.h"
-#include "../storage/xtradb/include/dict0boot.h"
-#include "../storage/xtradb/include/ha_prototypes.h"
-#include "../storage/xtradb/include/ut0mem.h"
-#include "../storage/xtradb/include/ibuf0ibuf.h"
+#include "univ.i"
+#include "buf0lru.h"
+#include "btr0sea.h"
+#include "os0file.h"
+#include "os0thread.h"
+#include "srv0start.h"
+#include "srv0srv.h"
+#include "trx0roll.h"
+#include "trx0trx.h"
+#include "trx0sys.h"
+#include "mtr0mtr.h"
+#include "row0ins.h"
+#include "row0mysql.h"
+#include "row0sel.h"
+#include "row0upd.h"
+#include "log0log.h"
+#include "lock0lock.h"
+#include "dict0crea.h"
+#include "btr0cur.h"
+#include "btr0btr.h"
+#include "fsp0fsp.h"
+#include "sync0sync.h"
+#include "fil0fil.h"
+#include "trx0xa.h"
+#include "row0merge.h"
+#include "thr0loc.h"
+#include "dict0boot.h"
+#include "ha_prototypes.h"
+#include "ut0mem.h"
+#include "ibuf0ibuf.h"
}
#include "ha_innodb.h"
#include "i_s.h"
-#include "handler0vars.h"
#ifdef MYSQL_SERVER
// Defined in trx0sys.c
@@ -92,9 +122,12 @@ extern ib_int64_t trx_sys_mysql_relay_log_pos;
#endif /* MYSQL_SERVER */
#ifndef MYSQL_SERVER
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
+# ifndef MYSQL_PLUGIN_IMPORT
+# define MYSQL_PLUGIN_IMPORT /* nothing */
+# endif /* MYSQL_PLUGIN_IMPORT */
+/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
-extern pthread_mutex_t LOCK_thread_count;
+extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
#if MYSQL_VERSION_ID < 50124
/* this is defined in mysql_priv.h inside #ifdef MYSQL_SERVER
@@ -111,6 +144,7 @@ static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
+static pthread_mutex_t analyze_mutex;
static bool innodb_inited = 0;
C_MODE_START
@@ -123,34 +157,11 @@ C_MODE_END
/* In the Windows plugin, the return value of current_thd is
undefined. Map it to NULL. */
-#if defined MYSQL_DYNAMIC_PLUGIN && defined __WIN__
-# undef current_thd
-# define current_thd NULL
-# define EQ_CURRENT_THD(thd) TRUE
-#else /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
-# define EQ_CURRENT_THD(thd) ((thd) == current_thd)
-#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
-#ifdef MYSQL_DYNAMIC_PLUGIN
-/* These must be weak global variables in the dynamic plugin. */
-struct handlerton* innodb_hton_ptr;
-#ifdef __WIN__
-struct st_mysql_plugin* builtin_innobase_plugin_ptr;
-#else
-int builtin_innobase_plugin;
-#endif /* __WIN__ */
-/********************************************************************
-Copy InnoDB system variables from the static InnoDB to the dynamic
-plugin. */
-static
-bool
-innodb_plugin_init(void);
-/*====================*/
- /* out: TRUE if the dynamic InnoDB plugin should start */
-#else /* MYSQL_DYNAMIC_PLUGIN */
-/* This must be a global variable in the statically linked InnoDB. */
-struct handlerton* innodb_hton_ptr = NULL;
-#endif /* MYSQL_DYNAMIC_PLUGIN */
+#define EQ_CURRENT_THD(thd) ((thd) == current_thd)
+
+
+static struct handlerton* innodb_hton_ptr;
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
@@ -161,12 +172,17 @@ static long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_additional_mem_pool_size, innobase_file_io_threads,
innobase_force_recovery, innobase_open_files,
innobase_autoinc_lock_mode;
-static unsigned long innobase_commit_concurrency = 0;
+static ulong innobase_commit_concurrency = 0;
+static ulong innobase_read_io_threads;
+static ulong innobase_write_io_threads;
-static unsigned long innobase_read_io_threads, innobase_write_io_threads;
static my_bool innobase_thread_concurrency_timer_based;
static long long innobase_buffer_pool_size, innobase_log_file_size;
+/** Percentage of the buffer pool to reserve for 'old' blocks.
+Connected to buf_LRU_old_ratio. */
+static uint innobase_old_blocks_pct;
+
/* The default values for the following char* start-up parameters
are determined in innobase_init below: */
@@ -181,9 +197,7 @@ file formats in the configuration file, but can only be set to any
of the supported file formats during runtime. */
static char* innobase_file_format_check = NULL;
-/* The following has a misleading name: starting from 4.0.5, this also
-affects Windows: */
-static char* innobase_unix_file_flush_method = NULL;
+static char* innobase_file_flush_method = NULL;
/* Below we have boolean-valued start-up parameters, and their default
values */
@@ -197,6 +211,7 @@ static my_bool innobase_use_doublewrite = TRUE;
static my_bool innobase_use_checksums = TRUE;
static my_bool innobase_extra_undoslots = FALSE;
static my_bool innobase_fast_recovery = FALSE;
+static my_bool innobase_recovery_stats = TRUE;
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
static my_bool innobase_overwrite_relay_log_info = FALSE;
static my_bool innobase_rollback_on_timeout = FALSE;
@@ -232,45 +247,60 @@ static void free_share(INNOBASE_SHARE *share);
static int innobase_close_connection(handlerton *hton, THD* thd);
static int innobase_commit(handlerton *hton, THD* thd, bool all);
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
-static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
+static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
void *savepoint);
static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
-static int innobase_release_savepoint(handlerton *hton, THD* thd,
+static int innobase_release_savepoint(handlerton *hton, THD* thd,
void *savepoint);
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
+/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
+system primary index. */
+static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
+
+/** @brief Initialize the default value of innodb_commit_concurrency.
+
+Once InnoDB is running, the innodb_commit_concurrency must not change
+from zero to nonzero. (Bug #42101)
-/****************************************************************
-Validate the file format name and return its corresponding id. */
+The initial default value is 0, and without this extra initialization,
+SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
+to 0, even if it was initially set to nonzero at the command line
+or configuration file. */
+static
+void
+innobase_commit_concurrency_init_default(void);
+/*==========================================*/
+
+/************************************************************//**
+Validate the file format name and return its corresponding id.
+@return valid file format id */
static
uint
innobase_file_format_name_lookup(
/*=============================*/
- /* out: valid file format id */
- const char* format_name); /* in: pointer to file format
+ const char* format_name); /*!< in: pointer to file format
name */
-/****************************************************************
+/************************************************************//**
Validate the file format check config parameters, as a side effect it
-sets the srv_check_file_format_at_startup variable. */
+sets the srv_check_file_format_at_startup variable.
+@return true if one of "on" or "off" */
static
bool
innobase_file_format_check_on_off(
/*==============================*/
- /* out: true if one of
- "on" or "off" */
- const char* format_check); /* in: parameter value */
-/****************************************************************
+ const char* format_check); /*!< in: parameter value */
+/************************************************************//**
Validate the file format check config parameters, as a side effect it
-sets the srv_check_file_format_at_startup variable. */
+sets the srv_check_file_format_at_startup variable.
+@return the format_id if valid config value, otherwise, return -1 */
static
-bool
-innobase_file_format_check_validate(
+int
+innobase_file_format_validate_and_set(
/*================================*/
- /* out: true if valid
- config value */
- const char* format_check); /* in: parameter value */
-/********************************************************************
+ const char* format_check); /*!< in: parameter value */
+/****************************************************************//**
Return alter table flags supported in an InnoDB database. */
static
uint
@@ -280,34 +310,19 @@ innobase_alter_table_flags(
static const char innobase_hton_name[]= "InnoDB";
-/** @brief Initialize the default value of innodb_commit_concurrency.
-
-Once InnoDB is running, the innodb_commit_concurrency must not change
-from zero to nonzero. (Bug #42101)
-
-The initial default value is 0, and without this extra initialization,
-SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
-to 0, even if it was initially set to nonzero at the command line
-or configuration file. */
-static
-void
-innobase_commit_concurrency_init_default(void);
-/*==========================================*/
-
-/*****************************************************************
-Check for a valid value of innobase_commit_concurrency. */
+/*************************************************************//**
+Check for a valid value of innobase_commit_concurrency.
+@return 0 for valid innodb_commit_concurrency */
static
int
innobase_commit_concurrency_validate(
/*=================================*/
- /* out: 0 for valid
- innodb_commit_concurrency */
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to system
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
- void* save, /* out: immediate result
+ void* save, /*!< out: immediate result
for update function */
- struct st_mysql_value* value) /* in: incoming string */
+ struct st_mysql_value* value) /*!< in: incoming string */
{
long long intbuf;
ulong commit_concurrency;
@@ -353,62 +368,64 @@ static handler *innobase_create_handler(handlerton *hton,
return new (mem_root) ha_innobase(hton, table);
}
-/***********************************************************************
-This function is used to prepare X/Open XA distributed transaction */
+/*******************************************************************//**
+This function is used to prepare an X/Open XA distributed transaction.
+@return 0 or error number */
static
int
innobase_xa_prepare(
/*================*/
- /* out: 0 or error number */
- handlerton* hton,
- THD* thd, /* in: handle to the MySQL thread of the user
- whose XA transaction should be prepared */
- bool all); /* in: TRUE - commit transaction
- FALSE - the current SQL statement ended */
-/***********************************************************************
-This function is used to recover X/Open XA distributed transactions */
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread of
+ the user whose XA transaction should
+ be prepared */
+ bool all); /*!< in: TRUE - commit transaction
+ FALSE - the current SQL statement
+ ended */
+/*******************************************************************//**
+This function is used to recover X/Open XA distributed transactions.
+@return number of prepared transactions stored in xid_list */
static
int
innobase_xa_recover(
/*================*/
- /* out: number of prepared transactions
- stored in xid_list */
- handlerton* hton,
- XID* xid_list, /* in/out: prepared transactions */
- uint len); /* in: number of slots in xid_list */
-/***********************************************************************
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ XID* xid_list,/*!< in/out: prepared transactions */
+ uint len); /*!< in: number of slots in xid_list */
+/*******************************************************************//**
This function is used to commit one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return 0 or error number */
static
int
innobase_commit_by_xid(
/*===================*/
- /* out: 0 or error number */
handlerton* hton,
- XID* xid); /* in: X/Open XA transaction identification */
-/***********************************************************************
+ 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 */
+which is in the prepared state
+@return 0 or error number */
static
int
innobase_rollback_by_xid(
/*=====================*/
- /* out: 0 or error number */
- handlerton* hton,
- XID *xid); /* in: X/Open XA transaction identification */
-/***********************************************************************
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ XID* xid); /*!< in: X/Open XA transaction
+ identification */
+/*******************************************************************//**
Create a consistent view for a cursor based on current transaction
which is created if the corresponding MySQL thread still lacks one.
This consistent view is then used inside of MySQL when accessing records
-using a cursor. */
+using a cursor.
+@return pointer to cursor view or NULL */
static
void*
innobase_create_cursor_view(
/*========================*/
- /* out: pointer to cursor view or NULL */
- handlerton* hton, /* in: innobase hton */
- THD* thd); /* in: user thread handle */
-/***********************************************************************
+ handlerton* hton, /*!< in: innobase hton */
+ THD* thd); /*!< in: user thread handle */
+/*******************************************************************//**
Set the given consistent cursor view to a transaction which is created
if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is
@@ -418,9 +435,9 @@ void
innobase_set_cursor_view(
/*=====================*/
handlerton* hton,
- THD* thd, /* in: user thread handle */
- void* curview);/* in: Consistent cursor view to be set */
-/***********************************************************************
+ THD* thd, /*!< in: user thread handle */
+ void* curview);/*!< in: Consistent cursor view to be set */
+/*******************************************************************//**
Close the given consistent cursor view of a transaction and restore
global read view to a transaction read view. Transaction is created if the
corresponding MySQL thread still lacks one. */
@@ -429,71 +446,70 @@ void
innobase_close_cursor_view(
/*=======================*/
handlerton* hton,
- THD* thd, /* in: user thread handle */
- void* curview);/* in: Consistent read view to be closed */
-/*********************************************************************
+ THD* thd, /*!< in: user thread handle */
+ void* curview);/*!< in: Consistent read view to be closed */
+/*****************************************************************//**
Removes all tables in the named database inside InnoDB. */
static
void
innobase_drop_database(
/*===================*/
- /* out: error number */
- handlerton* hton, /* in: handlerton of Innodb */
- char* path); /* in: database path; inside InnoDB the name
+ handlerton* hton, /*!< in: handlerton of Innodb */
+ char* path); /*!< in: database path; inside InnoDB the name
of the last directory in the path is used as
the database name: for example, in 'mysql/data/test'
the database name is 'test' */
-/***********************************************************************
+/*******************************************************************//**
Closes an InnoDB database. */
static
int
innobase_end(handlerton *hton, ha_panic_function type);
-/*********************************************************************
+/*****************************************************************//**
Creates an InnoDB transaction struct for the thd if it does not yet have one.
Starts a new InnoDB transaction if a transaction is not yet started. And
assigns a new snapshot for a consistent read if the transaction does not yet
-have one. */
+have one.
+@return 0 */
static
int
innobase_start_trx_and_assign_read_view(
/*====================================*/
- /* out: 0 */
- handlerton* hton, /* in: Innodb handlerton */
- THD* thd); /* in: MySQL thread handle of the user for whom
+ handlerton* hton, /*!< in: Innodb handlerton */
+ THD* thd); /*!< in: MySQL thread handle of the user for whom
the transaction should be committed */
-/********************************************************************
+/****************************************************************//**
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
-the logs, and the name of this function should be innobase_checkpoint. */
+the logs, and the name of this function should be innobase_checkpoint.
+@return TRUE if error */
static
bool
innobase_flush_logs(
/*================*/
- /* out: TRUE if error */
- handlerton* hton); /* in: InnoDB handlerton */
+ handlerton* hton); /*!< in: InnoDB handlerton */
-/****************************************************************************
+/************************************************************************//**
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
Monitor to the client. */
static
bool
innodb_show_status(
/*===============*/
- handlerton* hton, /* in: the innodb handlerton */
- THD* thd, /* in: the MySQL query thread of the caller */
+ handlerton* hton, /*!< in: the innodb handlerton */
+ THD* thd, /*!< in: the MySQL query thread of the caller */
stat_print_fn *stat_print);
static
bool innobase_show_status(handlerton *hton, THD* thd,
stat_print_fn* stat_print,
enum ha_stat_type stat_type);
-/*********************************************************************
+/*****************************************************************//**
Commits a transaction in an InnoDB database. */
static
void
innobase_commit_low(
/*================*/
- trx_t* trx); /* in: transaction handle */
+ trx_t* trx); /*!< in: transaction handle */
static SHOW_VAR innodb_status_variables[]= {
{"buffer_pool_pages_data",
@@ -512,10 +528,10 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
{"buffer_pool_pages_total",
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
- {"buffer_pool_read_ahead_rnd",
- (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
- {"buffer_pool_read_ahead_seq",
- (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
+ {"buffer_pool_read_ahead",
+ (char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG},
+ {"buffer_pool_read_ahead_evicted",
+ (char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
{"buffer_pool_read_requests",
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
{"buffer_pool_reads",
@@ -593,30 +609,30 @@ static SHOW_VAR innodb_status_variables[]= {
/* General functions */
-/**********************************************************************
+/******************************************************************//**
Returns true if the thread is the replication thread on the slave
server. Used in srv_conc_enter_innodb() to determine if the thread
should be allowed to enter InnoDB - the replication thread is treated
differently than other threads. Also used in
-srv_conc_force_exit_innodb(). */
+srv_conc_force_exit_innodb().
+@return true if thd is the replication thread */
extern "C" UNIV_INTERN
ibool
thd_is_replication_slave_thread(
/*============================*/
- /* out: true if thd is the replication thread */
- void* thd) /* in: thread handle (THD*) */
+ void* thd) /*!< in: thread handle (THD*) */
{
return((ibool) thd_slave_thread((THD*) thd));
}
-/**********************************************************************
+/******************************************************************//**
Save some CPU by testing the value of srv_thread_concurrency in inline
functions. */
static inline
void
innodb_srv_conc_enter_innodb(
/*=========================*/
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
if (UNIV_LIKELY(!srv_thread_concurrency)) {
@@ -626,14 +642,14 @@ innodb_srv_conc_enter_innodb(
srv_conc_enter_innodb(trx);
}
-/**********************************************************************
+/******************************************************************//**
Save some CPU by testing the value of srv_thread_concurrency in inline
functions. */
static inline
void
innodb_srv_conc_exit_innodb(
/*========================*/
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
if (UNIV_LIKELY(!trx->declared_to_be_inside_innodb)) {
@@ -643,7 +659,7 @@ innodb_srv_conc_exit_innodb(
srv_conc_exit_innodb(trx);
}
-/**********************************************************************
+/******************************************************************//**
Releases possible search latch and InnoDB thread FIFO ticket. These should
be released at each SQL statement end, and also when mysqld passes the
control to the client. It does no harm to release these also in the middle
@@ -652,7 +668,7 @@ static inline
void
innobase_release_stat_resources(
/*============================*/
- trx_t* trx) /* in: transaction object */
+ trx_t* trx) /*!< in: transaction object */
{
if (trx->has_search_latch) {
trx_search_latch_release_if_reserved(trx);
@@ -665,56 +681,55 @@ innobase_release_stat_resources(
}
}
-/**********************************************************************
+/******************************************************************//**
Returns true if the transaction this thread is processing has edited
non-transactional tables. Used by the deadlock detector when deciding
which transaction to rollback in case of a deadlock - we try to avoid
-rolling back transactions that have edited non-transactional tables. */
+rolling back transactions that have edited non-transactional tables.
+@return true if non-transactional tables have been edited */
extern "C" UNIV_INTERN
ibool
thd_has_edited_nontrans_tables(
/*===========================*/
- /* out: true if non-transactional tables have
- been edited */
- void* thd) /* in: thread handle (THD*) */
+ void* thd) /*!< in: thread handle (THD*) */
{
return((ibool) thd_non_transactional_update((THD*) thd));
}
-/**********************************************************************
-Returns true if the thread is executing a SELECT statement. */
+/******************************************************************//**
+Returns true if the thread is executing a SELECT statement.
+@return true if thd is executing SELECT */
extern "C" UNIV_INTERN
ibool
thd_is_select(
/*==========*/
- /* out: true if thd is executing SELECT */
- const void* thd) /* in: thread handle (THD*) */
+ const void* thd) /*!< in: thread handle (THD*) */
{
return(thd_sql_command((const THD*) thd) == SQLCOM_SELECT);
}
-/**********************************************************************
+/******************************************************************//**
Returns true if the thread supports XA,
-global value of innodb_supports_xa if thd is NULL. */
+global value of innodb_supports_xa if thd is NULL.
+@return true if thd has XA support */
extern "C" UNIV_INTERN
ibool
thd_supports_xa(
/*============*/
- /* out: true if thd has XA support */
- void* thd) /* in: thread handle (THD*), or NULL to query
+ void* thd) /*!< in: thread handle (THD*), or NULL to query
the global innodb_supports_xa */
{
return(THDVAR((THD*) thd, support_xa));
}
-/**********************************************************************
-Returns the lock wait timeout for the current connection. */
+/******************************************************************//**
+Returns the lock wait timeout for the current connection.
+@return the lock wait timeout, in seconds */
extern "C" UNIV_INTERN
ulong
thd_lock_wait_timeout(
/*==================*/
- /* out: the lock wait timeout, in seconds */
- void* thd) /* in: thread handle (THD*), or NULL to query
+ void* thd) /*!< in: thread handle (THD*), or NULL to query
the global innodb_lock_wait_timeout */
{
/* According to <mysql/plugin.h>, passing thd == NULL
@@ -722,29 +737,29 @@ thd_lock_wait_timeout(
return(THDVAR((THD*) thd, lock_wait_timeout));
}
-/************************************************************************
-Obtain the InnoDB transaction of a MySQL thread. */
+/********************************************************************//**
+Obtain the InnoDB transaction of a MySQL thread.
+@return reference to transaction pointer */
static inline
trx_t*&
thd_to_trx(
/*=======*/
- /* out: reference to transaction pointer */
- THD* thd) /* in: MySQL thread */
+ THD* thd) /*!< in: MySQL thread */
{
return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr));
}
-/************************************************************************
+/********************************************************************//**
Call this function when mysqld passes control to the client. That is to
avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
-documentation, see handler.cc. */
+documentation, see handler.cc.
+@return 0 */
static
int
innobase_release_temporary_latches(
/*===============================*/
- /* out: 0 */
- handlerton* hton, /* in: handlerton */
- THD* thd) /* in: MySQL thread */
+ handlerton* hton, /*!< in: handlerton */
+ THD* thd) /*!< in: MySQL thread */
{
trx_t* trx;
@@ -763,7 +778,7 @@ innobase_release_temporary_latches(
return(0);
}
-/************************************************************************
+/********************************************************************//**
Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
time calls srv_active_wake_master_thread. This function should be used
when a single database operation may introduce a small need for
@@ -780,33 +795,45 @@ innobase_active_small(void)
}
}
-/************************************************************************
+/********************************************************************//**
Converts an InnoDB error code to a MySQL error code and also tells to MySQL
about a possible transaction rollback inside InnoDB caused by a lock wait
-timeout or a deadlock. */
+timeout or a deadlock.
+@return MySQL error code */
extern "C" UNIV_INTERN
int
convert_error_code_to_mysql(
/*========================*/
- /* out: MySQL error code */
- int error, /* in: InnoDB error code */
- ulint flags, /* in: InnoDB table flags, or 0 */
- THD* thd) /* in: user thread handle or NULL */
+ int error, /*!< in: InnoDB error code */
+ ulint flags, /*!< in: InnoDB table flags, or 0 */
+ THD* thd) /*!< in: user thread handle or NULL */
{
switch (error) {
case DB_SUCCESS:
return(0);
+ case DB_INTERRUPTED:
+ my_error(ER_QUERY_INTERRUPTED, MYF(0));
+ /* fall through */
case DB_ERROR:
default:
return(-1); /* unspecified error */
case DB_DUPLICATE_KEY:
+ /* Be cautious with returning this error, since
+ mysql could re-enter the storage layer to get
+ duplicated key info, the operation requires a
+ valid table handle and/or transaction information,
+ which might not always be available in the error
+ handling stage. */
return(HA_ERR_FOUND_DUPP_KEY);
case DB_FOREIGN_DUPLICATE_KEY:
return(HA_ERR_FOREIGN_DUPLICATE_KEY);
+ case DB_MISSING_HISTORY:
+ return(HA_ERR_TABLE_DEF_CHANGED);
+
case DB_RECORD_NOT_FOUND:
return(HA_ERR_NO_ACTIVE_RECORD);
@@ -885,23 +912,20 @@ convert_error_code_to_mysql(
return(ER_PRIMARY_CANT_HAVE_NULL);
case DB_TOO_MANY_CONCURRENT_TRXS:
- /* Once MySQL add the appropriate code to errmsg.txt then
- we can get rid of this #ifdef. NOTE: The code checked by
- the #ifdef is the suggested name for the error condition
- and the actual error code name could very well be different.
- This will require some monitoring, ie. the status
- of this request on our part.*/
-#ifdef ER_TOO_MANY_CONCURRENT_TRXS
- return(ER_TOO_MANY_CONCURRENT_TRXS);
-#else
+ /* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
+ available in 5.1.38 and later, but the plugin should still
+ work with previous versions of MySQL. */
+#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
+ return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
+#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
return(HA_ERR_RECORD_FILE_FULL);
-#endif
+#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
case DB_UNSUPPORTED:
return(HA_ERR_UNSUPPORTED);
}
}
-/*****************************************************************
+/*************************************************************//**
If you want to print a thd that is not associated with the current thread,
you must call this function before reserving the InnoDB kernel_mutex, to
protect MySQL from setting thd->query NULL. If you print a thd of the current
@@ -917,7 +941,7 @@ innobase_mysql_prepare_print_arbitrary_thd(void)
VOID(pthread_mutex_lock(&LOCK_thread_count));
}
-/*****************************************************************
+/*************************************************************//**
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
In the InnoDB latching order, the mutex sits right above the
kernel_mutex. In debug builds, we assert that the kernel_mutex is
@@ -931,15 +955,15 @@ innobase_mysql_end_print_arbitrary_thd(void)
VOID(pthread_mutex_unlock(&LOCK_thread_count));
}
-/*****************************************************************
+/*************************************************************//**
Prints info of a THD object (== user session thread) to the given file. */
extern "C" UNIV_INTERN
void
innobase_mysql_print_thd(
/*=====================*/
- FILE* f, /* in: output stream */
- void* thd, /* in: pointer to a MySQL THD object */
- uint max_query_len) /* in: max query length to print, or 0 to
+ FILE* f, /*!< in: output stream */
+ void* thd, /*!< in: pointer to a MySQL THD object */
+ uint max_query_len) /*!< in: max query length to print, or 0 to
use the default max length */
{
char buffer[1024];
@@ -949,15 +973,15 @@ innobase_mysql_print_thd(
putc('\n', f);
}
-/**********************************************************************
+/******************************************************************//**
Get the variable length bounds of the given character set. */
extern "C" UNIV_INTERN
void
innobase_get_cset_width(
/*====================*/
- ulint cset, /* in: MySQL charset-collation code */
- ulint* mbminlen, /* out: minimum length of a char (in bytes) */
- ulint* mbmaxlen) /* out: maximum length of a char (in bytes) */
+ ulint cset, /*!< in: MySQL charset-collation code */
+ ulint* mbminlen, /*!< out: minimum length of a char (in bytes) */
+ ulint* mbmaxlen) /*!< out: maximum length of a char (in bytes) */
{
CHARSET_INFO* cs;
ut_ad(cset < 256);
@@ -969,95 +993,112 @@ innobase_get_cset_width(
*mbminlen = cs->mbminlen;
*mbmaxlen = cs->mbmaxlen;
} else {
- ut_a(cset == 0);
+ THD* thd = current_thd;
+
+ if (thd && thd_sql_command(thd) == SQLCOM_DROP_TABLE) {
+
+ /* Fix bug#46256: allow tables to be dropped if the
+ collation is not found, but issue a warning. */
+ if ((global_system_variables.log_warnings)
+ && (cset != 0)){
+
+ sql_print_warning(
+ "Unknown collation #%lu.", cset);
+ }
+ } else {
+
+ ut_a(cset == 0);
+ }
+
*mbminlen = *mbmaxlen = 0;
}
}
-/**********************************************************************
+/******************************************************************//**
Converts an identifier to a table name. */
extern "C" UNIV_INTERN
void
innobase_convert_from_table_id(
/*===========================*/
- struct charset_info_st* cs, /* in: the 'from' character set */
- char* to, /* out: converted identifier */
- const char* from, /* in: identifier to convert */
- ulint len) /* in: length of 'to', in bytes */
+ struct charset_info_st* cs, /*!< in: the 'from' character set */
+ char* to, /*!< out: converted identifier */
+ const char* from, /*!< in: identifier to convert */
+ ulint len) /*!< in: length of 'to', in bytes */
{
uint errors;
strconvert(cs, from, &my_charset_filename, to, (uint) len, &errors);
}
-/**********************************************************************
+/******************************************************************//**
Converts an identifier to UTF-8. */
extern "C" UNIV_INTERN
void
innobase_convert_from_id(
/*=====================*/
- struct charset_info_st* cs, /* in: the 'from' character set */
- char* to, /* out: converted identifier */
- const char* from, /* in: identifier to convert */
- ulint len) /* in: length of 'to', in bytes */
+ struct charset_info_st* cs, /*!< in: the 'from' character set */
+ char* to, /*!< out: converted identifier */
+ const char* from, /*!< in: identifier to convert */
+ ulint len) /*!< in: length of 'to', in bytes */
{
uint errors;
strconvert(cs, from, system_charset_info, to, (uint) len, &errors);
}
-/**********************************************************************
-Compares NUL-terminated UTF-8 strings case insensitively. */
+/******************************************************************//**
+Compares NUL-terminated UTF-8 strings case insensitively.
+@return 0 if a=b, <0 if a<b, >1 if a>b */
extern "C" UNIV_INTERN
int
innobase_strcasecmp(
/*================*/
- /* out: 0 if a=b, <0 if a<b, >1 if a>b */
- const char* a, /* in: first string to compare */
- const char* b) /* in: second string to compare */
+ const char* a, /*!< in: first string to compare */
+ const char* b) /*!< in: second string to compare */
{
return(my_strcasecmp(system_charset_info, a, b));
}
-/**********************************************************************
+/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
extern "C" UNIV_INTERN
void
innobase_casedn_str(
/*================*/
- char* a) /* in/out: string to put in lower case */
+ char* a) /*!< in/out: string to put in lower case */
{
my_casedn_str(system_charset_info, a);
}
-/**************************************************************************
-Determines the connection character set. */
+/**********************************************************************//**
+Determines the connection character set.
+@return connection character set */
extern "C" UNIV_INTERN
struct charset_info_st*
innobase_get_charset(
/*=================*/
- /* out: connection character set */
- void* mysql_thd) /* in: MySQL thread handle */
+ void* mysql_thd) /*!< in: MySQL thread handle */
{
return(thd_charset((THD*) mysql_thd));
}
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-/***********************************************************************
+extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
+/*******************************************************************//**
Map an OS error to an errno value. The OS error number is stored in
_doserrno and the mapped value is stored in errno) */
extern "C"
void __cdecl
_dosmaperr(
- unsigned long); /* in: OS error value */
+ unsigned long); /*!< in: OS error value */
-/*************************************************************************
-Creates a temporary file. */
+/*********************************************************************//**
+Creates a temporary file.
+@return temporary file descriptor, or < 0 on error */
extern "C" UNIV_INTERN
int
innobase_mysql_tmpfile(void)
/*========================*/
- /* out: temporary file descriptor, or < 0 on error */
{
int fd; /* handle of opened file */
HANDLE osfh; /* OS handle of opened file */
@@ -1135,13 +1176,13 @@ innobase_mysql_tmpfile(void)
DBUG_RETURN(fd);
}
#else
-/*************************************************************************
-Creates a temporary file. */
+/*********************************************************************//**
+Creates a temporary file.
+@return temporary file descriptor, or < 0 on error */
extern "C" UNIV_INTERN
int
innobase_mysql_tmpfile(void)
/*========================*/
- /* out: temporary file descriptor, or < 0 on error */
{
int fd2 = -1;
File fd = mysql_tmpfile("ib");
@@ -1168,46 +1209,47 @@ innobase_mysql_tmpfile(void)
}
#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
-/*************************************************************************
-Wrapper around MySQL's copy_and_convert function, see it for
-documentation. */
+/*********************************************************************//**
+Wrapper around MySQL's copy_and_convert function.
+@return number of bytes copied to 'to' */
extern "C" UNIV_INTERN
ulint
innobase_convert_string(
/*====================*/
- void* to,
- ulint to_length,
- CHARSET_INFO* to_cs,
- const void* from,
- ulint from_length,
- CHARSET_INFO* from_cs,
- uint* errors)
+ void* to, /*!< out: converted string */
+ ulint to_length, /*!< in: number of bytes reserved
+ for the converted string */
+ CHARSET_INFO* to_cs, /*!< in: character set to convert to */
+ const void* from, /*!< in: string to convert */
+ ulint from_length, /*!< in: number of bytes to convert */
+ CHARSET_INFO* from_cs, /*!< in: character set to convert from */
+ uint* errors) /*!< out: number of errors encountered
+ during the conversion */
{
return(copy_and_convert((char*)to, (uint32) to_length, to_cs,
(const char*)from, (uint32) from_length, from_cs,
errors));
}
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
the result to "buf". The result is converted to "system_charset_info".
Not more than "buf_size" bytes are written to "buf".
-The result is always '\0'-terminated (provided buf_size > 0) and the
+The result is always NUL-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating NUL).
+@return number of bytes that were written */
extern "C" UNIV_INTERN
ulint
innobase_raw_format(
/*================*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- ulint charset_coll, /* in: charset collation */
- char* buf, /* out: output buffer */
- ulint buf_size) /* in: output buffer size
+ ulint charset_coll, /*!< in: charset collation */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size) /*!< in: output buffer size
in bytes */
{
/* XXX we use a hard limit instead of allocating
@@ -1227,7 +1269,7 @@ innobase_raw_format(
return(ut_str_sql_format(buf_tmp, buf_tmp_used, buf, buf_size));
}
-/*************************************************************************
+/*********************************************************************//**
Compute the next autoinc value.
For MySQL replication the autoincrement values can be partitioned among
@@ -1243,16 +1285,16 @@ values we want to reserve for multi-value inserts e.g.,
innobase_next_autoinc() will be called with increment set to
n * 3 where autoinc_lock_mode != TRADITIONAL because we want
-to reserve 3 values for the multi-value INSERT above. */
+to reserve 3 values for the multi-value INSERT above.
+@return the next value */
static
ulonglong
innobase_next_autoinc(
/*==================*/
- /* out: the next value */
- ulonglong current, /* in: Current value */
- ulonglong increment, /* in: increment current by */
- ulonglong offset, /* in: AUTOINC offset */
- ulonglong max_value) /* in: max value for type */
+ ulonglong current, /*!< in: Current value */
+ ulonglong increment, /*!< in: increment current by */
+ ulonglong offset, /*!< in: AUTOINC offset */
+ ulonglong max_value) /*!< in: max value for type */
{
ulonglong next_value;
@@ -1310,14 +1352,14 @@ innobase_next_autoinc(
return(next_value);
}
-/*************************************************************************
+/*********************************************************************//**
Initializes some fields in an InnoDB transaction object. */
static
void
innobase_trx_init(
/*==============*/
- THD* thd, /* in: user thread handle */
- trx_t* trx) /* in/out: InnoDB transaction handle */
+ THD* thd, /*!< in: user thread handle */
+ trx_t* trx) /*!< in/out: InnoDB transaction handle */
{
DBUG_ENTER("innobase_trx_init");
DBUG_ASSERT(EQ_CURRENT_THD(thd));
@@ -1329,17 +1371,27 @@ innobase_trx_init(
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
+#ifdef EXTENDED_SLOWLOG
+ if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) {
+ trx->take_stats = TRUE;
+ } else {
+ trx->take_stats = FALSE;
+ }
+#else
+ trx->take_stats = FALSE;
+#endif
+
DBUG_VOID_RETURN;
}
-/*************************************************************************
-Allocates an InnoDB transaction for a MySQL handler object. */
+/*********************************************************************//**
+Allocates an InnoDB transaction for a MySQL handler object.
+@return InnoDB transaction handle */
extern "C" UNIV_INTERN
trx_t*
innobase_trx_allocate(
/*==================*/
- /* out: InnoDB transaction handle */
- THD* thd) /* in: user thread handle */
+ THD* thd) /*!< in: user thread handle */
{
trx_t* trx;
@@ -1357,16 +1409,16 @@ innobase_trx_allocate(
DBUG_RETURN(trx);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the InnoDB transaction handle for a MySQL handler object, creates
an InnoDB transaction struct if the corresponding MySQL thread struct still
-lacks one. */
+lacks one.
+@return InnoDB transaction handle */
static
trx_t*
check_trx_exists(
/*=============*/
- /* out: InnoDB transaction handle */
- THD* thd) /* in: user thread handle */
+ THD* thd) /*!< in: user thread handle */
{
trx_t*& trx = thd_to_trx(thd);
@@ -1386,6 +1438,32 @@ check_trx_exists(
/*************************************************************************
+Gets current trx. */
+extern "C"
+trx_t*
+innobase_get_trx()
+{
+ THD *thd=current_thd;
+ if (likely(thd != 0)) {
+ trx_t*& trx = thd_to_trx(thd);
+ return(trx);
+ } else {
+ return(NULL);
+ }
+}
+
+extern "C"
+ibool
+innobase_get_slow_log()
+{
+#ifdef EXTENDED_SLOWLOG
+ return((ibool) thd_opt_slow_log());
+#else
+ return(FALSE);
+#endif
+}
+
+/*********************************************************************//**
Construct ha_innobase handler. */
UNIV_INTERN
ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
@@ -1403,14 +1481,14 @@ ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
num_write_row(0)
{}
-/*************************************************************************
+/*********************************************************************//**
Destruct ha_innobase handler. */
UNIV_INTERN
ha_innobase::~ha_innobase()
{
}
-/*************************************************************************
+/*********************************************************************//**
Updates the user_thd field in a handle and also allocates a new InnoDB
transaction handle if needed, and updates the transaction fields in the
prebuilt struct. */
@@ -1418,7 +1496,7 @@ UNIV_INTERN inline
void
ha_innobase::update_thd(
/*====================*/
- THD* thd) /* in: thd to use the handle */
+ THD* thd) /*!< in: thd to use the handle */
{
trx_t* trx;
@@ -1432,7 +1510,7 @@ ha_innobase::update_thd(
user_thd = thd;
}
-/*************************************************************************
+/*********************************************************************//**
Updates the user_thd field in a handle and also allocates a new InnoDB
transaction handle if needed, and updates the transaction fields in the
prebuilt struct. */
@@ -1446,7 +1524,7 @@ ha_innobase::update_thd()
update_thd(thd);
}
-/*************************************************************************
+/*********************************************************************//**
Registers that InnoDB takes part in an SQL statement, so that MySQL knows to
roll back the statement if the statement results in an error. This MUST be
called for every SQL statement that may be rolled back by MySQL. Calling this
@@ -1455,15 +1533,15 @@ static inline
void
innobase_register_stmt(
/*===================*/
- handlerton* hton, /* in: Innobase hton */
- THD* thd) /* in: MySQL thd (connection) object */
+ handlerton* hton, /*!< in: Innobase hton */
+ THD* thd) /*!< in: MySQL thd (connection) object */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
/* Register the statement */
trans_register_ha(thd, FALSE, hton);
}
-/*************************************************************************
+/*********************************************************************//**
Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows
to call the InnoDB prepare and commit, or rollback for the transaction. This
MUST be called for every transaction for which the user may call commit or
@@ -1474,8 +1552,8 @@ static inline
void
innobase_register_trx_and_stmt(
/*===========================*/
- handlerton *hton, /* in: Innobase handlerton */
- THD* thd) /* in: MySQL thd (connection) object */
+ handlerton *hton, /*!< in: Innobase handlerton */
+ THD* thd) /*!< in: MySQL thd (connection) object */
{
/* NOTE that actually innobase_register_stmt() registers also
the transaction in the AUTOCOMMIT=1 mode. */
@@ -1532,7 +1610,7 @@ AUTOCOMMIT==0 or we are inside BEGIN ... COMMIT. Thus transactions no longer
put restrictions on the use of the query cache.
*/
-/**********************************************************************
+/******************************************************************//**
The MySQL query cache uses this to check from InnoDB if the query cache at
the moment is allowed to operate on an InnoDB table. The SQL query must
be a non-locking SELECT.
@@ -1549,24 +1627,23 @@ at the start of a SELECT processing. Then the calling thread cannot be
holding any InnoDB semaphores. The calling thread is holding the
query cache mutex, and this function will reserver the InnoDB kernel mutex.
Thus, the 'rank' in sync0sync.h of the MySQL query cache mutex is above
-the InnoDB kernel mutex. */
+the InnoDB kernel mutex.
+@return TRUE if permitted, FALSE if not; note that the value FALSE
+does not mean we should invalidate the query cache: invalidation is
+called explicitly */
static
my_bool
innobase_query_caching_of_table_permitted(
/*======================================*/
- /* out: TRUE if permitted, FALSE if not;
- note that the value FALSE does not mean
- we should invalidate the query cache:
- invalidation is called explicitly */
- THD* thd, /* in: thd of the user who is trying to
+ THD* thd, /*!< in: thd of the user who is trying to
store a result to the query cache or
retrieve it */
- char* full_name, /* in: concatenation of database name,
- the null character '\0', and the table
+ char* full_name, /*!< in: concatenation of database name,
+ the null character NUL, and the table
name */
- uint full_name_len, /* in: length of the full name, i.e.
+ uint full_name_len, /*!< in: length of the full name, i.e.
len(dbname) + len(tablename) + 1 */
- ulonglong *unused) /* unused for this engine */
+ ulonglong *unused) /*!< unused for this engine */
{
ibool is_autocommit;
trx_t* trx;
@@ -1656,21 +1733,21 @@ innobase_query_caching_of_table_permitted(
return((my_bool)FALSE);
}
-/*********************************************************************
-Invalidates the MySQL query cache for the table.
-NOTE that the exact prototype of this function has to be in
-/xtradb/row/row0ins.c! */
+/*****************************************************************//**
+Invalidates the MySQL query cache for the table. */
extern "C" UNIV_INTERN
void
innobase_invalidate_query_cache(
/*============================*/
- trx_t* trx, /* in: transaction which modifies the table */
- char* full_name, /* in: concatenation of database name, null
- char '\0', table name, null char'\0';
- NOTE that in Windows this is always
- in LOWER CASE! */
- ulint full_name_len) /* in: full name length where also the null
- chars count */
+ trx_t* trx, /*!< in: transaction which
+ modifies the table */
+ const char* full_name, /*!< in: concatenation of
+ database name, null char NUL,
+ table name, null char NUL;
+ NOTE that in Windows this is
+ always in LOWER CASE! */
+ ulint full_name_len) /*!< in: full name length where
+ also the null chars count */
{
/* Note that the sync0sync.h rank of the query cache mutex is just
above the InnoDB kernel mutex. The caller of this function must not
@@ -1679,38 +1756,42 @@ innobase_invalidate_query_cache(
/* Argument TRUE below means we are using transactions */
#ifdef HAVE_QUERY_CACHE
mysql_query_cache_invalidate4((THD*) trx->mysql_thd,
- (const char*) full_name,
+ full_name,
(uint32) full_name_len,
TRUE);
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
-and quote it if needed. */
+and quote it if needed.
+@return pointer to the end of buf */
static
char*
innobase_convert_identifier(
/*========================*/
- /* out: pointer to the end of buf */
- char* buf, /* out: buffer for converted identifier */
- ulint buflen, /* in: length of buf, in bytes */
- const char* id, /* in: identifier to convert */
- ulint idlen, /* in: length of id, in bytes */
- void* thd, /* in: MySQL connection thread, or NULL */
- ibool file_id)/* in: TRUE=id is a table or database name;
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool file_id)/*!< in: TRUE=id is a table or database name;
FALSE=id is an UTF-8 string */
{
char nz[NAME_LEN + 1];
+#if MYSQL_VERSION_ID >= 50141
+ char nz2[NAME_LEN + 1 + EXPLAIN_FILENAME_MAX_EXTRA_LENGTH];
+#else /* MYSQL_VERSION_ID >= 50141 */
char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
+#endif /* MYSQL_VERSION_ID >= 50141 */
const char* s = id;
int q;
if (file_id) {
- /* Decode the table name. The filename_to_tablename()
- function expects a NUL-terminated string. The input and
- output strings buffers must not be shared. */
+ /* Decode the table name. The MySQL function expects
+ a NUL-terminated string. The input and output strings
+ buffers must not be shared. */
if (UNIV_UNLIKELY(idlen > (sizeof nz) - 1)) {
idlen = (sizeof nz) - 1;
@@ -1720,7 +1801,13 @@ innobase_convert_identifier(
nz[idlen] = 0;
s = nz2;
+#if MYSQL_VERSION_ID >= 50141
+ idlen = explain_filename((THD*) thd, nz, nz2, sizeof nz2,
+ EXPLAIN_PARTITIONS_AS_COMMENT);
+ goto no_quote;
+#else /* MYSQL_VERSION_ID >= 50141 */
idlen = filename_to_tablename(nz, nz2, sizeof nz2);
+#endif /* MYSQL_VERSION_ID >= 50141 */
}
/* See if the identifier needs to be quoted. */
@@ -1731,6 +1818,9 @@ innobase_convert_identifier(
}
if (q == EOF) {
+#if MYSQL_VERSION_ID >= 50141
+no_quote:
+#endif /* MYSQL_VERSION_ID >= 50141 */
if (UNIV_UNLIKELY(idlen > buflen)) {
idlen = buflen;
}
@@ -1770,20 +1860,20 @@ innobase_convert_identifier(
return(buf);
}
-/*********************************************************************
+/*****************************************************************//**
Convert a table or index name to the MySQL system_charset_info (UTF-8)
-and quote it if needed. */
+and quote it if needed.
+@return pointer to the end of buf */
extern "C" UNIV_INTERN
char*
innobase_convert_name(
/*==================*/
- /* out: pointer to the end of buf */
- char* buf, /* out: buffer for converted identifier */
- ulint buflen, /* in: length of buf, in bytes */
- const char* id, /* in: identifier to convert */
- ulint idlen, /* in: length of id, in bytes */
- void* thd, /* in: MySQL connection thread, or NULL */
- ibool table_id)/* in: TRUE=id is a table or database name;
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool table_id)/*!< in: TRUE=id is a table or database name;
FALSE=id is an index name */
{
char* s = buf;
@@ -1827,32 +1917,32 @@ no_db_name:
}
-/**************************************************************************
-Determines if the currently running transaction has been interrupted. */
+/**********************************************************************//**
+Determines if the currently running transaction has been interrupted.
+@return TRUE if interrupted */
extern "C" UNIV_INTERN
ibool
trx_is_interrupted(
/*===============*/
- /* out: TRUE if interrupted */
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
return(trx && trx->mysql_thd && thd_killed((THD*) trx->mysql_thd));
}
-/******************************************************************
+/**************************************************************//**
Resets some fields of a prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
static
void
reset_template(
/*===========*/
- row_prebuilt_t* prebuilt) /* in/out: prebuilt struct */
+ row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */
{
prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
}
-/*********************************************************************
+/*****************************************************************//**
Call this when you have opened a new table handle in HANDLER, before you
call index_read_idx() etc. Actually, we can let the cursor stay open even
over a transaction commit! Then you should call this before every operation,
@@ -1914,16 +2004,16 @@ ha_innobase::init_table_handle_for_HANDLER(void)
reset_template(prebuilt);
}
-/*************************************************************************
-Opens an InnoDB database. */
+/*********************************************************************//**
+Opens an InnoDB database.
+@return 0 on success, error code on failure */
static
int
innobase_init(
/*==========*/
- /* out: 0 on success, error code on failure */
- void *p) /* in: InnoDB handlerton */
+ void *p) /*!< in: InnoDB handlerton */
{
- static char current_dir[3]; /* Set if using current lib */
+ static char current_dir[3]; /*!< Set if using current lib */
int err;
bool ret;
char *default_path;
@@ -1931,19 +2021,6 @@ innobase_init(
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton *)p;
-
-#ifdef MYSQL_DYNAMIC_PLUGIN
- if (!innodb_plugin_init()) {
- sql_print_error("InnoDB plugin init failed.");
- DBUG_RETURN(-1);
- }
-
- if (innodb_hton_ptr) {
- /* Patch the statically linked handlerton and variables */
- innobase_hton = innodb_hton_ptr;
- }
-#endif /* MYSQL_DYNAMIC_PLUGIN */
-
innodb_hton_ptr = innobase_hton;
innobase_hton->state = SHOW_OPTION_YES;
@@ -2226,8 +2303,8 @@ mem_free_and_error:
/* Did the user specify a format name that we support ?
As a side effect it will update the variable
srv_check_file_format_at_startup */
- if (!innobase_file_format_check_validate(
- innobase_file_format_check)) {
+ if (innobase_file_format_validate_and_set(
+ innobase_file_format_check) < 0) {
sql_print_error("InnoDB: invalid "
"innodb_file_format_check value: "
@@ -2241,13 +2318,34 @@ mem_free_and_error:
}
}
+ if (innobase_change_buffering) {
+ ulint use;
+
+ for (use = 0;
+ use < UT_ARR_SIZE(innobase_change_buffering_values);
+ use++) {
+ if (!innobase_strcasecmp(
+ innobase_change_buffering,
+ innobase_change_buffering_values[use])) {
+ ibuf_use = (ibuf_use_t) use;
+ goto innobase_change_buffering_inited_ok;
+ }
+ }
+
+ sql_print_error("InnoDB: invalid value "
+ "innodb_file_format_check=%s",
+ innobase_change_buffering);
+ goto mem_free_and_error;
+ }
+
+innobase_change_buffering_inited_ok:
ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
innobase_change_buffering = (char*)
innobase_change_buffering_values[ibuf_use];
/* --------------------------------------------------*/
- srv_file_flush_method_str = innobase_unix_file_flush_method;
+ srv_file_flush_method_str = innobase_file_flush_method;
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
srv_n_log_files = (ulint) innobase_log_files_in_group;
@@ -2275,6 +2373,7 @@ mem_free_and_error:
srv_force_recovery = (ulint) innobase_force_recovery;
srv_fast_recovery = (ibool) innobase_fast_recovery;
+ srv_recovery_stats = (ibool) innobase_recovery_stats;
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
srv_use_checksums = (ibool) innobase_use_checksums;
@@ -2310,6 +2409,9 @@ mem_free_and_error:
ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
srv_latin1_ordering = my_charset_latin1.sort_order;
+ innobase_old_blocks_pct = buf_LRU_old_ratio_update(
+ innobase_old_blocks_pct, FALSE);
+
innobase_commit_concurrency_init_default();
/* Since we in this module access directly the fields of a trx
@@ -2399,6 +2501,7 @@ skip_overwrite:
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1;
#ifdef MYSQL_DYNAMIC_PLUGIN
@@ -2416,13 +2519,16 @@ error:
DBUG_RETURN(TRUE);
}
-/***********************************************************************
-Closes an InnoDB database. */
+/*******************************************************************//**
+Closes an InnoDB database.
+@return TRUE if error */
static
int
-innobase_end(handlerton *hton, ha_panic_function type)
-/*==============*/
- /* out: TRUE if error */
+innobase_end(
+/*=========*/
+ handlerton* hton, /*!< in/out: InnoDB handlerton */
+ ha_panic_function type __attribute__((unused)))
+ /*!< in: ha_panic() parameter */
{
int err= 0;
@@ -2450,20 +2556,22 @@ innobase_end(handlerton *hton, ha_panic_function type)
pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
+ pthread_mutex_destroy(&analyze_mutex);
pthread_cond_destroy(&commit_cond);
}
DBUG_RETURN(err);
}
-/********************************************************************
+/****************************************************************//**
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
-the logs, and the name of this function should be innobase_checkpoint. */
+the logs, and the name of this function should be innobase_checkpoint.
+@return TRUE if error */
static
bool
-innobase_flush_logs(handlerton *hton)
-/*=====================*/
- /* out: TRUE if error */
+innobase_flush_logs(
+/*================*/
+ handlerton* hton) /*!< in/out: InnoDB handlerton */
{
bool result = 0;
@@ -2475,7 +2583,7 @@ innobase_flush_logs(handlerton *hton)
DBUG_RETURN(result);
}
-/********************************************************************
+/****************************************************************//**
Return alter table flags supported in an InnoDB database. */
static
uint
@@ -2485,18 +2593,21 @@ innobase_alter_table_flags(
{
return(HA_ONLINE_ADD_INDEX_NO_WRITES
| HA_ONLINE_DROP_INDEX_NO_WRITES
- | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES
+ /* Current InnoDB doesn't sort unique indexes along mysqld's order
+ It is dangerous to use index. So it is disabled until
+ the bug http://bugs.mysql.com/47622 */
+ /* | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES */
| HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES
| HA_ONLINE_ADD_PK_INDEX_NO_WRITES);
}
-/*********************************************************************
+/*****************************************************************//**
Commits a transaction in an InnoDB database. */
static
void
innobase_commit_low(
/*================*/
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
if (trx->conc_state == TRX_NOT_STARTED) {
@@ -2528,18 +2639,18 @@ innobase_commit_low(
trx_commit_for_mysql(trx);
}
-/*********************************************************************
+/*****************************************************************//**
Creates an InnoDB transaction struct for the thd if it does not yet have one.
Starts a new InnoDB transaction if a transaction is not yet started. And
assigns a new snapshot for a consistent read if the transaction does not yet
-have one. */
+have one.
+@return 0 */
static
int
innobase_start_trx_and_assign_read_view(
/*====================================*/
- /* out: 0 */
- handlerton *hton, /* in: Innodb handlerton */
- THD* thd) /* in: MySQL thread handle of the user for whom
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd) /*!< in: MySQL thread handle of the user for whom
the transaction should be committed */
{
trx_t* trx;
@@ -2575,18 +2686,18 @@ innobase_start_trx_and_assign_read_view(
DBUG_RETURN(0);
}
-/*********************************************************************
+/*****************************************************************//**
Commits a transaction in an InnoDB database or marks an SQL statement
-ended. */
+ended.
+@return 0 */
static
int
innobase_commit(
/*============*/
- /* out: 0 */
- handlerton *hton, /* in: Innodb handlerton */
- THD* thd, /* in: MySQL thread handle of the user for whom
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd, /*!< in: MySQL thread handle of the user for whom
the transaction should be committed */
- bool all) /* in: TRUE - commit transaction
+ bool all) /*!< in: TRUE - commit transaction
FALSE - the current SQL statement ended */
{
trx_t* trx;
@@ -2651,10 +2762,28 @@ retry:
}
}
+ /* The following calls to read the MySQL binary log
+ file name and the position return consistent results:
+ 1) Other InnoDB transactions cannot intervene between
+ these calls as we are holding prepare_commit_mutex.
+ 2) Binary logging of other engines is not relevant
+ to InnoDB as all InnoDB requires is that committing
+ InnoDB transactions appear in the same order in the
+ MySQL binary log as they appear in InnoDB logs.
+ 3) A MySQL log file rotation cannot happen because
+ MySQL protects against this by having a counter of
+ transactions in prepared state and it only allows
+ a rotation when the counter drops to zero. See
+ LOCK_prep_xids and COND_prep_xids in log.cc. */
trx->mysql_log_file_name = mysql_bin_log_file_name();
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
+ /* Don't do write + flush right now. For group commit
+ to work we want to do the flush after releasing the
+ prepare_commit_mutex. */
+ trx->flush_log_later = TRUE;
innobase_commit_low(trx);
+ trx->flush_log_later = FALSE;
if (innobase_commit_concurrency > 0) {
pthread_mutex_lock(&commit_cond_m);
@@ -2668,6 +2797,8 @@ retry:
pthread_mutex_unlock(&prepare_commit_mutex);
}
+ /* Now do a write + flush of logs. */
+ trx_commit_complete_for_mysql(trx);
trx->active_trans = 0;
} else {
@@ -2701,17 +2832,17 @@ retry:
DBUG_RETURN(0);
}
-/*********************************************************************
-Rolls back a transaction or the latest SQL statement. */
+/*****************************************************************//**
+Rolls back a transaction or the latest SQL statement.
+@return 0 or error number */
static
int
innobase_rollback(
/*==============*/
- /* out: 0 or error number */
- handlerton *hton, /* in: Innodb handlerton */
- THD* thd, /* in: handle to the MySQL thread of the user
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- bool all) /* in: TRUE - commit transaction
+ bool all) /*!< in: TRUE - commit transaction
FALSE - the current SQL statement ended */
{
int error = 0;
@@ -2729,6 +2860,8 @@ innobase_rollback(
innobase_release_stat_resources(trx);
+ trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
+
/* If we had reserved the auto-inc lock for some table (if
we come here to roll back the latest SQL statement) we
release it now before a possibly lengthy rollback */
@@ -2747,14 +2880,14 @@ innobase_rollback(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Rolls back a transaction */
+/*****************************************************************//**
+Rolls back a transaction
+@return 0 or error number */
static
int
innobase_rollback_trx(
/*==================*/
- /* out: 0 or error number */
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
int error = 0;
@@ -2778,18 +2911,18 @@ innobase_rollback_trx(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Rolls back a transaction to a savepoint. */
+/*****************************************************************//**
+Rolls back a transaction to a savepoint.
+@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
+given name */
static
int
innobase_rollback_to_savepoint(
/*===========================*/
- /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
- no savepoint with the given name */
- handlerton *hton, /* in: Innodb handlerton */
- THD* thd, /* in: handle to the MySQL thread of the user
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- void* savepoint) /* in: savepoint data */
+ void* savepoint) /*!< in: savepoint data */
{
ib_int64_t mysql_binlog_cache_pos;
int error = 0;
@@ -2816,18 +2949,18 @@ innobase_rollback_to_savepoint(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Release transaction savepoint name. */
+/*****************************************************************//**
+Release transaction savepoint name.
+@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
+given name */
static
int
innobase_release_savepoint(
/*=======================*/
- /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
- no savepoint with the given name */
- handlerton* hton, /* in: handlerton for Innodb */
- THD* thd, /* in: handle to the MySQL thread of the user
+ handlerton* hton, /*!< in: handlerton for Innodb */
+ THD* thd, /*!< in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- void* savepoint) /* in: savepoint data */
+ void* savepoint) /*!< in: savepoint data */
{
int error = 0;
trx_t* trx;
@@ -2847,16 +2980,16 @@ innobase_release_savepoint(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Sets a transaction savepoint. */
+/*****************************************************************//**
+Sets a transaction savepoint.
+@return always 0, that is, always succeeds */
static
int
innobase_savepoint(
/*===============*/
- /* out: always 0, that is, always succeeds */
- handlerton* hton, /* in: handle to the Innodb handlerton */
- THD* thd, /* in: handle to the MySQL thread */
- void* savepoint) /* in: savepoint data */
+ handlerton* hton, /*!< in: handle to the Innodb handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread */
+ void* savepoint) /*!< in: savepoint data */
{
int error = 0;
trx_t* trx;
@@ -2894,15 +3027,15 @@ innobase_savepoint(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Frees a possible InnoDB trx object associated with the current THD. */
+/*****************************************************************//**
+Frees a possible InnoDB trx object associated with the current THD.
+@return 0 or error number */
static
int
innobase_close_connection(
/*======================*/
- /* out: 0 or error number */
- handlerton* hton, /* in: innobase handlerton */
- THD* thd) /* in: handle to the MySQL thread of the user
+ handlerton* hton, /*!< in: innobase handlerton */
+ THD* thd) /*!< in: handle to the MySQL thread of the user
whose resources should be free'd */
{
trx_t* trx;
@@ -2939,21 +3072,18 @@ innobase_close_connection(
}
-/*****************************************************************************
+/*************************************************************************//**
** InnoDB database tables
*****************************************************************************/
-/********************************************************************
-Get the record format from the data dictionary. */
+/****************************************************************//**
+Get the record format from the data dictionary.
+@return one of ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT,
+ROW_TYPE_COMPRESSED, ROW_TYPE_DYNAMIC */
UNIV_INTERN
enum row_type
ha_innobase::get_row_type() const
/*=============================*/
- /* out: one of
- ROW_TYPE_REDUNDANT,
- ROW_TYPE_COMPACT,
- ROW_TYPE_COMPRESSED,
- ROW_TYPE_DYNAMIC */
{
if (prebuilt && prebuilt->table) {
const ulint flags = prebuilt->table->flags;
@@ -2984,11 +3114,13 @@ ha_innobase::get_row_type() const
-/********************************************************************
-Get the table flags to use for the statement. */
+/****************************************************************//**
+Get the table flags to use for the statement.
+@return table flags */
UNIV_INTERN
handler::Table_flags
ha_innobase::table_flags() const
+/*============================*/
{
/* Need to use tx_isolation here since table flags is (also)
called before prebuilt is inited. */
@@ -2998,58 +3130,81 @@ ha_innobase::table_flags() const
return int_table_flags | HA_BINLOG_STMT_CAPABLE;
}
-/********************************************************************
+/****************************************************************//**
Gives the file extension of an InnoDB single-table tablespace. */
static const char* ha_innobase_exts[] = {
".ibd",
NullS
};
+/****************************************************************//**
+Returns the table type (storage engine name).
+@return table type */
UNIV_INTERN
const char*
ha_innobase::table_type() const
/*===========================*/
- /* out: table type */
{
return(innobase_hton_name);
}
+/****************************************************************//**
+Returns the index type. */
UNIV_INTERN
const char*
-ha_innobase::index_type(uint)
-/*=========================*/
- /* out: index type */
+ha_innobase::index_type(
+/*====================*/
+ uint)
+ /*!< out: index type */
{
return("BTREE");
}
+/****************************************************************//**
+Returns the table file name extension.
+@return file extension string */
UNIV_INTERN
const char**
ha_innobase::bas_ext() const
/*========================*/
- /* out: file extension string */
{
return(ha_innobase_exts);
}
+/****************************************************************//**
+Returns the operations supported for indexes.
+@return flags of supported operations */
UNIV_INTERN
ulong
-ha_innobase::index_flags(uint, uint, bool) const
+ha_innobase::index_flags(
+/*=====================*/
+ uint,
+ uint,
+ bool)
+const
{
return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER
| HA_READ_RANGE | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN);
}
+/****************************************************************//**
+Returns the maximum number of keys.
+@return MAX_KEY */
UNIV_INTERN
uint
ha_innobase::max_supported_keys() const
+/*===================================*/
{
return(MAX_KEY);
}
+/****************************************************************//**
+Returns the maximum key length.
+@return maximum supported key length, in bytes */
UNIV_INTERN
uint
ha_innobase::max_supported_key_length() const
+/*=========================================*/
{
/* An InnoDB page must store >= 2 keys; a secondary key record
must also contain the primary key value: max key length is
@@ -3059,6 +3214,9 @@ ha_innobase::max_supported_key_length() const
return(3500);
}
+/****************************************************************//**
+Returns the key map of keys that are usable for scanning.
+@return key_map_full */
UNIV_INTERN
const key_map*
ha_innobase::keys_to_use_for_scanning()
@@ -3066,6 +3224,9 @@ ha_innobase::keys_to_use_for_scanning()
return(&key_map_full);
}
+/****************************************************************//**
+Determines if table caching is supported.
+@return HA_CACHE_TBL_ASKTRANSACT */
UNIV_INTERN
uint8
ha_innobase::table_cache_type()
@@ -3073,6 +3234,9 @@ ha_innobase::table_cache_type()
return(HA_CACHE_TBL_ASKTRANSACT);
}
+/****************************************************************//**
+Determines if the primary key is clustered index.
+@return true */
UNIV_INTERN
bool
ha_innobase::primary_key_is_clustered()
@@ -3080,7 +3244,7 @@ ha_innobase::primary_key_is_clustered()
return(true);
}
-/*********************************************************************
+/*****************************************************************//**
Normalizes a table name string. A normalized name consists of the
database name catenated to '/' and table name. An example:
test/mytable. On Windows normalization puts both the database name and the
@@ -3089,9 +3253,9 @@ static
void
normalize_table_name(
/*=================*/
- char* norm_name, /* out: normalized name as a
+ char* norm_name, /*!< out: normalized name as a
null-terminated string */
- const char* name) /* in: table name string */
+ const char* name) /*!< in: table name string */
{
char* name_ptr;
char* db_ptr;
@@ -3126,9 +3290,10 @@ normalize_table_name(
#endif
}
-/************************************************************************
+/********************************************************************//**
Set the autoinc column max value. This should only be called once from
-ha_innobase::open(). Therefore there's no need for a covering lock. */
+ha_innobase::open(). Therefore there's no need for a covering lock.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
ha_innobase::innobase_initialize_autoinc()
@@ -3137,8 +3302,7 @@ ha_innobase::innobase_initialize_autoinc()
dict_index_t* index;
ulonglong auto_inc;
const char* col_name;
- ulint error = DB_SUCCESS;
- dict_table_t* innodb_table = prebuilt->table;
+ ulint error;
col_name = table->found_next_number_field->field_name;
index = innobase_get_index(table->s->next_number_index);
@@ -3146,35 +3310,53 @@ ha_innobase::innobase_initialize_autoinc()
/* Execute SELECT MAX(col_name) FROM TABLE; */
error = row_search_max_autoinc(index, col_name, &auto_inc);
- if (error == DB_SUCCESS) {
+ switch (error) {
+ case DB_SUCCESS:
- /* At the this stage we dont' know the increment
+ /* At the this stage we don't know the increment
or the offset, so use default inrement of 1. */
++auto_inc;
+ break;
- dict_table_autoinc_initialize(innodb_table, auto_inc);
-
- } else {
+ case DB_RECORD_NOT_FOUND:
ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Error: (%lu) Couldn't read "
- "the MAX(%s) autoinc value from the "
- "index (%s).\n", error, col_name, index->name);
+ fprintf(stderr, " InnoDB: MySQL and InnoDB data "
+ "dictionaries are out of sync.\n"
+ "InnoDB: Unable to find the AUTOINC column %s in the "
+ "InnoDB table %s.\n"
+ "InnoDB: We set the next AUTOINC column value to the "
+ "maximum possible value,\n"
+ "InnoDB: in effect disabling the AUTOINC next value "
+ "generation.\n"
+ "InnoDB: You can either set the next AUTOINC value "
+ "explicitly using ALTER TABLE\n"
+ "InnoDB: or fix the data dictionary by recreating "
+ "the table.\n",
+ col_name, index->table->name);
+
+ auto_inc = 0xFFFFFFFFFFFFFFFFULL;
+ break;
+
+ default:
+ return(error);
}
- return(error);
+ dict_table_autoinc_initialize(prebuilt->table, auto_inc);
+
+ return(DB_SUCCESS);
}
-/*********************************************************************
+/*****************************************************************//**
Creates and opens a handle to a table which already exists in an InnoDB
-database. */
+database.
+@return 1 if error, 0 if success */
UNIV_INTERN
int
ha_innobase::open(
/*==============*/
- /* out: 1 if error, 0 if success */
- const char* name, /* in: table name */
- int mode, /* in: not used */
- uint test_if_locked) /* in: not used */
+ const char* name, /*!< in: table name */
+ int mode, /*!< in: not used */
+ uint test_if_locked) /*!< in: not used */
{
dict_table_t* ib_table;
char norm_name[1000];
@@ -3241,7 +3423,7 @@ retry:
if (is_part) {
sql_print_error("Failed to open table %s after "
- "%lu attemtps.\n", norm_name,
+ "%lu attempts.\n", norm_name,
retries);
}
@@ -3257,7 +3439,7 @@ retry:
"or, the table contains indexes that this "
"version of the engine\n"
"doesn't support.\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
+ "See " REFMAN "innodb-troubleshooting.html\n"
"how you can resolve the problem.\n",
norm_name);
free_share(share);
@@ -3273,7 +3455,7 @@ retry:
"Have you deleted the .ibd file from the "
"database directory under\nthe MySQL datadir, "
"or have you used DISCARD TABLESPACE?\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
+ "See " REFMAN "innodb-troubleshooting.html\n"
"how you can resolve the problem.\n",
norm_name);
free_share(share);
@@ -3379,7 +3561,6 @@ retry:
if (dict_table_autoinc_read(prebuilt->table) == 0) {
error = innobase_initialize_autoinc();
- /* Should always succeed! */
ut_a(error == DB_SUCCESS);
}
@@ -3396,13 +3577,13 @@ ha_innobase::max_supported_key_part_length() const
return(DICT_MAX_INDEX_COL_LEN - 1);
}
-/**********************************************************************
-Closes a handle to an InnoDB table. */
+/******************************************************************//**
+Closes a handle to an InnoDB table.
+@return 0 */
UNIV_INTERN
int
ha_innobase::close(void)
/*====================*/
- /* out: 0 */
{
THD* thd;
@@ -3428,30 +3609,30 @@ ha_innobase::close(void)
/* The following accessor functions should really be inside MySQL code! */
-/******************************************************************
-Gets field offset for a field in a table. */
+/**************************************************************//**
+Gets field offset for a field in a table.
+@return offset */
static inline
uint
get_field_offset(
/*=============*/
- /* out: offset */
- TABLE* table, /* in: MySQL table object */
- Field* field) /* in: MySQL field object */
+ TABLE* table, /*!< in: MySQL table object */
+ Field* field) /*!< in: MySQL field object */
{
return((uint) (field->ptr - table->record[0]));
}
-/******************************************************************
+/**************************************************************//**
Checks if a field in a record is SQL NULL. Uses the record format
-information in table to track the null bit in record. */
+information in table to track the null bit in record.
+@return 1 if NULL, 0 otherwise */
static inline
uint
field_in_record_is_null(
/*====================*/
- /* out: 1 if NULL, 0 otherwise */
- TABLE* table, /* in: MySQL table object */
- Field* field, /* in: MySQL field object */
- char* record) /* in: a row in MySQL format */
+ TABLE* table, /*!< in: MySQL table object */
+ Field* field, /*!< in: MySQL field object */
+ char* record) /*!< in: a row in MySQL format */
{
int null_offset;
@@ -3471,16 +3652,16 @@ field_in_record_is_null(
return(0);
}
-/******************************************************************
+/**************************************************************//**
Sets a field in a record to SQL NULL. Uses the record format
information in table to track the null bit in record. */
static inline
void
set_field_in_record_to_null(
/*========================*/
- TABLE* table, /* in: MySQL table object */
- Field* field, /* in: MySQL field object */
- char* record) /* in: a row in MySQL format */
+ TABLE* table, /*!< in: MySQL table object */
+ Field* field, /*!< in: MySQL field object */
+ char* record) /*!< in: a row in MySQL format */
{
int null_offset;
@@ -3490,24 +3671,23 @@ set_field_in_record_to_null(
record[null_offset] = record[null_offset] | field->null_bit;
}
-/*****************************************************************
+/*************************************************************//**
InnoDB uses this function to compare two data fields for which the data type
is such that we must use MySQL code to compare them. NOTE that the prototype
of this function is in rem0cmp.c in InnoDB source code! If you change this
-function, remember to update the prototype there! */
+function, remember to update the prototype there!
+@return 1, 0, -1, if a is greater, equal, less than b, respectively */
extern "C" UNIV_INTERN
int
innobase_mysql_cmp(
/*===============*/
- /* out: 1, 0, -1, if a is greater,
- equal, less than b, respectively */
- int mysql_type, /* in: MySQL type */
- uint charset_number, /* in: number of the charset */
- const unsigned char* a, /* in: data field */
- unsigned int a_length, /* in: data field length,
+ int mysql_type, /*!< in: MySQL type */
+ uint charset_number, /*!< in: number of the charset */
+ const unsigned char* a, /*!< in: data field */
+ unsigned int a_length, /*!< in: data field length,
not UNIV_SQL_NULL */
- const unsigned char* b, /* in: data field */
- unsigned int b_length) /* in: data field length,
+ const unsigned char* b, /*!< in: data field */
+ unsigned int b_length) /*!< in: data field length,
not UNIV_SQL_NULL */
{
CHARSET_INFO* charset;
@@ -3572,22 +3752,21 @@ innobase_mysql_cmp(
return(0);
}
-/******************************************************************
+/**************************************************************//**
Converts a MySQL type to an InnoDB type. Note that this function returns
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
-VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'. */
+VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
+@return DATA_BINARY, DATA_VARCHAR, ... */
extern "C" UNIV_INTERN
ulint
get_innobase_type_from_mysql_type(
/*==============================*/
- /* out: DATA_BINARY,
- DATA_VARCHAR, ... */
- ulint* unsigned_flag, /* out: DATA_UNSIGNED if an
+ ulint* unsigned_flag, /*!< out: DATA_UNSIGNED if an
'unsigned type';
at least ENUM and SET,
and unsigned integer
types are 'unsigned types' */
- const void* f) /* in: MySQL Field */
+ const void* f) /*!< in: MySQL Field */
{
const class Field* field = reinterpret_cast<const class Field*>(f);
@@ -3680,15 +3859,15 @@ get_innobase_type_from_mysql_type(
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Writes an unsigned integer value < 64k to 2 bytes, in the little-endian
storage format. */
static inline
void
innobase_write_to_2_little_endian(
/*==============================*/
- byte* buf, /* in: where to store */
- ulint val) /* in: value to write, must be < 64k */
+ byte* buf, /*!< in: where to store */
+ ulint val) /*!< in: value to write, must be < 64k */
{
ut_a(val < 256 * 256);
@@ -3696,31 +3875,31 @@ innobase_write_to_2_little_endian(
buf[1] = (byte)(val / 256);
}
-/***********************************************************************
+/*******************************************************************//**
Reads an unsigned integer value < 64k from 2 bytes, in the little-endian
-storage format. */
+storage format.
+@return value */
static inline
uint
innobase_read_from_2_little_endian(
/*===============================*/
- /* out: value */
- const uchar* buf) /* in: from where to read */
+ const uchar* buf) /*!< in: from where to read */
{
return (uint) ((ulint)(buf[0]) + 256 * ((ulint)(buf[1])));
}
-/***********************************************************************
-Stores a key value for a row to a buffer. */
+/*******************************************************************//**
+Stores a key value for a row to a buffer.
+@return key value length as stored in buff */
UNIV_INTERN
uint
ha_innobase::store_key_val_for_row(
/*===============================*/
- /* out: key value length as stored in buff */
- uint keynr, /* in: key number */
- char* buff, /* in/out: buffer for the key value (in MySQL
+ uint keynr, /*!< in: key number */
+ char* buff, /*!< in/out: buffer for the key value (in MySQL
format) */
- uint buff_len,/* in: buffer length */
- const uchar* record)/* in: row in MySQL format */
+ uint buff_len,/*!< in: buffer length */
+ const uchar* record)/*!< in: row in MySQL format */
{
KEY* key_info = table->key_info + keynr;
KEY_PART_INFO* key_part = key_info->key_part;
@@ -3843,7 +4022,10 @@ ha_innobase::store_key_val_for_row(
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
- || mysql_type == MYSQL_TYPE_LONG_BLOB) {
+ || mysql_type == MYSQL_TYPE_LONG_BLOB
+ /* MYSQL_TYPE_GEOMETRY data is treated
+ as BLOB data in innodb. */
+ || mysql_type == MYSQL_TYPE_GEOMETRY) {
CHARSET_INFO* cs;
ulint key_len;
@@ -3983,15 +4165,15 @@ ha_innobase::store_key_val_for_row(
DBUG_RETURN((uint)(buff - buff_start));
}
-/******************************************************************
+/**************************************************************//**
Builds a 'template' to the prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
static
void
build_template(
/*===========*/
- row_prebuilt_t* prebuilt, /* in/out: prebuilt struct */
- THD* thd, /* in: current user thread, used
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
+ THD* thd, /*!< in: current user thread, used
only if templ_type is
ROW_MYSQL_REC_FIELDS */
TABLE* table, /* in: MySQL table */
@@ -4237,7 +4419,7 @@ skip_field:
}
}
-/************************************************************************
+/********************************************************************//**
Get the upper limit of the MySQL integral and floating-point type. */
UNIV_INTERN
ulonglong
@@ -4298,18 +4480,17 @@ ha_innobase::innobase_get_int_col_max_value(
return(max_value);
}
-/************************************************************************
+/********************************************************************//**
This special handling is really to overcome the limitations of MySQL's
binlogging. We need to eliminate the non-determinism that will arise in
INSERT ... SELECT type of statements, since MySQL binlog only stores the
min value of the autoinc interval. Once that is fixed we can get rid of
-the special lock handling.*/
+the special lock handling.
+@return DB_SUCCESS if all OK else error code */
UNIV_INTERN
ulint
ha_innobase::innobase_lock_autoinc(void)
/*====================================*/
- /* out: DB_SUCCESS if all OK else
- error code */
{
ulint error = DB_SUCCESS;
@@ -4359,15 +4540,14 @@ ha_innobase::innobase_lock_autoinc(void)
return(ulong(error));
}
-/************************************************************************
-Reset the autoinc value in the table.*/
+/********************************************************************//**
+Reset the autoinc value in the table.
+@return DB_SUCCESS if all went well else error code */
UNIV_INTERN
ulint
ha_innobase::innobase_reset_autoinc(
/*================================*/
- /* out: DB_SUCCESS if all went well
- else error code */
- ulonglong autoinc) /* in: value to store */
+ ulonglong autoinc) /*!< in: value to store */
{
ulint error;
@@ -4383,16 +4563,15 @@ ha_innobase::innobase_reset_autoinc(
return(ulong(error));
}
-/************************************************************************
+/********************************************************************//**
Store the autoinc value in the table. The autoinc value is only set if
-it's greater than the existing autoinc value in the table.*/
+it's greater than the existing autoinc value in the table.
+@return DB_SUCCESS if all went well else error code */
UNIV_INTERN
ulint
ha_innobase::innobase_set_max_autoinc(
/*==================================*/
- /* out: DB_SUCCES if all went well
- else error code */
- ulonglong auto_inc) /* in: value to store */
+ ulonglong auto_inc) /*!< in: value to store */
{
ulint error;
@@ -4408,15 +4587,15 @@ ha_innobase::innobase_set_max_autoinc(
return(ulong(error));
}
-/************************************************************************
+/********************************************************************//**
Stores a row in an InnoDB database, to the table specified in this
-handle. */
+handle.
+@return error code */
UNIV_INTERN
int
ha_innobase::write_row(
/*===================*/
- /* out: error code */
- uchar* record) /* in: a row in MySQL format */
+ uchar* record) /*!< in: a row in MySQL format */
{
ulint error = 0;
int error_result= 0;
@@ -4611,24 +4790,29 @@ no_commit:
update the table upper limit. Note: last_value
will be 0 if get_auto_increment() was not called.*/
- if (auto_inc <= col_max_value
- && auto_inc >= prebuilt->autoinc_last_value) {
+ if (auto_inc >= prebuilt->autoinc_last_value) {
set_max_autoinc:
- ut_a(prebuilt->autoinc_increment > 0);
+ /* This should filter out the negative
+ values set explicitly by the user. */
+ if (auto_inc <= col_max_value) {
+ ut_a(prebuilt->autoinc_increment > 0);
- ulonglong need;
- ulonglong offset;
+ ulonglong need;
+ ulonglong offset;
- offset = prebuilt->autoinc_offset;
- need = prebuilt->autoinc_increment;
+ offset = prebuilt->autoinc_offset;
+ need = prebuilt->autoinc_increment;
- auto_inc = innobase_next_autoinc(
- auto_inc, need, offset, col_max_value);
+ auto_inc = innobase_next_autoinc(
+ auto_inc,
+ need, offset, col_max_value);
- err = innobase_set_max_autoinc(auto_inc);
+ err = innobase_set_max_autoinc(
+ auto_inc);
- if (err != DB_SUCCESS) {
- error = err;
+ if (err != DB_SUCCESS) {
+ error = err;
+ }
}
}
break;
@@ -4648,23 +4832,23 @@ func_exit:
DBUG_RETURN(error_result);
}
-/**************************************************************************
+/**********************************************************************//**
Checks which fields have changed in a row and stores information
-of them to an update vector. */
+of them to an update vector.
+@return error number or 0 */
static
int
calc_row_difference(
/*================*/
- /* out: error number or 0 */
- upd_t* uvect, /* in/out: update vector */
- uchar* old_row, /* in: old row in MySQL format */
- uchar* new_row, /* in: new row in MySQL format */
- struct st_table* table, /* in: table in MySQL data
+ upd_t* uvect, /*!< in/out: update vector */
+ uchar* old_row, /*!< in: old row in MySQL format */
+ uchar* new_row, /*!< in: new row in MySQL format */
+ struct st_table* table, /*!< in: table in MySQL data
dictionary */
- uchar* upd_buff, /* in: buffer to use */
- ulint buff_len, /* in: buffer length */
- row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
- THD* thd) /* in: user thread */
+ uchar* upd_buff, /*!< in: buffer to use */
+ ulint buff_len, /*!< in: buffer length */
+ row_prebuilt_t* prebuilt, /*!< in: InnoDB prebuilt struct */
+ THD* thd) /*!< in: user thread */
{
uchar* original_upd_buff = upd_buff;
Field* field;
@@ -4800,20 +4984,20 @@ calc_row_difference(
return(0);
}
-/**************************************************************************
+/**********************************************************************//**
Updates a row given as a parameter to a new value. Note that we are given
whole rows, not just the fields which are updated: this incurs some
overhead for CPU when we check which fields are actually updated.
TODO: currently InnoDB does not prevent the 'Halloween problem':
in a searched update a single row can get updated several times
-if its index columns are updated! */
+if its index columns are updated!
+@return error number or 0 */
UNIV_INTERN
int
ha_innobase::update_row(
/*====================*/
- /* out: error number or 0 */
- const uchar* old_row, /* in: old row in MySQL format */
- uchar* new_row) /* in: new row in MySQL format */
+ const uchar* old_row, /*!< in: old row in MySQL format */
+ uchar* new_row) /*!< in: new row in MySQL format */
{
upd_t* uvect;
int error = 0;
@@ -4913,14 +5097,14 @@ ha_innobase::update_row(
DBUG_RETURN(error);
}
-/**************************************************************************
-Deletes a row given as the parameter. */
+/**********************************************************************//**
+Deletes a row given as the parameter.
+@return error number or 0 */
UNIV_INTERN
int
ha_innobase::delete_row(
/*====================*/
- /* out: error number or 0 */
- const uchar* record) /* in: a row in MySQL format */
+ const uchar* record) /*!< in: a row in MySQL format */
{
int error = 0;
trx_t* trx = thd_to_trx(user_thd);
@@ -4956,7 +5140,7 @@ ha_innobase::delete_row(
DBUG_RETURN(error);
}
-/**************************************************************************
+/**********************************************************************//**
Removes a new lock set on a row, if it was not read optimistically. This can
be called after a row has been read in the processing of an UPDATE or a DELETE
query, if the option innodb_locks_unsafe_for_binlog is set. */
@@ -5024,55 +5208,24 @@ ha_innobase::try_semi_consistent_read(bool yes)
}
}
-#ifdef ROW_MERGE_IS_INDEX_USABLE
-/**********************************************************************
-Check if an index can be used by the optimizer. */
-UNIV_INTERN
-bool
-ha_innobase::is_index_available(
-/*============================*/
- /* out: true if available else false*/
- uint keynr) /* in: index number to check */
-{
- DBUG_ENTER("ha_innobase::is_index_available");
-
- if (table && keynr != MAX_KEY && table->s->keys > 0) {
- const dict_index_t* index;
- const KEY* key = table->key_info + keynr;
-
- ut_ad(user_thd == ha_thd());
- ut_a(prebuilt->trx == thd_to_trx(user_thd));
-
- index = dict_table_get_index_on_name(
- prebuilt->table, key->name);
-
- if (!row_merge_is_index_usable(prebuilt->trx, index)) {
-
- DBUG_RETURN(false);
- }
- }
-
- DBUG_RETURN(true);
-}
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
-
-/**********************************************************************
-Initializes a handle to use an index. */
+/******************************************************************//**
+Initializes a handle to use an index.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::index_init(
/*====================*/
- /* out: 0 or error number */
- uint keynr, /* in: key (index) number */
- bool sorted) /* in: 1 if result MUST be sorted according to index */
+ uint keynr, /*!< in: key (index) number */
+ bool sorted) /*!< in: 1 if result MUST be sorted according to index */
{
DBUG_ENTER("index_init");
DBUG_RETURN(change_active_index(keynr));
}
-/**********************************************************************
-Currently does nothing. */
+/******************************************************************//**
+Currently does nothing.
+@return 0 */
UNIV_INTERN
int
ha_innobase::index_end(void)
@@ -5086,7 +5239,7 @@ ha_innobase::index_end(void)
DBUG_RETURN(error);
}
-/*************************************************************************
+/*********************************************************************//**
Converts a search mode flag understood by MySQL to a flag understood
by InnoDB. */
static inline
@@ -5191,18 +5344,17 @@ overwrap, we use this test only as a secondary way of determining the
start of a new SQL statement. */
-/**************************************************************************
+/**********************************************************************//**
Positions an index cursor to the index specified in the handle. Fetches the
-row if any. */
+row if any.
+@return 0, HA_ERR_KEY_NOT_FOUND, or error number */
UNIV_INTERN
int
ha_innobase::index_read(
/*====================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND,
- or error number */
- uchar* buf, /* in/out: buffer for the returned
+ uchar* buf, /*!< in/out: buffer for the returned
row */
- const uchar* key_ptr, /* in: key value; if this is NULL
+ const uchar* key_ptr, /*!< in: key value; if this is NULL
we position the cursor at the
start or end of index; this can
also contain an InnoDB row id, in
@@ -5211,8 +5363,8 @@ ha_innobase::index_read(
also be a prefix of a full key value,
and the last column can be a prefix
of a full column */
- uint key_len,/* in: key value length */
- enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
+ uint key_len,/*!< in: key value length */
+ enum ha_rkey_function find_flag)/*!< in: search flags from my_base.h */
{
ulint mode;
dict_index_t* index;
@@ -5228,6 +5380,11 @@ ha_innobase::index_read(
index = prebuilt->index;
+ if (UNIV_UNLIKELY(index == NULL)) {
+ prebuilt->index_usable = FALSE;
+ DBUG_RETURN(HA_ERR_CRASHED);
+ }
+
/* Note that if the index for which the search template is built is not
necessarily prebuilt->index, but can also be the clustered index */
@@ -5308,32 +5465,31 @@ ha_innobase::index_read(
DBUG_RETURN(error);
}
-/***********************************************************************
+/*******************************************************************//**
The following functions works like index_read, but it find the last
-row with the current key value or prefix. */
+row with the current key value or prefix.
+@return 0, HA_ERR_KEY_NOT_FOUND, or an error code */
UNIV_INTERN
int
ha_innobase::index_read_last(
/*=========================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND, or an
- error code */
- uchar* buf, /* out: fetched row */
- const uchar* key_ptr,/* in: key value, or a prefix of a full
+ uchar* buf, /*!< out: fetched row */
+ const uchar* key_ptr,/*!< in: key value, or a prefix of a full
key value */
- uint key_len)/* in: length of the key val or prefix
+ uint key_len)/*!< in: length of the key val or prefix
in bytes */
{
return(index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST));
}
-/************************************************************************
-Get the index for a handle. Does not change active index.*/
+/********************************************************************//**
+Get the index for a handle. Does not change active index.
+@return NULL or index instance. */
UNIV_INTERN
dict_index_t*
ha_innobase::innobase_get_index(
/*============================*/
- /* out: NULL or index instance. */
- uint keynr) /* in: use this index; MAX_KEY means always
+ uint keynr) /*!< in: use this index; MAX_KEY means always
clustered index, even if it was internally
generated by InnoDB */
{
@@ -5366,14 +5522,14 @@ ha_innobase::innobase_get_index(
DBUG_RETURN(index);
}
-/************************************************************************
-Changes the active index of a handle. */
+/********************************************************************//**
+Changes the active index of a handle.
+@return 0 or error code */
UNIV_INTERN
int
ha_innobase::change_active_index(
/*=============================*/
- /* out: 0 or error code */
- uint keynr) /* in: use this index; MAX_KEY means always clustered
+ uint keynr) /*!< in: use this index; MAX_KEY means always clustered
index, even if it was internally generated by
InnoDB */
{
@@ -5389,9 +5545,24 @@ ha_innobase::change_active_index(
if (UNIV_UNLIKELY(!prebuilt->index)) {
sql_print_warning("InnoDB: change_active_index(%u) failed",
keynr);
+ prebuilt->index_usable = FALSE;
DBUG_RETURN(1);
}
+ prebuilt->index_usable = row_merge_is_index_usable(prebuilt->trx,
+ prebuilt->index);
+
+ if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
+ push_warning_printf(user_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ HA_ERR_TABLE_DEF_CHANGED,
+ "InnoDB: insufficient history for index %u",
+ keynr);
+ /* The caller seems to ignore this. Thus, we must check
+ this again in row_search_for_mysql(). */
+ DBUG_RETURN(convert_error_code_to_mysql(DB_MISSING_HISTORY,
+ 0, NULL));
+ }
+
ut_a(prebuilt->search_tuple != 0);
dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
@@ -5410,23 +5581,23 @@ ha_innobase::change_active_index(
DBUG_RETURN(0);
}
-/**************************************************************************
+/**********************************************************************//**
Positions an index cursor to the index specified in keynr. Fetches the
-row if any. */
-/* ??? This is only used to read whole keys ??? */
+row if any.
+??? This is only used to read whole keys ???
+@return error number or 0 */
UNIV_INTERN
int
ha_innobase::index_read_idx(
/*========================*/
- /* out: error number or 0 */
- uchar* buf, /* in/out: buffer for the returned
+ uchar* buf, /*!< in/out: buffer for the returned
row */
- uint keynr, /* in: use this index */
- const uchar* key, /* in: key value; if this is NULL
+ uint keynr, /*!< in: use this index */
+ const uchar* key, /*!< in: key value; if this is NULL
we position the cursor at the
start or end of index */
- uint key_len, /* in: key value length */
- enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
+ uint key_len, /*!< in: key value length */
+ enum ha_rkey_function find_flag)/*!< in: search flags from my_base.h */
{
if (change_active_index(keynr)) {
@@ -5436,19 +5607,18 @@ ha_innobase::index_read_idx(
return(index_read(buf, key, key_len, find_flag));
}
-/***************************************************************************
+/***********************************************************************//**
Reads the next or previous row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read.
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::general_fetch(
/*=======================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- uchar* buf, /* in/out: buffer for next row in MySQL
+ uchar* buf, /*!< in/out: buffer for next row in MySQL
format */
- uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
- uint match_mode) /* in: 0, ROW_SEL_EXACT, or
+ uint direction, /*!< in: ROW_SEL_NEXT or ROW_SEL_PREV */
+ uint match_mode) /*!< in: 0, ROW_SEL_EXACT, or
ROW_SEL_EXACT_PREFIX */
{
ulint ret;
@@ -5488,16 +5658,15 @@ ha_innobase::general_fetch(
DBUG_RETURN(error);
}
-/***************************************************************************
+/***********************************************************************//**
Reads the next row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read.
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::index_next(
/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- uchar* buf) /* in/out: buffer for next row in MySQL
+ uchar* buf) /*!< in/out: buffer for next row in MySQL
format */
{
ha_statistic_increment(&SSV::ha_read_next_count);
@@ -5505,47 +5674,46 @@ ha_innobase::index_next(
return(general_fetch(buf, ROW_SEL_NEXT, 0));
}
-/***********************************************************************
-Reads the next row matching to the key value given as the parameter. */
+/*******************************************************************//**
+Reads the next row matching to the key value given as the parameter.
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::index_next_same(
/*=========================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- uchar* buf, /* in/out: buffer for the row */
- const uchar* key, /* in: key value */
- uint keylen) /* in: key value length */
+ uchar* buf, /*!< in/out: buffer for the row */
+ const uchar* key, /*!< in: key value */
+ uint keylen) /*!< in: key value length */
{
ha_statistic_increment(&SSV::ha_read_next_count);
return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
}
-/***************************************************************************
+/***********************************************************************//**
Reads the previous row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read.
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::index_prev(
/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error number */
- uchar* buf) /* in/out: buffer for previous row in MySQL format */
+ uchar* buf) /*!< in/out: buffer for previous row in MySQL format */
{
ha_statistic_increment(&SSV::ha_read_prev_count);
return(general_fetch(buf, ROW_SEL_PREV, 0));
}
-/************************************************************************
+/********************************************************************//**
Positions a cursor on the first record in an index and reads the
-corresponding row to buf. */
+corresponding row to buf.
+@return 0, HA_ERR_END_OF_FILE, or error code */
UNIV_INTERN
int
ha_innobase::index_first(
/*=====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error code */
- uchar* buf) /* in/out: buffer for the row */
+ uchar* buf) /*!< in/out: buffer for the row */
{
int error;
@@ -5563,15 +5731,15 @@ ha_innobase::index_first(
DBUG_RETURN(error);
}
-/************************************************************************
+/********************************************************************//**
Positions a cursor on the last record in an index and reads the
-corresponding row to buf. */
+corresponding row to buf.
+@return 0, HA_ERR_END_OF_FILE, or error code */
UNIV_INTERN
int
ha_innobase::index_last(
/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error code */
- uchar* buf) /* in/out: buffer for the row */
+ uchar* buf) /*!< in/out: buffer for the row */
{
int error;
@@ -5589,14 +5757,14 @@ ha_innobase::index_last(
DBUG_RETURN(error);
}
-/********************************************************************
-Initialize a table scan. */
+/****************************************************************//**
+Initialize a table scan.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::rnd_init(
/*==================*/
- /* out: 0 or error number */
- bool scan) /* in: TRUE if table/index scan FALSE otherwise */
+ bool scan) /*!< in: TRUE if table/index scan FALSE otherwise */
{
int err;
@@ -5621,26 +5789,26 @@ ha_innobase::rnd_init(
return(err);
}
-/*********************************************************************
-Ends a table scan. */
+/*****************************************************************//**
+Ends a table scan.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::rnd_end(void)
/*======================*/
- /* out: 0 or error number */
{
return(index_end());
}
-/*********************************************************************
+/*****************************************************************//**
Reads the next row in a table scan (also used to read the FIRST row
-in a table scan). */
+in a table scan).
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::rnd_next(
/*==================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error number */
- uchar* buf) /* in/out: returns the row in this buffer,
+ uchar* buf) /*!< in/out: returns the row in this buffer,
in MySQL format */
{
int error;
@@ -5663,15 +5831,15 @@ ha_innobase::rnd_next(
DBUG_RETURN(error);
}
-/**************************************************************************
-Fetches a row from the table based on a row reference. */
+/**********************************************************************//**
+Fetches a row from the table based on a row reference.
+@return 0, HA_ERR_KEY_NOT_FOUND, or error code */
UNIV_INTERN
int
ha_innobase::rnd_pos(
/*=================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND, or error code */
- uchar* buf, /* in/out: buffer for the row */
- uchar* pos) /* in: primary key value of the row in the
+ uchar* buf, /*!< in/out: buffer for the row */
+ uchar* pos) /*!< in: primary key value of the row in the
MySQL format, or the row id if the clustered
index was internally generated by InnoDB; the
length of data in pos has to be ref_length */
@@ -5715,7 +5883,7 @@ ha_innobase::rnd_pos(
DBUG_RETURN(error);
}
-/*************************************************************************
+/*********************************************************************//**
Stores a reference to the current row to 'ref' field of the handle. Note
that in the case where we have generated the clustered index for the
table, the function parameter is illogical: we MUST ASSUME that 'record'
@@ -5727,7 +5895,7 @@ UNIV_INTERN
void
ha_innobase::position(
/*==================*/
- const uchar* record) /* in: row in MySQL format */
+ const uchar* record) /*!< in: row in MySQL format */
{
uint len;
@@ -5762,17 +5930,17 @@ See http://bugs.mysql.com/32710 for expl. why we choose PROCESS. */
(row_is_magic_monitor_table(table_name) \
&& check_global_access(thd, PROCESS_ACL))
-/*********************************************************************
+/*****************************************************************//**
Creates a table definition to an InnoDB database. */
static
int
create_table_def(
/*=============*/
- trx_t* trx, /* in: InnoDB transaction handle */
- TABLE* form, /* in: information on table
+ trx_t* trx, /*!< in: InnoDB transaction handle */
+ TABLE* form, /*!< in: information on table
columns and indexes */
- const char* table_name, /* in: table name */
- const char* path_of_temp_table,/* in: if this is a table explicitly
+ const char* table_name, /*!< in: table name */
+ const char* path_of_temp_table,/*!< in: if this is a table explicitly
created by the user with the
TEMPORARY keyword, then this
parameter is the dir path where the
@@ -5780,7 +5948,7 @@ create_table_def(
an .ibd file for it (no .ibd extension
in the path, though); otherwise this
is NULL */
- ulint flags) /* in: table flags */
+ ulint flags) /*!< in: table flags */
{
Field* field;
dict_table_t* table;
@@ -5846,7 +6014,7 @@ create_table_def(
number fits in one byte in prtype */
push_warning_printf(
(THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CANT_CREATE_TABLE,
"In InnoDB, charset-collation codes"
" must be below 256."
@@ -5875,6 +6043,19 @@ create_table_def(
}
}
+ /* First check whether the column to be added has a
+ system reserved name. */
+ if (dict_col_name_is_reserved(field->field_name)){
+ my_error(ER_WRONG_COLUMN_NAME, MYF(0),
+ field->field_name);
+
+ dict_mem_table_free(table);
+ trx_commit_for_mysql(trx);
+
+ error = DB_ERROR;
+ goto error_ret;
+ }
+
dict_mem_table_add_col(table, table->heap,
(char*) field->field_name,
col_type,
@@ -5888,23 +6069,32 @@ create_table_def(
error = row_create_table_for_mysql(table, trx);
+ if (error == DB_DUPLICATE_KEY) {
+ char buf[100];
+ innobase_convert_identifier(buf, sizeof buf,
+ table_name, strlen(table_name),
+ trx->mysql_thd, TRUE);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
+ }
+
+error_ret:
error = convert_error_code_to_mysql(error, flags, NULL);
DBUG_RETURN(error);
}
-/*********************************************************************
+/*****************************************************************//**
Creates an index in an InnoDB database. */
static
int
create_index(
/*=========*/
- trx_t* trx, /* in: InnoDB transaction handle */
- TABLE* form, /* in: information on table
+ trx_t* trx, /*!< in: InnoDB transaction handle */
+ TABLE* form, /*!< in: information on table
columns and indexes */
- ulint flags, /* in: InnoDB table flags */
- const char* table_name, /* in: table name */
- uint key_num) /* in: index number */
+ ulint flags, /*!< in: InnoDB table flags */
+ const char* table_name, /*!< in: table name */
+ uint key_num) /*!< in: index number */
{
Field* field;
dict_index_t* index;
@@ -5926,6 +6116,9 @@ create_index(
n_fields = key->key_parts;
+ /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
+ ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
+
ind_type = 0;
if (key_num == form->s->primary_key) {
@@ -6018,24 +6211,24 @@ create_index(
DBUG_RETURN(error);
}
-/*********************************************************************
+/*****************************************************************//**
Creates an index to an InnoDB table when the user has defined no
primary index. */
static
int
create_clustered_index_when_no_primary(
/*===================================*/
- trx_t* trx, /* in: InnoDB transaction handle */
- ulint flags, /* in: InnoDB table flags */
- const char* table_name) /* in: table name */
+ trx_t* trx, /*!< in: InnoDB transaction handle */
+ ulint flags, /*!< in: InnoDB table flags */
+ const char* table_name) /*!< in: table name */
{
dict_index_t* index;
int error;
/* We pass 0 as the space id, and determine at a lower level the space
id where to store the table */
-
- index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
+ index = dict_mem_index_create(table_name,
+ innobase_index_reserve_name,
0, DICT_CLUSTERED, 0);
error = row_create_index_for_mysql(index, trx, NULL);
@@ -6045,20 +6238,20 @@ create_clustered_index_when_no_primary(
return(error);
}
-/*********************************************************************
+/*****************************************************************//**
Validates the create options. We may build on this function
in future. For now, it checks two specifiers:
KEY_BLOCK_SIZE and ROW_FORMAT
-If innodb_strict_mode is not set then this function is a no-op */
+If innodb_strict_mode is not set then this function is a no-op
+@return TRUE if valid. */
static
ibool
create_options_are_valid(
/*=====================*/
- /* out: TRUE if valid. */
- THD* thd, /* in: connection thread. */
- TABLE* form, /* in: information on table
+ THD* thd, /*!< in: connection thread. */
+ TABLE* form, /*!< in: information on table
columns and indexes */
- HA_CREATE_INFO* create_info) /* in: create info. */
+ HA_CREATE_INFO* create_info) /*!< in: create info. */
{
ibool kbs_specified = FALSE;
ibool ret = TRUE;
@@ -6088,7 +6281,7 @@ create_options_are_valid(
/* Valid value. */
break;
default:
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid"
" KEY_BLOCK_SIZE = %lu."
@@ -6102,7 +6295,7 @@ create_options_are_valid(
/* If KEY_BLOCK_SIZE was specified, check for its
dependencies. */
if (kbs_specified && !srv_file_per_table) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_per_table.");
@@ -6110,7 +6303,7 @@ create_options_are_valid(
}
if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_format >"
@@ -6134,7 +6327,7 @@ create_options_are_valid(
if (!srv_file_per_table) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_per_table.",
@@ -6146,7 +6339,7 @@ create_options_are_valid(
if (srv_file_format < DICT_TF_FORMAT_ZIP) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_format >"
@@ -6163,7 +6356,7 @@ create_options_are_valid(
&& form->s->row_type == ROW_TYPE_DYNAMIC) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify"
" ROW_FORMAT = DYNAMIC with"
@@ -6187,7 +6380,7 @@ create_options_are_valid(
if (kbs_specified) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify"
" ROW_FORMAT = %s with"
@@ -6200,7 +6393,7 @@ create_options_are_valid(
default:
push_warning(thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid ROW_FORMAT specifier.");
ret = FALSE;
@@ -6211,13 +6404,13 @@ create_options_are_valid(
return(ret);
}
-/*********************************************************************
+/*****************************************************************//**
Update create_info. Used in SHOW CREATE TABLE et al. */
UNIV_INTERN
void
ha_innobase::update_create_info(
/*============================*/
- HA_CREATE_INFO* create_info) /* in/out: create info */
+ HA_CREATE_INFO* create_info) /*!< in/out: create info */
{
if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) {
ha_innobase::info(HA_STATUS_AUTO);
@@ -6225,17 +6418,17 @@ ha_innobase::update_create_info(
}
}
-/*********************************************************************
-Creates a new table to an InnoDB database. */
+/*****************************************************************//**
+Creates a new table to an InnoDB database.
+@return error number */
UNIV_INTERN
int
ha_innobase::create(
/*================*/
- /* out: error number */
- const char* name, /* in: table name */
- TABLE* form, /* in: information on table
+ const char* name, /*!< in: table name */
+ TABLE* form, /*!< in: information on table
columns and indexes */
- HA_CREATE_INFO* create_info) /* in: more information of the
+ HA_CREATE_INFO* create_info) /*!< in: more information of the
created table, contains also the
create statement string */
{
@@ -6264,13 +6457,15 @@ ha_innobase::create(
1. <database_name>/<table_name>: for normal table creation
2. full path: for temp table creation, or sym link
- When srv_file_per_table is on, check for full path pattern, i.e.
+ When srv_file_per_table is on and mysqld_embedded is off,
+ check for full path pattern, i.e.
X:\dir\..., X is a driver letter, or
\\dir1\dir2\..., UNC path
returns error if it is in full path format, but not creating a temp.
table. Currently InnoDB does not support symbolic link on Windows. */
if (srv_file_per_table
+ && !mysqld_embedded
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
if ((name[1] == ':')
@@ -6461,14 +6656,6 @@ ha_innobase::create(
flags = DICT_TF_COMPACT;
}
- error = create_table_def(trx, form, norm_name,
- create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
- flags);
-
- if (error) {
- goto cleanup;
- }
-
/* Look for a primary key */
primary_key_no= (form->s->primary_key != MAX_KEY ?
@@ -6478,7 +6665,24 @@ ha_innobase::create(
/* Our function row_get_mysql_key_number_for_index assumes
the primary key is always number 0, if it exists */
- DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
+ ut_a(primary_key_no == -1 || primary_key_no == 0);
+
+ /* Check for name conflicts (with reserved name) for
+ any user indices to be created. */
+ if (innobase_index_name_is_reserved(trx, form->key_info,
+ form->s->keys)) {
+ error = -1;
+ goto cleanup;
+ }
+
+ error = create_table_def(trx, form, norm_name,
+ create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
+ flags);
+
+ if (error) {
+ goto cleanup;
+ }
+
/* Create the keys */
@@ -6553,18 +6757,22 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE. */
+ this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
- || thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
- && create_info->auto_increment_value != 0) {
-
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
- definition from the dictionary and get the current value
- of the auto increment field. Set a new value to the
- auto increment field if the value is greater than the
- maximum value in the column. */
+ || thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
+ && create_info->auto_increment_value > 0) {
+
+ /* Query was one of :
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ CREATE INDEX x on t(...);
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
auto_inc_value = create_info->auto_increment_value;
@@ -6592,14 +6800,14 @@ cleanup:
DBUG_RETURN(error);
}
-/*********************************************************************
-Discards or imports an InnoDB tablespace. */
+/*****************************************************************//**
+Discards or imports an InnoDB tablespace.
+@return 0 == success, -1 == error */
UNIV_INTERN
int
ha_innobase::discard_or_import_tablespace(
/*======================================*/
- /* out: 0 == success, -1 == error */
- my_bool discard) /* in: TRUE if discard, else import */
+ my_bool discard) /*!< in: TRUE if discard, else import */
{
dict_table_t* dict_table;
trx_t* trx;
@@ -6625,13 +6833,13 @@ ha_innobase::discard_or_import_tablespace(
DBUG_RETURN(err);
}
-/*********************************************************************
-Deletes all rows of an InnoDB table. */
+/*****************************************************************//**
+Deletes all rows of an InnoDB table.
+@return error number */
UNIV_INTERN
int
ha_innobase::delete_all_rows(void)
/*==============================*/
- /* out: error number */
{
int error;
@@ -6664,18 +6872,18 @@ ha_innobase::delete_all_rows(void)
DBUG_RETURN(error);
}
-/*********************************************************************
+/*****************************************************************//**
Drops a table from an InnoDB database. Before calling this function,
MySQL calls innobase_commit to commit the transaction of the current user.
Then the current user cannot have locks set on the table. Drop table
operation inside InnoDB will remove all locks any user has on the table
-inside InnoDB. */
+inside InnoDB.
+@return error number */
UNIV_INTERN
int
ha_innobase::delete_table(
/*======================*/
- /* out: error number */
- const char* name) /* in: table name */
+ const char* name) /*!< in: table name */
{
ulint name_len;
int error;
@@ -6742,15 +6950,14 @@ ha_innobase::delete_table(
DBUG_RETURN(error);
}
-/*********************************************************************
+/*****************************************************************//**
Removes all tables in the named database inside InnoDB. */
static
void
innobase_drop_database(
/*===================*/
- /* out: error number */
- handlerton *hton, /* in: handlerton of Innodb */
- char* path) /* in: database path; inside InnoDB the name
+ handlerton *hton, /*!< in: handlerton of Innodb */
+ char* path) /*!< in: database path; inside InnoDB the name
of the last directory in the path is used as
the database name: for example, in 'mysql/data/test'
the database name is 'test' */
@@ -6819,18 +7026,18 @@ innobase_drop_database(
innobase_commit_low(trx);
trx_free_for_mysql(trx);
}
-/*************************************************************************
-Renames an InnoDB table. */
+/*********************************************************************//**
+Renames an InnoDB table.
+@return 0 or error code */
static
int
innobase_rename_table(
/*==================*/
- /* out: 0 or error code */
- trx_t* trx, /* in: transaction */
- const char* from, /* in: old name of the table */
- const char* to, /* in: new name of the table */
+ trx_t* trx, /*!< in: transaction */
+ const char* from, /*!< in: old name of the table */
+ const char* to, /*!< in: new name of the table */
ibool lock_and_commit)
- /* in: TRUE=lock data dictionary and commit */
+ /*!< in: TRUE=lock data dictionary and commit */
{
int error;
char* norm_to;
@@ -6886,15 +7093,15 @@ innobase_rename_table(
DBUG_RETURN(error);
}
-/*************************************************************************
-Renames an InnoDB table. */
+/*********************************************************************//**
+Renames an InnoDB table.
+@return 0 or error code */
UNIV_INTERN
int
ha_innobase::rename_table(
/*======================*/
- /* out: 0 or error code */
- const char* from, /* in: old name of the table */
- const char* to) /* in: new name of the table */
+ const char* from, /*!< in: old name of the table */
+ const char* to) /*!< in: new name of the table */
{
trx_t* trx;
int error;
@@ -6925,23 +7132,40 @@ ha_innobase::rename_table(
innobase_commit_low(trx);
trx_free_for_mysql(trx);
+ /* Add a special case to handle the Duplicated Key error
+ and return DB_ERROR instead.
+ This is to avoid a possible SIGSEGV error from mysql error
+ handling code. Currently, mysql handles the Duplicated Key
+ error by re-entering the storage layer and getting dup key
+ info by calling get_dup_key(). This operation requires a valid
+ table handle ('row_prebuilt_t' structure) which could no
+ longer be available in the error handling stage. The suggested
+ solution is to report a 'table exists' error message (since
+ the dup key error here is due to an existing table whose name
+ is the one we are trying to rename to) and return the generic
+ error code. */
+ if (error == (int) DB_DUPLICATE_KEY) {
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
+
+ error = DB_ERROR;
+ }
+
error = convert_error_code_to_mysql(error, 0, NULL);
DBUG_RETURN(error);
}
-/*************************************************************************
-Estimates the number of index records in a range. */
+/*********************************************************************//**
+Estimates the number of index records in a range.
+@return estimated number of rows */
UNIV_INTERN
ha_rows
ha_innobase::records_in_range(
/*==========================*/
- /* out: estimated number of
- rows */
- uint keynr, /* in: index number */
- key_range *min_key, /* in: start key value of the
+ uint keynr, /*!< in: index number */
+ key_range *min_key, /*!< in: start key value of the
range, may also be 0 */
- key_range *max_key) /* in: range end key val, may
+ key_range *max_key) /*!< in: range end key val, may
also be 0 */
{
KEY* key;
@@ -7039,14 +7263,14 @@ ha_innobase::records_in_range(
DBUG_RETURN((ha_rows) n_rows);
}
-/*************************************************************************
+/*********************************************************************//**
Gives an UPPER BOUND to the number of rows in a table. This is used in
-filesort.cc. */
+filesort.cc.
+@return upper bound of rows */
UNIV_INTERN
ha_rows
ha_innobase::estimate_rows_upper_bound(void)
/*======================================*/
- /* out: upper bound of rows */
{
dict_index_t* index;
ulonglong estimate;
@@ -7089,15 +7313,15 @@ ha_innobase::estimate_rows_upper_bound(void)
DBUG_RETURN((ha_rows) estimate);
}
-/*************************************************************************
+/*********************************************************************//**
How many seeks it will take to read through the table. This is to be
comparable to the number returned by records_in_range so that we can
-decide if we should scan the table or use keys. */
+decide if we should scan the table or use keys.
+@return estimated time measured in disk seeks */
UNIV_INTERN
double
ha_innobase::scan_time()
/*====================*/
- /* out: estimated time measured in disk seeks */
{
/* Since MySQL seems to favor table scans too much over index
searches, we pretend that a sequential read takes the same time
@@ -7107,17 +7331,17 @@ ha_innobase::scan_time()
return((double) (prebuilt->table->stat_clustered_index_size));
}
-/**********************************************************************
+/******************************************************************//**
Calculate the time it takes to read a set of ranges through an index
-This enables us to optimise reads for clustered indexes. */
+This enables us to optimise reads for clustered indexes.
+@return estimated time measured in disk seeks */
UNIV_INTERN
double
ha_innobase::read_time(
/*===================*/
- /* out: estimated time measured in disk seeks */
- uint index, /* in: key number */
- uint ranges, /* in: how many ranges */
- ha_rows rows) /* in: estimated number of rows in the ranges */
+ uint index, /*!< in: key number */
+ uint ranges, /*!< in: how many ranges */
+ ha_rows rows) /*!< in: estimated number of rows in the ranges */
{
ha_rows total_rows;
double time_for_scan;
@@ -7145,14 +7369,14 @@ ha_innobase::read_time(
return(ranges + (double) rows / (double) total_rows * time_for_scan);
}
-/*************************************************************************
+/*********************************************************************//**
Returns statistics information of the table to the MySQL interpreter,
in various fields of the handle object. */
UNIV_INTERN
int
ha_innobase::info(
/*==============*/
- uint flag) /* in: what information MySQL requests */
+ uint flag) /*!< in: what information MySQL requests */
{
dict_table_t* ib_table;
dict_index_t* index;
@@ -7217,7 +7441,7 @@ ha_innobase::info(
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
if (os_file_get_status(path,&stat_info)) {
- stats.create_time = stat_info.ctime;
+ stats.create_time = (ulong) stat_info.ctime;
}
}
@@ -7279,7 +7503,7 @@ ha_innobase::info(
We do not update delete_length if no locking is requested
so the "old" value can remain. delete_length is initialized
to 0 in the ha_statistics' constructor. */
- if (!(flag & HA_STATUS_NO_LOCK)) {
+ if (!(flag & HA_STATUS_NO_LOCK) && srv_stats_update_need_lock) {
/* lock the data dictionary to avoid races with
ibd_file_missing and tablespace_discarded */
@@ -7339,8 +7563,8 @@ ha_innobase::info(
".frm file. Have you mixed up "
".frm files from different "
"installations? See "
-"http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n",
-
+ REFMAN
+ "innodb-troubleshooting.html\n",
ib_table->name);
break;
}
@@ -7352,7 +7576,7 @@ ha_innobase::info(
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
"statistics for %lu columns. Have you mixed up .frm files from different "
"installations? "
-"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n",
+"See " REFMAN "innodb-troubleshooting.html\n",
index->name,
ib_table->name,
(unsigned long)
@@ -7413,48 +7637,53 @@ ha_innobase::info(
DBUG_RETURN(0);
}
-/**************************************************************************
+/**********************************************************************//**
Updates index cardinalities of the table, based on 8 random dives into
-each index tree. This does NOT calculate exact statistics on the table. */
+each index tree. This does NOT calculate exact statistics on the table.
+@return returns always 0 (success) */
UNIV_INTERN
int
ha_innobase::analyze(
/*=================*/
- /* out: returns always 0 (success) */
- THD* thd, /* in: connection thread handle */
- HA_CHECK_OPT* check_opt) /* in: currently ignored */
+ THD* thd, /*!< in: connection thread handle */
+ HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
+ /* Serialize ANALYZE TABLE inside InnoDB, see
+ Bug#38996 Race condition in ANALYZE TABLE */
+ pthread_mutex_lock(&analyze_mutex);
+
/* Simply call ::info() with all the flags */
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ pthread_mutex_unlock(&analyze_mutex);
+
return(0);
}
-/**************************************************************************
+/**********************************************************************//**
This is mapped to "ALTER TABLE tablename ENGINE=InnoDB", which rebuilds
the table in MySQL. */
UNIV_INTERN
int
ha_innobase::optimize(
/*==================*/
- THD* thd, /* in: connection thread handle */
- HA_CHECK_OPT* check_opt) /* in: currently ignored */
+ THD* thd, /*!< in: connection thread handle */
+ HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
return(HA_ADMIN_TRY_ALTER);
}
-/***********************************************************************
+/*******************************************************************//**
Tries to check that an InnoDB table is not corrupted. If corruption is
noticed, prints to stderr information about it. In case of corruption
-may also assert a failure and crash the server. */
+may also assert a failure and crash the server.
+@return HA_ADMIN_CORRUPT or HA_ADMIN_OK */
UNIV_INTERN
int
ha_innobase::check(
/*===============*/
- /* out: HA_ADMIN_CORRUPT or
- HA_ADMIN_OK */
- THD* thd, /* in: user thread handle */
- HA_CHECK_OPT* check_opt) /* in: check options, currently
+ THD* thd, /*!< in: user thread handle */
+ HA_CHECK_OPT* check_opt) /*!< in: check options, currently
ignored */
{
ulint ret;
@@ -7473,24 +7702,27 @@ ha_innobase::check(
ret = row_check_table_for_mysql(prebuilt);
- if (ret == DB_SUCCESS) {
+ switch (ret) {
+ case DB_SUCCESS:
return(HA_ADMIN_OK);
+ case DB_INTERRUPTED:
+ my_error(ER_QUERY_INTERRUPTED, MYF(0));
+ return(-1);
+ default:
+ return(HA_ADMIN_CORRUPT);
}
-
- return(HA_ADMIN_CORRUPT);
}
-/*****************************************************************
+/*************************************************************//**
Adds information about free space in the InnoDB tablespace to a table comment
which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
-foreign keys. */
+foreign keys.
+@return table comment + InnoDB free space + info on foreign keys */
UNIV_INTERN
char*
ha_innobase::update_table_comment(
/*==============================*/
- /* out: table comment + InnoDB free space +
- info on foreign keys */
- const char* comment)/* in: table comment defined by user */
+ const char* comment)/*!< in: table comment defined by user */
{
uint length = (uint) strlen(comment);
char* str;
@@ -7556,15 +7788,15 @@ ha_innobase::update_table_comment(
return(str ? str : (char*) comment);
}
-/***********************************************************************
-Gets the foreign key create info for a table stored in InnoDB. */
+/*******************************************************************//**
+Gets the foreign key create info for a table stored in InnoDB.
+@return own: character string in the form which can be inserted to the
+CREATE TABLE statement, MUST be freed with
+ha_innobase::free_foreign_key_create_info */
UNIV_INTERN
char*
ha_innobase::get_foreign_key_create_info(void)
/*==========================================*/
- /* out, own: character string in the form which
- can be inserted to the CREATE TABLE statement,
- MUST be freed with ::free_foreign_key_create_info */
{
char* str = 0;
long flen;
@@ -7749,10 +7981,11 @@ ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
DBUG_RETURN(0);
}
-/*********************************************************************
+/*****************************************************************//**
Checks if ALTER TABLE may change the storage engine of the table.
Changing storage engines is not allowed for tables for which there
-are foreign key constraints (parent or child tables). */
+are foreign key constraints (parent or child tables).
+@return TRUE if can switch engines */
UNIV_INTERN
bool
ha_innobase::can_switch_engines(void)
@@ -7777,16 +8010,16 @@ ha_innobase::can_switch_engines(void)
DBUG_RETURN(can_switch);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if a table is referenced by a foreign key. The MySQL manual states that
a REPLACE is either equivalent to an INSERT, or DELETE(s) + INSERT. Only a
delete is then allowed internally to resolve a duplicate key conflict in
-REPLACE, not an update. */
+REPLACE, not an update.
+@return > 0 if referenced by a FOREIGN KEY */
UNIV_INTERN
uint
ha_innobase::referenced_by_foreign_key(void)
/*========================================*/
- /* out: > 0 if referenced by a FOREIGN KEY */
{
if (dict_table_is_referenced_by_foreign_key(prebuilt->table)) {
@@ -7796,29 +8029,29 @@ ha_innobase::referenced_by_foreign_key(void)
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Frees the foreign key create info for a table stored in InnoDB, if it is
non-NULL. */
UNIV_INTERN
void
ha_innobase::free_foreign_key_create_info(
/*======================================*/
- char* str) /* in, own: create info string to free */
+ char* str) /*!< in, own: create info string to free */
{
if (str) {
my_free(str, MYF(0));
}
}
-/***********************************************************************
-Tells something additional to the handler about how to do things. */
+/*******************************************************************//**
+Tells something additional to the handler about how to do things.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::extra(
/*===============*/
- /* out: 0 or error number */
enum ha_extra_function operation)
- /* in: HA_EXTRA_FLUSH or some other flag */
+ /*!< in: HA_EXTRA_FLUSH or some other flag */
{
/* Warning: since it is not sure that MySQL calls external_lock
before calling this function, the trx field in prebuilt can be
@@ -7898,7 +8131,7 @@ ha_innobase::reset()
return(0);
}
-/**********************************************************************
+/******************************************************************//**
MySQL calls this function at the start of each SQL statement inside LOCK
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
mark SQL statement borders. Note also a special case: if a temporary table
@@ -7908,13 +8141,13 @@ MySQL-5.0 also calls this before each statement in an execution of a stored
procedure. To make the execution more deterministic for binlogging, MySQL-5.0
locks all tables involved in a stored procedure with full explicit table
locks (thd_in_lock_tables(thd) holds in store_lock()) before executing the
-procedure. */
+procedure.
+@return 0 or error code */
UNIV_INTERN
int
ha_innobase::start_stmt(
/*====================*/
- /* out: 0 or error code */
- THD* thd, /* in: handle to the user thread */
+ THD* thd, /*!< in: handle to the user thread */
thr_lock_type lock_type)
{
trx_t* trx;
@@ -7983,14 +8216,14 @@ ha_innobase::start_stmt(
return(0);
}
-/**********************************************************************
-Maps a MySQL trx isolation level code to the InnoDB isolation level code */
+/******************************************************************//**
+Maps a MySQL trx isolation level code to the InnoDB isolation level code
+@return InnoDB isolation level */
static inline
ulint
innobase_map_isolation_level(
/*=========================*/
- /* out: InnoDB isolation level */
- enum_tx_isolation iso) /* in: MySQL isolation level code */
+ enum_tx_isolation iso) /*!< in: MySQL isolation level code */
{
switch(iso) {
case ISO_REPEATABLE_READ: return(TRX_ISO_REPEATABLE_READ);
@@ -8001,21 +8234,21 @@ innobase_map_isolation_level(
}
}
-/**********************************************************************
+/******************************************************************//**
As MySQL will execute an external lock for every new table it uses when it
starts to process an SQL statement (an exception is when MySQL calls
start_stmt for the handle) we can use this function to store the pointer to
the THD in the handle. We will also use this function to communicate
to InnoDB that a new SQL statement has started and that we must store a
savepoint to our transaction handle, so that we are able to roll back
-the SQL statement in case of an error. */
+the SQL statement in case of an error.
+@return 0 */
UNIV_INTERN
int
ha_innobase::external_lock(
/*=======================*/
- /* out: 0 */
- THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
+ THD* thd, /*!< in: handle to the user thread */
+ int lock_type) /*!< in: lock type */
{
trx_t* trx;
@@ -8032,8 +8265,12 @@ ha_innobase::external_lock(
{
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(ha_thd());
- if (tx_isolation <= ISO_READ_COMMITTED &&
- binlog_format == BINLOG_FORMAT_STMT)
+ if (tx_isolation <= ISO_READ_COMMITTED
+ && binlog_format == BINLOG_FORMAT_STMT
+#if MYSQL_VERSION_ID > 50140
+ && thd_binlog_filter_ok(thd)
+#endif /* MYSQL_VERSION_ID > 50140 */
+ )
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -8146,6 +8383,23 @@ ha_innobase::external_lock(
statement has ended */
if (trx->n_mysql_tables_in_use == 0) {
+#ifdef EXTENDED_SLOWLOG
+ increment_thd_innodb_stats(thd, trx->io_reads,
+ trx->io_read,
+ trx->io_reads_wait_timer,
+ trx->lock_que_wait_timer,
+ trx->innodb_que_wait_timer,
+ trx->distinct_page_access);
+
+ trx->io_reads = 0;
+ trx->io_read = 0;
+ trx->io_reads_wait_timer = 0;
+ trx->lock_que_wait_timer = 0;
+ trx->innodb_que_wait_timer = 0;
+ trx->distinct_page_access = 0;
+ if (trx->distinct_page_access_hash)
+ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
+#endif
trx->mysql_n_tables_locked = 0;
prebuilt->used_in_HANDLER = FALSE;
@@ -8169,16 +8423,16 @@ ha_innobase::external_lock(
DBUG_RETURN(0);
}
-/**********************************************************************
+/******************************************************************//**
With this function MySQL request a transactional lock to a table when
-user issued query LOCK TABLES..WHERE ENGINE = InnoDB. */
+user issued query LOCK TABLES..WHERE ENGINE = InnoDB.
+@return error code */
UNIV_INTERN
int
ha_innobase::transactional_table_lock(
/*==================================*/
- /* out: error code */
- THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
+ THD* thd, /*!< in: handle to the user thread */
+ int lock_type) /*!< in: lock type */
{
trx_t* trx;
@@ -8200,8 +8454,8 @@ ha_innobase::transactional_table_lock(
"InnoDB: Have you deleted the .ibd file"
" from the database directory under\n"
"InnoDB: the MySQL datadir?"
- "InnoDB: See"
- " http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
+ "InnoDB: See " REFMAN
+ "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
DBUG_RETURN(HA_ERR_CRASHED);
@@ -8262,29 +8516,27 @@ ha_innobase::transactional_table_lock(
DBUG_RETURN(0);
}
-/****************************************************************************
-Here we export InnoDB status variables to MySQL. */
+/************************************************************************//**
+Here we export InnoDB status variables to MySQL. */
static
-int
-innodb_export_status()
-/*==================*/
+void
+innodb_export_status(void)
+/*======================*/
{
if (innodb_inited) {
srv_export_innodb_status();
}
-
- return(0);
}
-/****************************************************************************
+/************************************************************************//**
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
Monitor to the client. */
static
bool
innodb_show_status(
/*===============*/
- handlerton* hton, /* in: the innodb handlerton */
- THD* thd, /* in: the MySQL query thread of the caller */
+ handlerton* hton, /*!< in: the innodb handlerton */
+ THD* thd, /*!< in: the MySQL query thread of the caller */
stat_print_fn *stat_print)
{
trx_t* trx;
@@ -8365,14 +8617,14 @@ innodb_show_status(
DBUG_RETURN(FALSE);
}
-/****************************************************************************
+/************************************************************************//**
Implements the SHOW MUTEX STATUS command. . */
static
bool
innodb_mutex_show_status(
/*=====================*/
- handlerton* hton, /* in: the innodb handlerton */
- THD* thd, /* in: the MySQL query thread of the
+ handlerton* hton, /*!< in: the innodb handlerton */
+ THD* thd, /*!< in: the MySQL query thread of the
caller */
stat_print_fn* stat_print)
{
@@ -8396,6 +8648,10 @@ innodb_mutex_show_status(
mutex = UT_LIST_GET_FIRST(mutex_list);
while (mutex != NULL) {
+ if (mutex->count_os_wait == 0
+ || buf_pool_is_block_mutex(mutex)) {
+ goto next_mutex;
+ }
#ifdef UNIV_DEBUG
if (mutex->mutex_type != 1) {
if (mutex->count_using > 0) {
@@ -8431,8 +8687,8 @@ innodb_mutex_show_status(
rw_lock_wait_time += mutex->lspent_time;
}
#else /* UNIV_DEBUG */
- buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu",
- mutex->cfile_name, (ulong) mutex->cline);
+ buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s",
+ mutex->cmutex_name);
buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
mutex->count_os_wait);
@@ -8444,6 +8700,7 @@ innodb_mutex_show_status(
}
#endif /* UNIV_DEBUG */
+next_mutex:
mutex = UT_LIST_GET_NEXT(list, mutex);
}
@@ -8454,9 +8711,10 @@ innodb_mutex_show_status(
lock = UT_LIST_GET_FIRST(rw_lock_list);
while (lock != NULL) {
- if (lock->count_os_wait) {
- buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%lu",
- lock->cfile_name, (ulong) lock->cline);
+ if (lock->count_os_wait
+ && !buf_pool_is_block_lock(lock)) {
+ buf1len= my_snprintf(buf1, sizeof(buf1), "%s",
+ lock->lock_name);
buf2len= my_snprintf(buf2, sizeof(buf2),
"os_waits=%lu", lock->count_os_wait);
@@ -8507,7 +8765,7 @@ bool innobase_show_status(handlerton *hton, THD* thd,
}
}
-/****************************************************************************
+/************************************************************************//**
Handling the shared INNOBASE_SHARE structure that is needed to provide table
locking.
****************************************************************************/
@@ -8541,7 +8799,6 @@ static INNOBASE_SHARE* get_share(const char* table_name)
innobase_open_tables, fold, share);
thr_lock_init(&share->lock);
- pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
}
share->use_count++;
@@ -8572,7 +8829,6 @@ static void free_share(INNOBASE_SHARE* share)
HASH_DELETE(INNOBASE_SHARE, table_name_hash,
innobase_open_tables, fold, share);
thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
my_free(share, MYF(0));
/* TODO: invoke HASH_MIGRATE if innobase_open_tables
@@ -8582,27 +8838,26 @@ static void free_share(INNOBASE_SHARE* share)
pthread_mutex_unlock(&innobase_share_mutex);
}
-/*********************************************************************
+/*****************************************************************//**
Converts a MySQL table lock stored in the 'lock' field of the handle to
a proper type before storing pointer to the lock into an array of pointers.
MySQL also calls this if it wants to reset some table locks to a not-locked
state during the processing of an SQL query. An example is that during a
SELECT the read lock is released early on the 'const' tables where we only
fetch one row. MySQL does not call this when it releases all locks at the
-end of an SQL statement. */
+end of an SQL statement.
+@return pointer to the next element in the 'to' array */
UNIV_INTERN
THR_LOCK_DATA**
ha_innobase::store_lock(
/*====================*/
- /* out: pointer to the next
- element in the 'to' array */
- THD* thd, /* in: user thread handle */
- THR_LOCK_DATA** to, /* in: pointer to an array
+ THD* thd, /*!< in: user thread handle */
+ THR_LOCK_DATA** to, /*!< in: pointer to an array
of pointers to lock structs;
pointer to the 'lock' field
of current handle is stored
next to this array */
- enum thr_lock_type lock_type) /* in: lock type to store in
+ enum thr_lock_type lock_type) /*!< in: lock type to store in
'lock'; this may also be
TL_IGNORE */
{
@@ -8680,6 +8935,7 @@ ha_innobase::store_lock(
&& isolation_level != TRX_ISO_SERIALIZABLE
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
&& (sql_command == SQLCOM_INSERT_SELECT
+ || sql_command == SQLCOM_REPLACE_SELECT
|| sql_command == SQLCOM_UPDATE
|| sql_command == SQLCOM_CREATE_TABLE)) {
@@ -8687,10 +8943,11 @@ ha_innobase::store_lock(
option set or this session is using READ COMMITTED
isolation level and isolation level of the transaction
is not set to serializable and MySQL is doing
- INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
- CREATE ... SELECT... without FOR UPDATE or
- IN SHARE MODE in select, then we use consistent
- read for select. */
+ INSERT INTO...SELECT or REPLACE INTO...SELECT
+ or UPDATE ... = (SELECT ...) or CREATE ...
+ SELECT... without FOR UPDATE or IN SHARE
+ MODE in select, then we use consistent read
+ for select. */
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = LOCK_NONE;
@@ -8785,16 +9042,16 @@ ha_innobase::store_lock(
return(to);
}
-/*******************************************************************************
+/*********************************************************************//**
Read the next autoinc value. Acquire the relevant locks before reading
the AUTOINC value. If SUCCESS then the table AUTOINC mutex will be locked
-on return and all relevant locks acquired. */
+on return and all relevant locks acquired.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
ha_innobase::innobase_get_autoinc(
/*==============================*/
- /* out: DB_SUCCESS or error code */
- ulonglong* value) /* out: autoinc value */
+ ulonglong* value) /*!< out: autoinc value */
{
*value = 0;
@@ -8812,14 +9069,14 @@ ha_innobase::innobase_get_autoinc(
return(prebuilt->autoinc_error);
}
-/***********************************************************************
+/*******************************************************************//**
This function reads the global auto-inc counter. It doesn't use the
-AUTOINC lock even if the lock mode is set to TRADITIONAL. */
+AUTOINC lock even if the lock mode is set to TRADITIONAL.
+@return the autoinc value */
UNIV_INTERN
ulonglong
ha_innobase::innobase_peek_autoinc(void)
/*====================================*/
- /* out: the autoinc value */
{
ulonglong auto_inc;
dict_table_t* innodb_table;
@@ -8836,11 +9093,11 @@ ha_innobase::innobase_peek_autoinc(void)
ut_a(auto_inc > 0);
dict_table_autoinc_unlock(innodb_table);
-
+
return(auto_inc);
}
-
-/*******************************************************************************
+
+/*********************************************************************//**
This function initializes the auto-inc counter if it has not been
initialized yet. This function does not change the value of the auto-inc
counter if it already has been initialized. Returns the value of the
@@ -8851,11 +9108,11 @@ UNIV_INTERN
void
ha_innobase::get_auto_increment(
/*============================*/
- ulonglong offset, /* in: */
- ulonglong increment, /* in: table autoinc increment */
- ulonglong nb_desired_values, /* in: number of values reqd */
- ulonglong *first_value, /* out: the autoinc value */
- ulonglong *nb_reserved_values) /* out: count of reserved values */
+ ulonglong offset, /*!< in: table autoinc offset */
+ ulonglong increment, /*!< in: table autoinc increment */
+ ulonglong nb_desired_values, /*!< in: number of values reqd */
+ ulonglong *first_value, /*!< out: the autoinc value */
+ ulonglong *nb_reserved_values) /*!< out: count of reserved values */
{
trx_t* trx;
ulint error;
@@ -8910,6 +9167,7 @@ ha_innobase::get_auto_increment(
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
+ ulonglong current;
ulonglong next_value;
ulonglong col_max_value;
@@ -8918,11 +9176,12 @@ ha_innobase::get_auto_increment(
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
+ current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- *first_value, need, offset, col_max_value);
+ current, need, offset, col_max_value);
prebuilt->autoinc_last_value = next_value;
@@ -8949,12 +9208,17 @@ ha_innobase::get_auto_increment(
dict_table_autoinc_unlock(prebuilt->table);
}
-/* See comment in handler.h */
+/*******************************************************************//**
+Reset the auto-increment counter to the given value, i.e. the next row
+inserted will get the given value. This is called e.g. after TRUNCATE
+is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
+returned by storage engines that don't support this operation.
+@return 0 or error code */
UNIV_INTERN
int
ha_innobase::reset_auto_increment(
/*==============================*/
- ulonglong value) /* in: new value for table autoinc */
+ ulonglong value) /*!< in: new value for table autoinc */
{
DBUG_ENTER("ha_innobase::reset_auto_increment");
@@ -8995,19 +9259,18 @@ ha_innobase::get_error_message(int error, String *buf)
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Compares two 'refs'. A 'ref' is the (internal) primary key value of the row.
If there is no explicitly declared non-null unique key or a primary key, then
-InnoDB internally uses the row id as the primary key. */
+InnoDB internally uses the row id as the primary key.
+@return < 0 if ref1 < ref2, 0 if equal, else > 0 */
UNIV_INTERN
int
ha_innobase::cmp_ref(
/*=================*/
- /* out: < 0 if ref1 < ref2, 0 if equal, else
- > 0 */
- const uchar* ref1, /* in: an (internal) primary key value in the
+ const uchar* ref1, /*!< in: an (internal) primary key value in the
MySQL key value format */
- const uchar* ref2) /* in: an (internal) primary key value in the
+ const uchar* ref2) /*!< in: an (internal) primary key value in the
MySQL key value format */
{
enum_field_types mysql_type;
@@ -9067,25 +9330,24 @@ ha_innobase::cmp_ref(
return(0);
}
-/***********************************************************************
-Ask InnoDB if a query to a table can be cached. */
+/*******************************************************************//**
+Ask InnoDB if a query to a table can be cached.
+@return TRUE if query caching of the table is permitted */
UNIV_INTERN
my_bool
ha_innobase::register_query_cache_table(
/*====================================*/
- /* out: TRUE if query caching
- of the table is permitted */
- THD* thd, /* in: user thread handle */
- char* table_key, /* in: concatenation of database name,
- the null character '\0',
+ THD* thd, /*!< in: user thread handle */
+ char* table_key, /*!< in: concatenation of database name,
+ the null character NUL,
and the table name */
- uint key_length, /* in: length of the full name, i.e.
+ uint key_length, /*!< in: length of the full name, i.e.
len(dbname) + len(tablename) + 1 */
qc_engine_callback*
- call_back, /* out: pointer to function for
+ call_back, /*!< out: pointer to function for
checking if query caching
is permitted */
- ulonglong *engine_data) /* in/out: data to call_back */
+ ulonglong *engine_data) /*!< in/out: data to call_back */
{
*call_back = innobase_query_caching_of_table_permitted;
*engine_data = 0;
@@ -9111,30 +9373,26 @@ ha_innobase::get_mysql_bin_log_pos()
return(trx_sys_mysql_bin_log_pos);
}
-/**********************************************************************
+/******************************************************************//**
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
finds charset information and returns length of prefix_len characters in the
index field in bytes.
-
-NOTE: the prototype of this function is copied to data0type.c! If you change
-this function, you MUST change also data0type.c! */
+@return number of bytes occupied by the first n characters */
extern "C" UNIV_INTERN
ulint
innobase_get_at_most_n_mbchars(
/*===========================*/
- /* out: number of bytes occupied by the first
- n characters */
- ulint charset_id, /* in: character set id */
- ulint prefix_len, /* in: prefix length in bytes of the index
+ ulint charset_id, /*!< in: character set id */
+ ulint prefix_len, /*!< in: prefix length in bytes of the index
(this has to be divided by mbmaxlen to get the
number of CHARACTERS n in the prefix) */
- ulint data_len, /* in: length of the string in bytes */
- const char* str) /* in: character string */
+ ulint data_len, /*!< in: length of the string in bytes */
+ const char* str) /*!< in: character string */
{
- ulint char_length; /* character length in bytes */
- ulint n_chars; /* number of characters in prefix */
- CHARSET_INFO* charset; /* charset used in the field */
+ ulint char_length; /*!< character length in bytes */
+ ulint n_chars; /*!< number of characters in prefix */
+ CHARSET_INFO* charset; /*!< charset used in the field */
charset = get_charset((uint) charset_id, MYF(MY_WME));
@@ -9185,55 +9443,26 @@ innobase_get_at_most_n_mbchars(
return(char_length);
}
-/***********************************************************************
-This function is used to prepare X/Open XA distributed transaction */
+/*******************************************************************//**
+This function is used to prepare an X/Open XA distributed transaction.
+@return 0 or error number */
static
int
innobase_xa_prepare(
/*================*/
- /* out: 0 or error number */
- handlerton *hton,
- THD* thd, /* in: handle to the MySQL thread of the user
- whose XA transaction should be prepared */
- bool all) /* in: TRUE - commit transaction
- FALSE - the current SQL statement ended */
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread of
+ the user whose XA transaction should
+ be prepared */
+ bool all) /*!< in: TRUE - commit transaction
+ FALSE - the current SQL statement
+ ended */
{
int error = 0;
trx_t* trx = check_trx_exists(thd);
DBUG_ASSERT(hton == innodb_hton_ptr);
- if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
- (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
- {
- if (srv_enable_unsafe_group_commit && !THDVAR(thd, support_xa)) {
- /* choose group commit rather than binlog order */
- return(0);
- }
-
- /* For ibbackup to work the order of transactions in binlog
- and InnoDB must be the same. Consider the situation
-
- thread1> prepare; write to binlog; ...
- <context switch>
- thread2> prepare; write to binlog; commit
- thread1> ... commit
-
- To ensure this will not happen we're taking the mutex on
- prepare, and releasing it on commit.
-
- Note: only do it for normal commits, done via ha_commit_trans.
- If 2pc protocol is executed by external transaction
- coordinator, it will be just a regular MySQL client
- executing XA PREPARE and XA COMMIT commands.
- In this case we cannot know how many minutes or hours
- will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time.
- */
- pthread_mutex_lock(&prepare_commit_mutex);
- trx->active_trans = 2;
- }
-
/* we use support_xa value as it was seen at transaction start
time, not the current session variable value. Any possible changes
to the session variable take effect only in the next transaction */
@@ -9286,20 +9515,49 @@ innobase_xa_prepare(
srv_active_wake_master_thread();
+ if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
+ (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ {
+ if (srv_enable_unsafe_group_commit && !THDVAR(thd, support_xa)) {
+ /* choose group commit rather than binlog order */
+ return(error);
+ }
+
+ /* For ibbackup to work the order of transactions in binlog
+ and InnoDB must be the same. Consider the situation
+
+ thread1> prepare; write to binlog; ...
+ <context switch>
+ thread2> prepare; write to binlog; commit
+ thread1> ... commit
+
+ To ensure this will not happen we're taking the mutex on
+ prepare, and releasing it on commit.
+
+ Note: only do it for normal commits, done via ha_commit_trans.
+ If 2pc protocol is executed by external transaction
+ coordinator, it will be just a regular MySQL client
+ executing XA PREPARE and XA COMMIT commands.
+ In this case we cannot know how many minutes or hours
+ will be between XA PREPARE and XA COMMIT, and we don't want
+ to block for undefined period of time. */
+ pthread_mutex_lock(&prepare_commit_mutex);
+ trx->active_trans = 2;
+ }
+
return(error);
}
-/***********************************************************************
-This function is used to recover X/Open XA distributed transactions */
+/*******************************************************************//**
+This function is used to recover X/Open XA distributed transactions.
+@return number of prepared transactions stored in xid_list */
static
int
innobase_xa_recover(
/*================*/
- /* out: number of prepared transactions
- stored in xid_list */
- handlerton *hton,
- XID* xid_list, /* in/out: prepared transactions */
- uint len) /* in: number of slots in xid_list */
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ XID* xid_list,/*!< in/out: prepared transactions */
+ uint len) /*!< in: number of slots in xid_list */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -9311,16 +9569,16 @@ innobase_xa_recover(
return(trx_recover_for_mysql(xid_list, len));
}
-/***********************************************************************
+/*******************************************************************//**
This function is used to commit one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return 0 or error number */
static
int
innobase_commit_by_xid(
/*===================*/
- /* out: 0 or error number */
handlerton *hton,
- XID* xid) /* in: X/Open XA transaction identification */
+ XID* xid) /*!< in: X/Open XA transaction identification */
{
trx_t* trx;
@@ -9337,16 +9595,17 @@ innobase_commit_by_xid(
}
}
-/***********************************************************************
+/*******************************************************************//**
This function is used to rollback one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return 0 or error number */
static
int
innobase_rollback_by_xid(
/*=====================*/
- /* out: 0 or error number */
- handlerton *hton,
- XID *xid) /* in: X/Open XA transaction identification */
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ XID* xid) /*!< in: X/Open XA transaction
+ identification */
{
trx_t* trx;
@@ -9361,25 +9620,25 @@ innobase_rollback_by_xid(
}
}
-/***********************************************************************
+/*******************************************************************//**
Create a consistent view for a cursor based on current transaction
which is created if the corresponding MySQL thread still lacks one.
This consistent view is then used inside of MySQL when accessing records
-using a cursor. */
+using a cursor.
+@return pointer to cursor view or NULL */
static
void*
innobase_create_cursor_view(
/*========================*/
- /* out: pointer to cursor view or NULL */
- handlerton *hton, /* in: innobase hton */
- THD* thd) /* in: user thread handle */
+ handlerton *hton, /*!< in: innobase hton */
+ THD* thd) /*!< in: user thread handle */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
return(read_cursor_view_create_for_mysql(check_trx_exists(thd)));
}
-/***********************************************************************
+/*******************************************************************//**
Close the given consistent cursor view of a transaction and restore
global read view to a transaction read view. Transaction is created if the
corresponding MySQL thread still lacks one. */
@@ -9388,8 +9647,8 @@ void
innobase_close_cursor_view(
/*=======================*/
handlerton *hton,
- THD* thd, /* in: user thread handle */
- void* curview)/* in: Consistent read view to be closed */
+ THD* thd, /*!< in: user thread handle */
+ void* curview)/*!< in: Consistent read view to be closed */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -9397,7 +9656,7 @@ innobase_close_cursor_view(
(cursor_view_t*) curview);
}
-/***********************************************************************
+/*******************************************************************//**
Set the given consistent cursor view to a transaction which is created
if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is
@@ -9407,8 +9666,8 @@ void
innobase_set_cursor_view(
/*=====================*/
handlerton *hton,
- THD* thd, /* in: user thread handle */
- void* curview)/* in: Consistent cursor view to be set */
+ THD* thd, /*!< in: user thread handle */
+ void* curview)/*!< in: Consistent cursor view to be set */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -9533,6 +9792,20 @@ ha_innobase::check_if_incompatible_data(
DBUG_RETURN(COMPATIBLE_DATA_NO);
}
+ /* Renaming column asynchronizes dictionary between mysqld and InnoDB...
+ If not synchronized, treat as COMPATIBLE_DATA_NO
+ until the bug http://bugs.mysql.com/47621 is fixed officialily */
+ {
+ uint i;
+ for (i = 0; i < table->s->fields; i++) {
+ if (table->field[i]->flags & FIELD_IN_ADD_INDEX
+ && innobase_strcasecmp(table->field[i]->field_name,
+ dict_table_get_col_name(prebuilt->table, i))) {
+ DBUG_RETURN(COMPATIBLE_DATA_NO);
+ }
+ }
+ }
+
/* Check if a column participating in a foreign key is being renamed.
There is no mechanism for updating InnoDB foreign key definitions. */
if (foreign_key_column_is_being_renamed(prebuilt, table)) {
@@ -9567,14 +9840,14 @@ ha_innobase::check_if_incompatible_data(
DBUG_RETURN(COMPATIBLE_DATA_YES);
}
-/****************************************************************
-Validate the file format name and return its corresponding id. */
+/************************************************************//**
+Validate the file format name and return its corresponding id.
+@return valid file format id */
static
uint
innobase_file_format_name_lookup(
/*=============================*/
- /* out: valid file format id*/
- const char* format_name) /* in: pointer to file format name */
+ const char* format_name) /*!< in: pointer to file format name */
{
char* endp;
uint format_id;
@@ -9610,16 +9883,15 @@ innobase_file_format_name_lookup(
return(DICT_TF_FORMAT_MAX + 1);
}
-/****************************************************************
+/************************************************************//**
Validate the file format check value, is it one of "on" or "off",
-as a side effect it sets the srv_check_file_format_at_startup variable. */
+as a side effect it sets the srv_check_file_format_at_startup variable.
+@return true if config value one of "on" or "off" */
static
bool
innobase_file_format_check_on_off(
/*==============================*/
- /* out: true if config value one
- of "on" or "off" */
- const char* format_check) /* in: parameter value */
+ const char* format_check) /*!< in: parameter value */
{
bool ret = true;
@@ -9639,45 +9911,43 @@ innobase_file_format_check_on_off(
return(ret);
}
-/****************************************************************
+/************************************************************//**
Validate the file format check config parameters, as a side effect it
-sets the srv_check_file_format_at_startup variable. */
+sets the srv_check_file_format_at_startup variable.
+@return the format_id if valid config value, otherwise, return -1 */
static
-bool
-innobase_file_format_check_validate(
+int
+innobase_file_format_validate_and_set(
/*================================*/
- /* out: true if valid config value */
- const char* format_check) /* in: parameter value */
+ const char* format_check) /*!< in: parameter value */
{
uint format_id;
- bool ret = true;
format_id = innobase_file_format_name_lookup(format_check);
if (format_id < DICT_TF_FORMAT_MAX + 1) {
srv_check_file_format_at_startup = format_id;
+
+ return((int) format_id);
} else {
- ret = false;
+ return(-1);
}
-
- return(ret);
}
-/*****************************************************************
+/*************************************************************//**
Check if it is a valid file format. This function is registered as
-a callback with MySQL. */
+a callback with MySQL.
+@return 0 for valid file format */
static
int
innodb_file_format_name_validate(
/*=============================*/
- /* out: 0 for valid file
- format */
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to system
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
- void* save, /* out: immediate result
+ void* save, /*!< out: immediate result
for update function */
- struct st_mysql_value* value) /* in: incoming string */
+ struct st_mysql_value* value) /*!< in: incoming string */
{
const char* file_format_input;
char buff[STRING_BUFFER_USUAL_SIZE];
@@ -9696,58 +9966,74 @@ innodb_file_format_name_validate(
if (format_id <= DICT_TF_FORMAT_MAX) {
- *(uint*) save = format_id;
+ /* Save a pointer to the name in the
+ 'file_format_name_map' constant array. */
+ *static_cast<const char**>(save) =
+ trx_sys_file_format_id_to_name(format_id);
+
return(0);
}
}
+ *static_cast<const char**>(save) = NULL;
return(1);
}
-/********************************************************************
+/****************************************************************//**
Update the system variable innodb_file_format using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_file_format_name_update(
/*===========================*/
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
- void* var_ptr, /* out: where the
+ void* var_ptr, /*!< out: where the
formal string goes */
- const void* save) /* in: immediate result
+ const void* save) /*!< in: immediate result
from check function */
{
+ const char* format_name;
+
ut_a(var_ptr != NULL);
ut_a(save != NULL);
- ut_a((*(const uint*) save) <= DICT_TF_FORMAT_MAX);
- srv_file_format = *(const uint*) save;
+ format_name = *static_cast<const char*const*>(save);
- *(const char**) var_ptr
+ if (format_name) {
+ uint format_id;
+
+ format_id = innobase_file_format_name_lookup(format_name);
+
+ if (format_id <= DICT_TF_FORMAT_MAX) {
+ srv_file_format = format_id;
+ }
+ }
+
+ *static_cast<const char**>(var_ptr)
= trx_sys_file_format_id_to_name(srv_file_format);
}
-/*****************************************************************
+/*************************************************************//**
Check if valid argument to innodb_file_format_check. This
-function is registered as a callback with MySQL. */
+function is registered as a callback with MySQL.
+@return 0 for valid file format */
static
int
innodb_file_format_check_validate(
/*==============================*/
- /* out: 0 for valid file
- format */
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to system
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
- void* save, /* out: immediate result
+ void* save, /*!< out: immediate result
for update function */
- struct st_mysql_value* value) /* in: incoming string */
+ struct st_mysql_value* value) /*!< in: incoming string */
{
const char* file_format_input;
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
+ int format_id;
ut_a(save != NULL);
ut_a(value != NULL);
@@ -9760,81 +10046,106 @@ innodb_file_format_check_validate(
message if they did so. */
if (innobase_file_format_check_on_off(file_format_input)) {
- sql_print_warning(
+ push_warning_printf(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
"InnoDB: invalid innodb_file_format_check "
"value; on/off can only be set at startup or "
"in the configuration file");
- } else if (innobase_file_format_check_validate(
- file_format_input)) {
-
- uint format_id;
-
- format_id = innobase_file_format_name_lookup(
- file_format_input);
-
- ut_a(format_id <= DICT_TF_FORMAT_MAX);
+ } else {
+ format_id = innobase_file_format_validate_and_set(
+ file_format_input);
- *(uint*) save = format_id;
+ if (format_id >= 0) {
+ /* Save a pointer to the name in the
+ 'file_format_name_map' constant array. */
+ *static_cast<const char**>(save) =
+ trx_sys_file_format_id_to_name(
+ (uint)format_id);
- return(0);
+ return(0);
- } else {
- sql_print_warning(
- "InnoDB: invalid innodb_file_format_check "
- "value; can be any format up to %s "
- "or its equivalent numeric id",
- trx_sys_file_format_id_to_name(
- DICT_TF_FORMAT_MAX));
+ } else {
+ push_warning_printf(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "InnoDB: invalid innodb_file_format_check "
+ "value; can be any format up to %s "
+ "or its equivalent numeric id",
+ trx_sys_file_format_id_to_name(
+ DICT_TF_FORMAT_MAX));
+ }
}
}
+ *static_cast<const char**>(save) = NULL;
return(1);
}
-/********************************************************************
+/****************************************************************//**
Update the system variable innodb_file_format_check using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_file_format_check_update(
/*============================*/
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
- void* var_ptr, /* out: where the
+ void* var_ptr, /*!< out: where the
formal string goes */
- const void* save) /* in: immediate result
+ const void* save) /*!< in: immediate result
from check function */
{
- uint format_id;
+ const char* format_name_in;
+ const char** format_name_out;
+ uint format_id;
ut_a(save != NULL);
ut_a(var_ptr != NULL);
- format_id = *(const uint*) save;
+ format_name_in = *static_cast<const char*const*>(save);
+
+ if (!format_name_in) {
+
+ return;
+ }
+
+ format_id = innobase_file_format_name_lookup(format_name_in);
+
+ if (format_id > DICT_TF_FORMAT_MAX) {
+ /* DEFAULT is "on", which is invalid at runtime. */
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "Ignoring SET innodb_file_format=%s",
+ format_name_in);
+ return;
+ }
+
+ format_name_out = static_cast<const char**>(var_ptr);
/* Update the max format id in the system tablespace. */
- if (trx_sys_file_format_max_set(format_id, (const char**) var_ptr)) {
+ if (trx_sys_file_format_max_set(format_id, format_name_out)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" [Info] InnoDB: the file format in the system "
- "tablespace is now set to %s.\n", *(char**) var_ptr);
+ "tablespace is now set to %s.\n", *format_name_out);
}
}
-/********************************************************************
+/****************************************************************//**
Update the system variable innodb_adaptive_hash_index using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_adaptive_hash_index_update(
/*==============================*/
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
- void* var_ptr, /* out: where the
+ void* var_ptr, /*!< out: where the
formal string goes */
- const void* save) /* in: immediate result
+ const void* save) /*!< in: immediate result
from check function */
{
if (*(my_bool*) save) {
@@ -9844,21 +10155,39 @@ innodb_adaptive_hash_index_update(
}
}
-/*****************************************************************
+/****************************************************************//**
+Update the system variable innodb_old_blocks_pct using the "saved"
+value. This function is registered as a callback with MySQL. */
+static
+void
+innodb_old_blocks_pct_update(
+/*=========================*/
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
+ system variable */
+ void* var_ptr,/*!< out: where the
+ formal string goes */
+ const void* save) /*!< in: immediate result
+ from check function */
+{
+ innobase_old_blocks_pct = buf_LRU_old_ratio_update(
+ *static_cast<const uint*>(save), TRUE);
+}
+
+/*************************************************************//**
Check if it is a valid value of innodb_change_buffering. This function is
-registered as a callback with MySQL. */
+registered as a callback with MySQL.
+@return 0 for valid innodb_change_buffering */
static
int
innodb_change_buffering_validate(
/*=============================*/
- /* out: 0 for valid
- innodb_change_buffering */
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to system
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
- void* save, /* out: immediate result
+ void* save, /*!< out: immediate result
for update function */
- struct st_mysql_value* value) /* in: incoming string */
+ struct st_mysql_value* value) /*!< in: incoming string */
{
const char* change_buffering_input;
char buff[STRING_BUFFER_USUAL_SIZE];
@@ -9886,19 +10215,19 @@ innodb_change_buffering_validate(
return(1);
}
-/********************************************************************
+/****************************************************************//**
Update the system variable innodb_change_buffering using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_change_buffering_update(
/*===========================*/
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
- void* var_ptr, /* out: where the
+ void* var_ptr, /*!< out: where the
formal string goes */
- const void* save) /* in: immediate result
+ const void* save) /*!< in: immediate result
from check function */
{
ut_a(var_ptr != NULL);
@@ -9918,6 +10247,49 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
return 0;
}
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an warning message to the client, and returns true. */
+extern "C" UNIV_INTERN
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if an index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys) /* in: Number of indexes to
+ be created. */
+{
+ const KEY* key;
+ uint key_num; /* index number */
+
+ for (key_num = 0; key_num < num_of_keys; key_num++) {
+ key = &key_info[key_num];
+
+ if (innobase_strcasecmp(key->name,
+ innobase_index_reserve_name) == 0) {
+ /* Push warning to mysql */
+ push_warning_printf((THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_NAME_FOR_INDEX,
+ "Cannot Create Index with name "
+ "'%s'. The name is reserved "
+ "for the system default primary "
+ "index.",
+ innobase_index_reserve_name);
+
+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
+ innobase_index_reserve_name);
+
+ return(true);
+ }
+ }
+
+ return(false);
+}
+
static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG}
@@ -9948,8 +10320,18 @@ static MYSQL_SYSVAR_BOOL(extra_undoslots, innobase_extra_undoslots,
static MYSQL_SYSVAR_BOOL(fast_recovery, innobase_fast_recovery,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"Enable to use speed hack of recovery avoiding flush list sorting.",
+ NULL, NULL, TRUE);
+
+static MYSQL_SYSVAR_BOOL(recovery_stats, innobase_recovery_stats,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Output statistics of recovery process after it.",
NULL, NULL, FALSE);
+static MYSQL_SYSVAR_ULONG(use_purge_thread, srv_use_purge_thread,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of purge devoted threads. #### over 1 is EXPERIMENTAL ####",
+ NULL, NULL, 1, 0, 64, 0);
+
static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"During InnoDB crash recovery on slave overwrite relay-log.info "
@@ -9962,6 +10344,11 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
"Disable with --skip-innodb-doublewrite.",
NULL, NULL, TRUE);
+static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
+ PLUGIN_VAR_RQCMDARG,
+ "Number of IOPs the server can do. Tunes the background IO rate",
+ NULL, NULL, 200, 100, ~0L, 0);
+
static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
PLUGIN_VAR_OPCMDARG,
"Speeds up the shutdown process of the InnoDB storage engine. Possible "
@@ -9985,12 +10372,15 @@ static MYSQL_SYSVAR_STR(file_format, innobase_file_format_name,
innodb_file_format_name_validate,
innodb_file_format_name_update, "Antelope");
+/* If a new file format is introduced, the file format
+name needs to be updated accordingly. Please refer to
+file_format_name_map[] defined in trx0sys.c for the next
+file format name. */
static MYSQL_SYSVAR_STR(file_format_check, innobase_file_format_check,
PLUGIN_VAR_OPCMDARG,
"The highest file format in the tablespace.",
innodb_file_format_check_validate,
- innodb_file_format_check_update,
- "on");
+ innodb_file_format_check_update, "Barracuda");
static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
PLUGIN_VAR_OPCMDARG,
@@ -9999,7 +10389,7 @@ static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
" or 2 (write at commit, flush once per second).",
NULL, NULL, 1, 0, 2, 0);
-static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
+static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"With which method to flush data.", NULL, NULL, NULL);
@@ -10035,7 +10425,12 @@ static MYSQL_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
PLUGIN_VAR_RQCMDARG,
"Percentage of dirty pages allowed in bufferpool.",
- NULL, NULL, 90, 0, 100, 0);
+ NULL, NULL, 75, 0, 99, 0);
+
+static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
+ PLUGIN_VAR_NOCMDARG,
+ "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
+ NULL, NULL, FALSE);
static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
PLUGIN_VAR_RQCMDARG,
@@ -10087,6 +10482,12 @@ static MYSQL_SYSVAR_ULONG(stats_auto_update, srv_stats_auto_update,
"(except for ANALYZE TABLE command) 0:disable 1:enable",
NULL, NULL, 1, 0, 1, 0);
+static MYSQL_SYSVAR_ULONG(stats_update_need_lock, srv_stats_update_need_lock,
+ PLUGIN_VAR_RQCMDARG,
+ "Enable/Disable InnoDB's update statistics which needs to lock dictionary. "
+ "e.g. Data_free.",
+ NULL, NULL, 1, 0, 1, 0);
+
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
PLUGIN_VAR_OPCMDARG,
"Enable InnoDB adaptive hash index (enabled by default). "
@@ -10102,7 +10503,7 @@ static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
- NULL, NULL, 1*1024*1024L, 512*1024L, LONG_MAX, 1024);
+ NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment,
PLUGIN_VAR_RQCMDARG,
@@ -10112,7 +10513,7 @@ static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment,
static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
- NULL, NULL, 8*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
+ NULL, NULL, 128*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
PLUGIN_VAR_RQCMDARG,
@@ -10125,10 +10526,20 @@ static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
NULL, NULL, 500L, 1L, ~0L, 0);
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
"Number of file I/O threads in InnoDB.",
NULL, NULL, 4, 4, 64, 0);
+static MYSQL_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of background read I/O threads in InnoDB.",
+ NULL, NULL, 4, 1, 64, 0);
+
+static MYSQL_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of background write I/O threads in InnoDB.",
+ NULL, NULL, 4, 1, 64, 0);
+
static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Helps to save your data in case the disk image of the database becomes corrupt.",
@@ -10137,7 +10548,7 @@ static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the buffer which InnoDB uses to write log to the log files on disk.",
- NULL, NULL, 1024*1024L, 256*1024L, LONG_MAX, 1024);
+ NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -10154,6 +10565,18 @@ static MYSQL_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
"Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
NULL, NULL, 1, 1, 10, 0);
+static MYSQL_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
+ PLUGIN_VAR_RQCMDARG,
+ "Percentage of the buffer pool to reserve for 'old' blocks.",
+ NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
+
+static MYSQL_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
+ PLUGIN_VAR_RQCMDARG,
+ "Move blocks to the 'new' end of the buffer pool if the first access"
+ " was at least this many milliseconds ago."
+ " The timeout is disabled if 0 (the default).",
+ NULL, NULL, 0, 0, UINT_MAX32, 0);
+
static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"How many files at the maximum InnoDB keeps open at the same time.",
@@ -10161,8 +10584,13 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
PLUGIN_VAR_RQCMDARG,
- "Count of spin-loop rounds in InnoDB mutexes",
- NULL, NULL, 20L, 0L, ~0L, 0);
+ "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
+ NULL, NULL, 30L, 0L, ~0L, 0);
+
+static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
+ PLUGIN_VAR_OPCMDARG,
+ "Maximum delay between polling for a spin lock (6 by default)",
+ NULL, NULL, 6L, 0L, ~0L, 0);
static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based,
innobase_thread_concurrency_timer_based,
@@ -10213,10 +10641,11 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering,
innodb_change_buffering_validate,
innodb_change_buffering_update, NULL);
-static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
+static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
PLUGIN_VAR_RQCMDARG,
- "Number of IO operations per second the server can do. Tunes background IO rate.",
- NULL, NULL, 200, 100, 999999999, 0);
+ "Number of pages that must be accessed sequentially for InnoDB to"
+ "trigger a readahead.",
+ NULL, NULL, 56, 0, 64, 0);
static MYSQL_SYSVAR_LONGLONG(ibuf_max_size, srv_ibuf_max_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -10226,13 +10655,18 @@ static MYSQL_SYSVAR_LONGLONG(ibuf_max_size, srv_ibuf_max_size,
static MYSQL_SYSVAR_ULONG(ibuf_active_contract, srv_ibuf_active_contract,
PLUGIN_VAR_RQCMDARG,
"Enable/Disable active_contract of insert buffer. 0:disable 1:enable",
- NULL, NULL, 0, 0, 1, 0);
+ NULL, NULL, 1, 0, 1, 0);
static MYSQL_SYSVAR_ULONG(ibuf_accel_rate, srv_ibuf_accel_rate,
PLUGIN_VAR_RQCMDARG,
"Tunes amount of insert buffer processing of background, in addition to innodb_io_capacity. (in percentage)",
NULL, NULL, 100, 100, 999999999, 0);
+static MYSQL_SYSVAR_ULONG(checkpoint_age_target, srv_checkpoint_age_target,
+ PLUGIN_VAR_RQCMDARG,
+ "Control soft limit of checkpoint age. (0 : not control)",
+ NULL, NULL, 0, 0, ~0UL, 0);
+
static MYSQL_SYSVAR_ULONG(flush_neighbor_pages, srv_flush_neighbor_pages,
PLUGIN_VAR_RQCMDARG,
"Enable/Disable flushing also neighbor pages. 0:disable 1:enable",
@@ -10268,8 +10702,8 @@ TYPELIB read_ahead_typelib=
};
static MYSQL_SYSVAR_ENUM(read_ahead, srv_read_ahead,
PLUGIN_VAR_RQCMDARG,
- "Control read ahead activity. (none, random, linear, [both])",
- NULL, innodb_read_ahead_update, 3, &read_ahead_typelib);
+ "Control read ahead activity (none, random, [linear], both). [from 1.0.5: random read ahead is ignored]",
+ NULL, innodb_read_ahead_update, 2, &read_ahead_typelib);
static
void
@@ -10299,24 +10733,14 @@ TYPELIB adaptive_checkpoint_typelib=
};
static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
PLUGIN_VAR_RQCMDARG,
- "Enable/Disable flushing along modified age. ([none], reflex, estimate)",
- NULL, innodb_adaptive_checkpoint_update, 0, &adaptive_checkpoint_typelib);
+ "Enable/Disable flushing along modified age. (none, reflex, [estimate])",
+ NULL, innodb_adaptive_checkpoint_update, 2, &adaptive_checkpoint_typelib);
static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_commit,
PLUGIN_VAR_RQCMDARG,
"Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
NULL, NULL, 0, 0, 1, 0);
-static MYSQL_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Number of background read I/O threads in InnoDB.",
- NULL, NULL, 8, 1, 64, 0);
-
-static MYSQL_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Number of background write I/O threads in InnoDB.",
- NULL, NULL, 8, 1, 64, 0);
-
static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import,
PLUGIN_VAR_RQCMDARG,
"Enable/Disable converting automatically *.ibd files when import tablespace.",
@@ -10325,13 +10749,18 @@ static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import,
static MYSQL_SYSVAR_ULONG(extra_rsegments, srv_extra_rsegments,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Number of extra user rollback segments when create new database.",
- NULL, NULL, 0, 0, 127, 0);
+ NULL, NULL, 0, 0, 126, 0);
static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit,
PLUGIN_VAR_RQCMDARG,
"Limit the allocated memory for dictionary cache. (0: unlimited)",
NULL, NULL, 0, 0, LONG_MAX, 0);
+static MYSQL_SYSVAR_ULONG(relax_table_creation, srv_relax_table_creation,
+ PLUGIN_VAR_RQCMDARG,
+ "Relax limitation of column size at table creation as builtin InnoDB.",
+ NULL, NULL, 0, 0, 1, 0);
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
@@ -10344,8 +10773,11 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(extra_undoslots),
MYSQL_SYSVAR(fast_recovery),
+ MYSQL_SYSVAR(recovery_stats),
MYSQL_SYSVAR(fast_shutdown),
MYSQL_SYSVAR(file_io_threads),
+ MYSQL_SYSVAR(read_io_threads),
+ MYSQL_SYSVAR(write_io_threads),
MYSQL_SYSVAR(file_per_table),
MYSQL_SYSVAR(file_format),
MYSQL_SYSVAR(file_format_check),
@@ -10363,14 +10795,18 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(log_files_in_group),
MYSQL_SYSVAR(log_group_home_dir),
MYSQL_SYSVAR(max_dirty_pages_pct),
+ MYSQL_SYSVAR(adaptive_flushing),
MYSQL_SYSVAR(max_purge_lag),
MYSQL_SYSVAR(mirrored_log_groups),
+ MYSQL_SYSVAR(old_blocks_pct),
+ MYSQL_SYSVAR(old_blocks_time),
MYSQL_SYSVAR(open_files),
MYSQL_SYSVAR(overwrite_relay_log_info),
MYSQL_SYSVAR(rollback_on_timeout),
MYSQL_SYSVAR(stats_on_metadata),
MYSQL_SYSVAR(stats_method),
MYSQL_SYSVAR(stats_auto_update),
+ MYSQL_SYSVAR(stats_update_need_lock),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
MYSQL_SYSVAR(replication_delay),
@@ -10378,6 +10814,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(strict_mode),
MYSQL_SYSVAR(support_xa),
MYSQL_SYSVAR(sync_spin_loops),
+ MYSQL_SYSVAR(spin_wait_delay),
MYSQL_SYSVAR(table_locks),
MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_concurrency_timer_based),
@@ -10386,186 +10823,26 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(show_verbose_locks),
MYSQL_SYSVAR(show_locks_held),
MYSQL_SYSVAR(version),
- MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(ibuf_max_size),
MYSQL_SYSVAR(ibuf_active_contract),
MYSQL_SYSVAR(ibuf_accel_rate),
+ MYSQL_SYSVAR(checkpoint_age_target),
MYSQL_SYSVAR(flush_neighbor_pages),
MYSQL_SYSVAR(read_ahead),
MYSQL_SYSVAR(adaptive_checkpoint),
MYSQL_SYSVAR(enable_unsafe_group_commit),
- MYSQL_SYSVAR(read_io_threads),
- MYSQL_SYSVAR(write_io_threads),
MYSQL_SYSVAR(expand_import),
MYSQL_SYSVAR(extra_rsegments),
MYSQL_SYSVAR(dict_size_limit),
MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(change_buffering),
+ MYSQL_SYSVAR(read_ahead_threshold),
+ MYSQL_SYSVAR(io_capacity),
+ MYSQL_SYSVAR(use_purge_thread),
+ MYSQL_SYSVAR(relax_table_creation),
NULL
};
-#ifdef MYSQL_DYNAMIC_PLUGIN
-struct st_mysql_sys_var
-{
- MYSQL_PLUGIN_VAR_HEADER;
- void* value;
-};
-
-struct param_mapping
-{
- const char* server; /* Parameter name in the server. */
- const char* plugin; /* Paramater name in the plugin. */
-};
-
-/********************************************************************
-Match the parameters from the static and dynamic versions. */
-static
-bool
-innobase_match_parameter(
-/*=====================*/
- /* out: true if names match */
- const char* from_server, /* in: variable name from server */
- const char* from_plugin) /* in: variable name from plugin */
-{
- static const param_mapping param_map[] = {
- {"use_adaptive_hash_indexes", "adaptive_hash_index"}
- };
-
- if (strcmp(from_server, from_plugin) == 0) {
- return(true);
- }
-
- const param_mapping* param = param_map;
- int n_elems = sizeof(param_map) / sizeof(param_map[0]);
-
- for (int i = 0; i < n_elems; ++i, ++param) {
-
- if (strcmp(param->server, from_server) == 0
- && strcmp(param->plugin, from_plugin) == 0) {
-
- return(true);
- }
- }
-
- return(false);
-}
-
-/********************************************************************
-Copy InnoDB system variables from the static InnoDB to the dynamic
-plugin. */
-static
-bool
-innodb_plugin_init(void)
-/*====================*/
- /* out: TRUE if the dynamic InnoDB plugin should start */
-{
-#if !MYSQL_STORAGE_ENGINE_PLUGIN
-#error "MYSQL_STORAGE_ENGINE_PLUGIN must be nonzero."
-#endif
-
- /* Copy the system variables. */
-
- struct st_mysql_plugin* builtin;
- struct st_mysql_sys_var** sta; /* static parameters */
- struct st_mysql_sys_var** dyn; /* dynamic parameters */
-
-#ifdef __WIN__
- if (!builtin_innobase_plugin_ptr) {
-
- return(true);
- }
-
- builtin = builtin_innobase_plugin_ptr;
-#else
- switch (builtin_innobase_plugin) {
- case 0:
- return(true);
- case MYSQL_STORAGE_ENGINE_PLUGIN:
- break;
- default:
- return(false);
- }
-
- builtin = (struct st_mysql_plugin*) &builtin_innobase_plugin;
-#endif
-
- for (sta = builtin->system_vars; *sta != NULL; sta++) {
-
- for (dyn = innobase_system_variables; *dyn != NULL; dyn++) {
-
- /* do not copy session variables */
- if (((*sta)->flags | (*dyn)->flags)
- & PLUGIN_VAR_THDLOCAL) {
- continue;
- }
-
- if (innobase_match_parameter((*sta)->name,
- (*dyn)->name)) {
-
- /* found the corresponding parameter */
-
- /* check if the flags are the same,
- ignoring differences in the READONLY or
- NOSYSVAR flags;
- e.g. we are not copying string variable to
- an integer one, but we do not care if it is
- readonly in the static and not in the
- dynamic */
- if (((*sta)->flags ^ (*dyn)->flags)
- & ~(PLUGIN_VAR_READONLY
- | PLUGIN_VAR_NOSYSVAR)) {
-
- fprintf(stderr,
- "InnoDB: %s in static InnoDB "
- "(flags=0x%x) differs from "
- "%s in dynamic InnoDB "
- "(flags=0x%x)\n",
- (*sta)->name, (*sta)->flags,
- (*dyn)->name, (*dyn)->flags);
-
- /* we could break; here leaving this
- parameter uncopied */
- return(false);
- }
-
- /* assign the value of the static parameter
- to the dynamic one, according to their type */
-
-#define COPY_VAR(label, type) \
- case label: \
- *(type*)(*dyn)->value = *(type*)(*sta)->value; \
- break;
-
- switch ((*sta)->flags
- & ~(PLUGIN_VAR_MASK
- | PLUGIN_VAR_UNSIGNED)) {
-
- COPY_VAR(PLUGIN_VAR_BOOL, char);
- COPY_VAR(PLUGIN_VAR_INT, int);
- COPY_VAR(PLUGIN_VAR_LONG, long);
- COPY_VAR(PLUGIN_VAR_LONGLONG, long long);
- COPY_VAR(PLUGIN_VAR_STR, char*);
-
- default:
- fprintf(stderr,
- "InnoDB: unknown flags "
- "0x%x for %s\n",
- (*sta)->flags, (*sta)->name);
- }
-
- /* Make the static InnoDB variable point to
- the dynamic one */
- (*sta)->value = (*dyn)->value;
-
- break;
- }
- }
- }
-
- return(true);
-}
-#endif /* MYSQL_DYNAMIC_PLUGIN */
-
mysql_declare_plugin(innobase)
{
MYSQL_STORAGE_ENGINE_PLUGIN,
@@ -10594,6 +10871,7 @@ i_s_innodb_cmpmem,
i_s_innodb_cmpmem_reset,
i_s_innodb_table_stats,
i_s_innodb_index_stats,
+i_s_innodb_admin_command,
i_s_innodb_patches
mysql_declare_plugin_end;
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index d5a50a74d6f..6c7098560b9 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -27,35 +27,43 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma interface /* gcc class implementation */
#endif
+/** InnoDB table share */
typedef struct st_innobase_share {
- THR_LOCK lock;
- pthread_mutex_t mutex;
- const char* table_name;
- uint use_count;
- void* table_name_hash;
+ THR_LOCK lock; /*!< MySQL lock protecting
+ this structure */
+ const char* table_name; /*!< InnoDB table name */
+ uint use_count; /*!< reference count,
+ incremented in get_share()
+ and decremented in free_share() */
+ void* table_name_hash;/*!< hash table chain node */
} INNOBASE_SHARE;
+/** InnoDB B-tree index */
struct dict_index_struct;
+/** Prebuilt structures in an Innobase table handle used within MySQL */
struct row_prebuilt_struct;
+/** InnoDB B-tree index */
typedef struct dict_index_struct dict_index_t;
+/** Prebuilt structures in an Innobase table handle used within MySQL */
typedef struct row_prebuilt_struct row_prebuilt_t;
-/* The class defining a handle to an Innodb table */
+/** The class defining a handle to an Innodb table */
class ha_innobase: public handler
{
- row_prebuilt_t* prebuilt; /* prebuilt struct in InnoDB, used
+ row_prebuilt_t* prebuilt; /*!< prebuilt struct in InnoDB, used
to save CPU time with prebuilt data
structures*/
- THD* user_thd; /* the thread handle of the user
+ THD* user_thd; /*!< the thread handle of the user
currently using the handle; this is
set in external_lock function */
THR_LOCK_DATA lock;
- INNOBASE_SHARE *share;
+ INNOBASE_SHARE* share; /*!< information for MySQL
+ table locking */
- uchar* upd_buff; /* buffer used in updates */
- uchar* key_val_buff; /* buffer used in converting
+ uchar* upd_buff; /*!< buffer used in updates */
+ uchar* key_val_buff; /*!< buffer used in converting
search key values from MySQL format
to Innodb format */
ulong upd_and_key_val_buff_len;
@@ -63,13 +71,13 @@ class ha_innobase: public handler
two buffers */
Table_flags int_table_flags;
uint primary_key;
- ulong start_of_scan; /* this is set to 1 when we are
+ ulong start_of_scan; /*!< this is set to 1 when we are
starting a table scan but have not
yet fetched any row, else 0 */
uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */
- uint num_write_row; /* number of write_row() calls */
+ uint num_write_row; /*!< number of write_row() calls */
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
const uchar* record);
@@ -119,14 +127,6 @@ class ha_innobase: public handler
void try_semi_consistent_read(bool yes);
void unlock_row();
-#ifdef ROW_MERGE_IS_INDEX_USABLE
- /** Check if an index can be used by this transaction.
- * @param keynr key number to check
- * @return true if available, false if the index
- * does not contain old records that exist
- * in the read view of this transaction */
- bool is_index_available(uint keynr);
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
int index_init(uint index, bool sorted);
int index_end();
int index_read(uchar * buf, const uchar * key,
@@ -274,27 +274,55 @@ int thd_binlog_format(const MYSQL_THD thd);
@param all TRUE <=> rollback main transaction.
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+
+#if MYSQL_VERSION_ID > 50140
+/**
+ Check if binary logging is filtered for thread's current db.
+ @param thd Thread handle
+ @retval 1 the query is not filtered, 0 otherwise.
+*/
+bool thd_binlog_filter_ok(const MYSQL_THD thd);
+#endif /* MYSQL_VERSION_ID > 50140 */
}
typedef struct trx_struct trx_t;
-/************************************************************************
+/********************************************************************//**
+@file handler/ha_innodb.h
Converts an InnoDB error code to a MySQL error code and also tells to MySQL
about a possible transaction rollback inside InnoDB caused by a lock wait
-timeout or a deadlock. */
+timeout or a deadlock.
+@return MySQL error code */
extern "C"
int
convert_error_code_to_mysql(
/*========================*/
- /* out: MySQL error code */
- int error, /* in: InnoDB error code */
- ulint flags, /* in: InnoDB table flags, or 0 */
- MYSQL_THD thd); /* in: user thread handle or NULL */
+ int error, /*!< in: InnoDB error code */
+ ulint flags, /*!< in: InnoDB table flags, or 0 */
+ MYSQL_THD thd); /*!< in: user thread handle or NULL */
-/*************************************************************************
-Allocates an InnoDB transaction for a MySQL handler object. */
+/*********************************************************************//**
+Allocates an InnoDB transaction for a MySQL handler object.
+@return InnoDB transaction handle */
extern "C"
trx_t*
innobase_trx_allocate(
/*==================*/
- /* out: InnoDB transaction handle */
- MYSQL_THD thd); /* in: user thread handle */
+ MYSQL_THD thd); /*!< in: user thread handle */
+
+
+/*********************************************************************//**
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name
+matches, this function pushes an warning message to the client,
+and returns true. */
+extern "C"
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if the index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys); /* in: Number of indexes to
+ be created. */
+
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 1b5466e66eb..e060d88b3b8 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file handler/handler0alter.cc
Smart ALTER TABLE
*******************************************************/
@@ -34,19 +35,18 @@ extern "C" {
}
#include "ha_innodb.h"
-#include "handler0vars.h"
-/*****************************************************************
+/*************************************************************//**
Copies an InnoDB column to a MySQL field. This function is
adapted from row_sel_field_store_in_mysql_format(). */
static
void
innobase_col_to_mysql(
/*==================*/
- const dict_col_t* col, /* in: InnoDB column */
- const uchar* data, /* in: InnoDB column data */
- ulint len, /* in: length of data, in bytes */
- Field* field) /* in/out: MySQL field */
+ const dict_col_t* col, /*!< in: InnoDB column */
+ const uchar* data, /*!< in: InnoDB column data */
+ ulint len, /*!< in: length of data, in bytes */
+ Field* field) /*!< in/out: MySQL field */
{
uchar* ptr;
uchar* dest = field->ptr;
@@ -122,16 +122,16 @@ innobase_col_to_mysql(
}
}
-/*****************************************************************
+/*************************************************************//**
Copies an InnoDB record to table->record[0]. */
extern "C" UNIV_INTERN
void
innobase_rec_to_mysql(
/*==================*/
- 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(
+ 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(
rec, index, ...) */
{
uint n_fields = table->s->fields;
@@ -172,13 +172,13 @@ null_field:
}
}
-/*****************************************************************
+/*************************************************************//**
Resets table->record[0]. */
extern "C" UNIV_INTERN
void
innobase_rec_reset(
/*===============*/
- TABLE* table) /* in/out: MySQL table */
+ TABLE* table) /*!< in/out: MySQL table */
{
uint n_fields = table->s->fields;
uint i;
@@ -188,13 +188,13 @@ innobase_rec_reset(
}
}
-/**********************************************************************
+/******************************************************************//**
Removes the filename encoding of a database and table name. */
static
void
innobase_convert_tablename(
/*=======================*/
- char* s) /* in: identifier; out: decoded identifier */
+ char* s) /*!< in: identifier; out: decoded identifier */
{
uint errors;
@@ -222,15 +222,15 @@ innobase_convert_tablename(
}
}
-/***********************************************************************
-This function checks that index keys are sensible. */
+/*******************************************************************//**
+This function checks that index keys are sensible.
+@return 0 or error number */
static
int
innobase_check_index_keys(
/*======================*/
- /* out: 0 or error number */
- const KEY* key_info, /* in: Indexes to be created */
- ulint num_of_keys) /* in: Number of indexes to
+ const KEY* key_info, /*!< in: Indexes to be created */
+ ulint num_of_keys) /*!< in: Number of indexes to
be created */
{
ulint key_num;
@@ -322,15 +322,15 @@ innobase_check_index_keys(
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Create index field definition for key part */
static
void
innobase_create_index_field_def(
/*============================*/
- KEY_PART_INFO* key_part, /* in: MySQL key definition */
- mem_heap_t* heap, /* in: memory heap */
- merge_index_field_t* index_field) /* out: index field
+ KEY_PART_INFO* key_part, /*!< in: MySQL key definition */
+ mem_heap_t* heap, /*!< in: memory heap */
+ merge_index_field_t* index_field) /*!< out: index field
definition for key_part */
{
Field* field;
@@ -364,20 +364,20 @@ innobase_create_index_field_def(
DBUG_VOID_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Create index definition for key */
static
void
innobase_create_index_def(
/*======================*/
- KEY* key, /* in: key definition */
- bool new_primary, /* in: TRUE=generating
+ KEY* key, /*!< in: key definition */
+ bool new_primary, /*!< in: TRUE=generating
a new primary key
on the table */
- bool key_primary, /* in: TRUE if this key
+ bool key_primary, /*!< in: TRUE if this key
is a primary key */
- merge_index_def_t* index, /* out: index definition */
- mem_heap_t* heap) /* in: heap where memory
+ merge_index_def_t* index, /*!< out: index definition */
+ mem_heap_t* heap) /*!< in: heap where memory
is allocated */
{
ulint i;
@@ -418,14 +418,14 @@ innobase_create_index_def(
DBUG_VOID_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Copy index field definition */
static
void
innobase_copy_index_field_def(
/*==========================*/
- const dict_field_t* field, /* in: definition to copy */
- merge_index_field_t* index_field) /* out: copied definition */
+ const dict_field_t* field, /*!< in: definition to copy */
+ merge_index_field_t* index_field) /*!< out: copied definition */
{
DBUG_ENTER("innobase_copy_index_field_def");
DBUG_ASSERT(field != NULL);
@@ -437,15 +437,15 @@ innobase_copy_index_field_def(
DBUG_VOID_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Copy index definition for the index */
static
void
innobase_copy_index_def(
/*====================*/
- const dict_index_t* index, /* in: index definition to copy */
- merge_index_def_t* new_index,/* out: Index definition */
- mem_heap_t* heap) /* in: heap where allocated */
+ const dict_index_t* index, /*!< in: index definition to copy */
+ merge_index_def_t* new_index,/*!< out: Index definition */
+ mem_heap_t* heap) /*!< in: heap where allocated */
{
ulint n_fields;
ulint i;
@@ -475,7 +475,7 @@ innobase_copy_index_def(
DBUG_VOID_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Create an index table where indexes are ordered as follows:
IF a new primary key is defined for the table THEN
@@ -490,18 +490,18 @@ ELSE
ENDIF
-*/
+
+@return key definitions or NULL */
static
merge_index_def_t*
innobase_create_key_def(
/*====================*/
- /* out: key definitions or NULL */
- trx_t* trx, /* in: trx */
- const dict_table_t*table, /* in: table definition */
- mem_heap_t* heap, /* in: heap where space for key
+ trx_t* trx, /*!< in: trx */
+ const dict_table_t*table, /*!< in: table definition */
+ mem_heap_t* heap, /*!< in: heap where space for key
definitions are allocated */
- KEY* key_info, /* in: Indexes to be created */
- ulint& n_keys) /* in/out: Number of indexes to
+ KEY* key_info, /*!< in: Indexes to be created */
+ ulint& n_keys) /*!< in/out: Number of indexes to
be created */
{
ulint i = 0;
@@ -582,16 +582,16 @@ innobase_create_key_def(
DBUG_RETURN(indexdefs);
}
-/***********************************************************************
-Create a temporary tablename using query id, thread id, and id */
+/*******************************************************************//**
+Create a temporary tablename using query id, thread id, and id
+@return temporary tablename */
static
char*
innobase_create_temporary_tablename(
/*================================*/
- /* out: temporary tablename */
- mem_heap_t* heap, /* in: memory heap */
- char id, /* in: identifier [0-9a-zA-Z] */
- const char* table_name) /* in: table name */
+ mem_heap_t* heap, /*!< in: memory heap */
+ char id, /*!< in: identifier [0-9a-zA-Z] */
+ const char* table_name) /*!< in: table name */
{
char* name;
ulint len;
@@ -607,28 +607,28 @@ innobase_create_temporary_tablename(
return(name);
}
-/***********************************************************************
-Create indexes. */
+/*******************************************************************//**
+Create indexes.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::add_index(
/*===================*/
- /* out: 0 or error number */
- TABLE* table, /* in: Table where indexes are created */
- KEY* key_info, /* in: Indexes to be created */
- uint num_of_keys) /* in: Number of indexes to be created */
+ TABLE* table, /*!< in: Table where indexes are created */
+ KEY* key_info, /*!< in: Indexes to be created */
+ uint num_of_keys) /*!< in: Number of indexes to be created */
{
- dict_index_t** index; /* Index to be created */
- dict_table_t* innodb_table; /* InnoDB table in dictionary */
- dict_table_t* indexed_table; /* Table where indexes are created */
- merge_index_def_t* index_defs; /* Index definitions */
- mem_heap_t* heap; /* Heap for index definitions */
- trx_t* trx; /* Transaction */
+ dict_index_t** index; /*!< Index to be created */
+ dict_table_t* innodb_table; /*!< InnoDB table in dictionary */
+ dict_table_t* indexed_table; /*!< Table where indexes are created */
+ merge_index_def_t* index_defs; /*!< Index definitions */
+ mem_heap_t* heap; /*!< Heap for index definitions */
+ trx_t* trx; /*!< Transaction */
ulint num_of_idx;
ulint num_created = 0;
ibool dict_locked = FALSE;
ulint new_primary;
- ulint error;
+ int error;
DBUG_ENTER("ha_innobase::add_index");
ut_a(table);
@@ -646,6 +646,7 @@ ha_innobase::add_index(
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads. */
trx_search_latch_release_if_reserved(prebuilt->trx);
+ trx_start_if_not_started(prebuilt->trx);
/* Create a background transaction for the operations on
the data dictionary tables. */
@@ -655,14 +656,18 @@ ha_innobase::add_index(
innodb_table = indexed_table
= dict_table_get(prebuilt->table->name, FALSE);
- /* Check that index keys are sensible */
-
- error = innobase_check_index_keys(key_info, num_of_keys);
+ /* Check if the index name is reserved. */
+ if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
+ error = ER_WRONG_NAME_FOR_INDEX;
+ } else {
+ /* Check that index keys are sensible */
+ error = innobase_check_index_keys(key_info, num_of_keys);
+ }
if (UNIV_UNLIKELY(error)) {
err_exit:
mem_heap_free(heap);
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx_free_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx);
DBUG_RETURN(error);
@@ -760,10 +765,11 @@ err_exit:
ut_ad(error == DB_SUCCESS);
/* Commit the data dictionary transaction in order to release
- the table locks on the system tables. Unfortunately, this
- means that if MySQL crashes while creating a new primary key
- inside row_merge_build_indexes(), indexed_table will not be
- dropped on crash recovery. Thus, it will become orphaned. */
+ the table locks on the system tables. This means that if
+ MySQL crashes while creating a new primary key inside
+ row_merge_build_indexes(), indexed_table will not be dropped
+ by trx_rollback_active(). It will have to be recovered or
+ dropped by the database administrator. */
trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
@@ -800,7 +806,7 @@ error_handling:
alter table t drop index b, add index (b);
The fix will have to parse the SQL and note that the index
- being added has the same name as the the one being dropped and
+ being added has the same name as the one being dropped and
ignore that in the dup index check.*/
//dict_table_check_for_dup_indexes(prebuilt->table);
#endif
@@ -862,6 +868,7 @@ error_handling:
indexed_table->n_mysql_handles_opened++;
error = row_merge_drop_table(trx, innodb_table);
+ innodb_table = indexed_table;
goto convert_error;
case DB_TOO_BIG_RECORD:
@@ -876,7 +883,9 @@ error:
/* fall through */
default:
if (new_primary) {
- row_merge_drop_table(trx, indexed_table);
+ if (indexed_table != innodb_table) {
+ row_merge_drop_table(trx, indexed_table);
+ }
} else {
if (!dict_locked) {
row_mysql_lock_data_dictionary(trx);
@@ -911,16 +920,16 @@ convert_error:
DBUG_RETURN(error);
}
-/***********************************************************************
-Prepare to drop some indexes of a table. */
+/*******************************************************************//**
+Prepare to drop some indexes of a table.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::prepare_drop_index(
/*============================*/
- /* out: 0 or error number */
- TABLE* table, /* in: Table where indexes are dropped */
- uint* key_num, /* in: Key nums to be dropped */
- uint num_of_keys) /* in: Number of keys to be dropped */
+ TABLE* table, /*!< in: Table where indexes are dropped */
+ uint* key_num, /*!< in: Key nums to be dropped */
+ uint num_of_keys) /*!< in: Number of keys to be dropped */
{
trx_t* trx;
int err = 0;
@@ -1112,17 +1121,17 @@ func_exit:
DBUG_RETURN(err);
}
-/***********************************************************************
-Drop the indexes that were passed to a successful prepare_drop_index(). */
+/*******************************************************************//**
+Drop the indexes that were passed to a successful prepare_drop_index().
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::final_drop_index(
/*==========================*/
- /* out: 0 or error number */
- TABLE* table) /* in: Table where indexes are dropped */
+ TABLE* table) /*!< in: Table where indexes are dropped */
{
- dict_index_t* index; /* Index to be dropped */
- trx_t* trx; /* Transaction */
+ dict_index_t* index; /*!< Index to be dropped */
+ trx_t* trx; /*!< Transaction */
int err;
DBUG_ENTER("ha_innobase::final_drop_index");
@@ -1135,6 +1144,7 @@ ha_innobase::final_drop_index(
update_thd();
trx_search_latch_release_if_reserved(prebuilt->trx);
+ trx_start_if_not_started(prebuilt->trx);
/* Create a background transaction for the operations on
the data dictionary tables. */
diff --git a/storage/xtradb/handler/handler0vars.h b/storage/xtradb/handler/handler0vars.h
deleted file mode 100644
index fa7de329e67..00000000000
--- a/storage/xtradb/handler/handler0vars.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2008, 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
-
-*****************************************************************************/
-
-/***********************************************************************
-This file contains accessor functions for dynamic plugin on Windows.
-***********************************************************************/
-
-#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
-/***********************************************************************
-This is a list of externals that can not be resolved by delay loading.
-They have to be resolved indirectly via their addresses in the .map file.
-All of them are external variables. */
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_bin;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO* system_charset_info;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO* default_charset_info;
-//extern MYSQL_PLUGIN_IMPORT CHARSET_INFO** all_charsets;
-extern MYSQL_PLUGIN_IMPORT system_variables global_system_variables;
-//extern MYSQL_PLUGIN_IMPORT char* mysql_real_data_home;
-extern MYSQL_PLUGIN_IMPORT char* mysql_data_home;
-//extern MYSQL_PLUGIN_IMPORT char** tx_isolation_names;
-//extern MYSQL_PLUGIN_IMPORT char** binlog_format_names;
-//extern MYSQL_PLUGIN_IMPORT char reg_ext;
-extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
-extern MYSQL_PLUGIN_IMPORT key_map key_map_full;
-extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
-extern MYSQL_PLUGIN_IMPORT bool mysqld_embedded;
-extern MYSQL_PLUGIN_IMPORT uint lower_case_table_names;
-extern MYSQL_PLUGIN_IMPORT ulong specialflag;
-extern MYSQL_PLUGIN_IMPORT int my_umask;
-
-extern MYSQL_PLUGIN_IMPORT char *relay_log_info_file;
-
-/*
-#define my_charset_bin (*wdl_my_charset_bin)
-#define my_charset_latin1 (*wdl_my_charset_latin1)
-#define my_charset_filename (*wdl_my_charset_filename)
-#define system_charset_info (*wdl_system_charset_info)
-#define default_charset_info (*wdl_default_charset_info)
-#define all_charsets (wdl_all_charsets)
-#define global_system_variables (*wdl_global_system_variables)
-#define mysql_real_data_home (wdl_mysql_real_data_home)
-#define mysql_data_home (*wdl_mysql_data_home)
-#define tx_isolation_names (wdl_tx_isolation_names)
-#define binlog_format_names (wdl_binlog_format_names)
-#define reg_ext (wdl_reg_ext)
-#define LOCK_thread_count (*wdl_LOCK_thread_count)
-#define key_map_full (*wdl_key_map_full)
-#define mysql_tmpdir_list (*wdl_mysql_tmpdir_list)
-#define mysqld_embedded (*wdl_mysqld_embedded)
-*/
-//#define lower_case_table_names (*wdl_lower_case_table_names)
-//#define specialflag (*wdl_specialflag)
-//#define my_umask (*wdl_my_umask)
-
-#endif
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index e45f2b4dac0..fce4e66a791 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file handler/i_s.cc
InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov
@@ -46,6 +47,7 @@ extern "C" {
#include "trx0rseg.h" /* for trx_rseg_struct */
#include "trx0sys.h" /* for trx_sys */
#include "dict0dict.h" /* for dict_sys */
+#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
/* from buf0buf.c */
struct buf_chunk_struct{
ulint mem_size; /* allocated size of the chunk */
@@ -55,7 +57,6 @@ struct buf_chunk_struct{
buf_block_t* blocks; /* array of buffer control blocks */
};
}
-#include "handler0vars.h"
static const char plugin_author[] = "Innobase Oy";
@@ -83,14 +84,16 @@ do { \
#define STRUCT_FLD(name, value) value
#endif
-static const ST_FIELD_INFO END_OF_ST_FIELD_INFO =
- {STRUCT_FLD(field_name, NULL),
- STRUCT_FLD(field_length, 0),
- STRUCT_FLD(field_type, MYSQL_TYPE_NULL),
- STRUCT_FLD(value, 0),
- STRUCT_FLD(field_flags, 0),
- STRUCT_FLD(old_name, ""),
- STRUCT_FLD(open_method, SKIP_OPEN_TABLE)};
+/* Don't use a static const variable here, as some C++ compilers (notably
+HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
+#define END_OF_ST_FIELD_INFO \
+ {STRUCT_FLD(field_name, NULL), \
+ STRUCT_FLD(field_length, 0), \
+ STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
+ STRUCT_FLD(value, 0), \
+ STRUCT_FLD(field_flags, 0), \
+ STRUCT_FLD(old_name, ""), \
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
/*
Use the following types mapping:
@@ -125,39 +128,39 @@ bool schema_table_store_record(THD *thd, TABLE *table);
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
bool check_global_access(THD *thd, ulong want_access);
-/***********************************************************************
+/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
INFORMATION_SCHEMA.innodb_locks
-INFORMATION_SCHEMA.innodb_lock_waits */
+INFORMATION_SCHEMA.innodb_lock_waits
+@return 0 on success */
static
int
trx_i_s_common_fill_table(
/*======================*/
- /* out: 0 on success */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond); /* in: condition (not used) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond); /*!< in: condition (not used) */
-/***********************************************************************
-Unbind a dynamic INFORMATION_SCHEMA table. */
+/*******************************************************************//**
+Unbind a dynamic INFORMATION_SCHEMA table.
+@return 0 on success */
static
int
i_s_common_deinit(
/*==============*/
- /* out: 0 on success */
- void* p); /* in/out: table schema object */
+ void* p); /*!< in/out: table schema object */
-/***********************************************************************
+/*******************************************************************//**
Auxiliary function to store time_t value in MYSQL_TYPE_DATETIME
-field. */
+field.
+@return 0 on success */
static
int
field_store_time_t(
/*===============*/
- /* out: 0 on success */
- Field* field, /* in/out: target field for storage */
- time_t time) /* in: value to store */
+ Field* field, /*!< in/out: target field for storage */
+ time_t time) /*!< in: value to store */
{
MYSQL_TIME my_time;
struct tm tm_time;
@@ -176,15 +179,15 @@ field_store_time_t(
return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME));
}
-/***********************************************************************
-Auxiliary function to store char* value in MYSQL_TYPE_STRING field. */
+/*******************************************************************//**
+Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
+@return 0 on success */
static
int
field_store_string(
/*===============*/
- /* out: 0 on success */
- Field* field, /* in/out: target field for storage */
- const char* str) /* in: NUL-terminated utf-8 string,
+ Field* field, /*!< in/out: target field for storage */
+ const char* str) /*!< in: NUL-terminated utf-8 string,
or NULL */
{
int ret;
@@ -203,16 +206,16 @@ field_store_string(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
-If the value is ULINT_UNDEFINED then the field it set to NULL. */
+If the value is ULINT_UNDEFINED then the field it set to NULL.
+@return 0 on success */
static
int
field_store_ulint(
/*==============*/
- /* out: 0 on success */
- Field* field, /* in/out: target field for storage */
- ulint n) /* in: value to store */
+ Field* field, /*!< in/out: target field for storage */
+ ulint n) /*!< in: value to store */
{
int ret;
@@ -510,7 +513,7 @@ static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_index_fields_info[] =
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
- {STRUCT_FLD(field_name, "accessed"),
+ {STRUCT_FLD(field_name, "access_time"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
@@ -727,7 +730,7 @@ i_s_innodb_buffer_pool_pages_fill(
field_store_string(table->field[0], page_type);
table->field[1]->store(block->page.space);
table->field[2]->store(block->page.offset);
- table->field[3]->store(block->page.LRU_position);
+ table->field[3]->store(0);
table->field[4]->store(block->page.buf_fix_count);
table->field[5]->store(block->page.flush_type);
@@ -806,7 +809,7 @@ i_s_innodb_buffer_pool_pages_index_fill(
field_store_string(table->field[0], NULL);
p = (char *)index->table_name;
}
- strcpy(table_name_raw, p);
+ strcpy(table_name_raw, (const char*)p);
filename_to_tablename(table_name_raw, table_name, sizeof(table_name));
field_store_string(table->field[1], table_name);
field_store_string(table->field[2], index->name);
@@ -816,11 +819,11 @@ i_s_innodb_buffer_pool_pages_index_fill(
table->field[5]->store(page_get_n_recs(frame));
table->field[6]->store(page_get_data_size(frame));
table->field[7]->store(block->is_hashed);
- table->field[8]->store(block->page.accessed);
+ table->field[8]->store(block->page.access_time);
table->field[9]->store(block->page.newest_modification != 0);
table->field[10]->store(block->page.oldest_modification != 0);
table->field[11]->store(block->page.old);
- table->field[12]->store(block->page.LRU_position);
+ table->field[12]->store(0);
table->field[13]->store(block->page.buf_fix_count);
table->field[14]->store(block->page.flush_type);
@@ -914,7 +917,7 @@ i_s_innodb_buffer_pool_pages_blob_fill(
table->field[4]->store(block->page.offset);
}
- table->field[5]->store(block->page.LRU_position);
+ table->field[5]->store(0);
table->field[6]->store(block->page.buf_fix_count);
table->field[7]->store(block->page.flush_type);
@@ -1214,18 +1217,18 @@ static ST_FIELD_INFO innodb_trx_fields_info[] =
END_OF_ST_FIELD_INFO
};
-/***********************************************************************
+/*******************************************************************//**
Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_trx
-table with it. */
+table with it.
+@return 0 on success */
static
int
fill_innodb_trx_from_cache(
/*=======================*/
- /* out: 0 on success */
- trx_i_s_cache_t* cache, /* in: cache to read from */
- THD* thd, /* in: used to call
+ trx_i_s_cache_t* cache, /*!< in: cache to read from */
+ THD* thd, /*!< in: used to call
schema_table_store_record() */
- TABLE* table) /* in/out: fill this table */
+ TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@@ -1299,14 +1302,14 @@ fill_innodb_trx_from_cache(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table INFORMATION_SCHEMA.innodb_trx */
+/*******************************************************************//**
+Bind the dynamic table INFORMATION_SCHEMA.innodb_trx
+@return 0 on success */
static
int
innodb_trx_init(
/*============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@@ -1467,17 +1470,17 @@ static ST_FIELD_INFO innodb_locks_fields_info[] =
END_OF_ST_FIELD_INFO
};
-/***********************************************************************
+/*******************************************************************//**
Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_locks
-table with it. */
+table with it.
+@return 0 on success */
static
int
fill_innodb_locks_from_cache(
/*=========================*/
- /* out: 0 on success */
- trx_i_s_cache_t* cache, /* in: cache to read from */
- THD* thd, /* in: MySQL client connection */
- TABLE* table) /* in/out: fill this table */
+ trx_i_s_cache_t* cache, /*!< in: cache to read from */
+ THD* thd, /*!< in: MySQL client connection */
+ TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@@ -1575,14 +1578,14 @@ fill_innodb_locks_from_cache(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table INFORMATION_SCHEMA.innodb_locks */
+/*******************************************************************//**
+Bind the dynamic table INFORMATION_SCHEMA.innodb_locks
+@return 0 on success */
static
int
innodb_locks_init(
/*==============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@@ -1687,18 +1690,18 @@ static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
END_OF_ST_FIELD_INFO
};
-/***********************************************************************
+/*******************************************************************//**
Read data from cache buffer and fill the
-INFORMATION_SCHEMA.innodb_lock_waits table with it. */
+INFORMATION_SCHEMA.innodb_lock_waits table with it.
+@return 0 on success */
static
int
fill_innodb_lock_waits_from_cache(
/*==============================*/
- /* out: 0 on success */
- trx_i_s_cache_t* cache, /* in: cache to read from */
- THD* thd, /* in: used to call
+ trx_i_s_cache_t* cache, /*!< in: cache to read from */
+ THD* thd, /*!< in: used to call
schema_table_store_record() */
- TABLE* table) /* in/out: fill this table */
+ TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@@ -1758,14 +1761,14 @@ fill_innodb_lock_waits_from_cache(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
+/*******************************************************************//**
+Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits
+@return 0 on success */
static
int
innodb_lock_waits_init(
/*===================*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@@ -1828,19 +1831,19 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits =
STRUCT_FLD(__reserved1, NULL)
};
-/***********************************************************************
+/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
INFORMATION_SCHEMA.innodb_locks
-INFORMATION_SCHEMA.innodb_lock_waits */
+INFORMATION_SCHEMA.innodb_lock_waits
+@return 0 on success */
static
int
trx_i_s_common_fill_table(
/*======================*/
- /* out: 0 on success */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (not used) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (not used) */
{
const char* table_name;
int ret;
@@ -1989,18 +1992,18 @@ static ST_FIELD_INFO i_s_cmp_fields_info[] =
};
-/***********************************************************************
+/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmp or
-innodb_cmp_reset. */
+innodb_cmp_reset.
+@return 0 on success, 1 on failure */
static
int
i_s_cmp_fill_low(
/*=============*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond, /* in: condition (ignored) */
- ibool reset) /* in: TRUE=reset cumulated counts */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond, /*!< in: condition (ignored) */
+ ibool reset) /*!< in: TRUE=reset cumulated counts */
{
TABLE* table = (TABLE *) tables->table;
int status = 0;
@@ -2047,42 +2050,42 @@ i_s_cmp_fill_low(
DBUG_RETURN(status);
}
-/***********************************************************************
-Fill the dynamic table information_schema.innodb_cmp. */
+/*******************************************************************//**
+Fill the dynamic table information_schema.innodb_cmp.
+@return 0 on success, 1 on failure */
static
int
i_s_cmp_fill(
/*=========*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (ignored) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmp_fill_low(thd, tables, cond, FALSE));
}
-/***********************************************************************
-Fill the dynamic table information_schema.innodb_cmp_reset. */
+/*******************************************************************//**
+Fill the dynamic table information_schema.innodb_cmp_reset.
+@return 0 on success, 1 on failure */
static
int
i_s_cmp_reset_fill(
/*===============*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (ignored) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmp_fill_low(thd, tables, cond, TRUE));
}
-/***********************************************************************
-Bind the dynamic table information_schema.innodb_cmp. */
+/*******************************************************************//**
+Bind the dynamic table information_schema.innodb_cmp.
+@return 0 on success */
static
int
i_s_cmp_init(
/*=========*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmp_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@@ -2093,14 +2096,14 @@ i_s_cmp_init(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table information_schema.innodb_cmp_reset. */
+/*******************************************************************//**
+Bind the dynamic table information_schema.innodb_cmp_reset.
+@return 0 on success */
static
int
i_s_cmp_reset_init(
/*===============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmp_reset_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@@ -2257,18 +2260,18 @@ static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
END_OF_ST_FIELD_INFO
};
-/***********************************************************************
+/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmpmem or
-innodb_cmpmem_reset. */
+innodb_cmpmem_reset.
+@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_fill_low(
/*================*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond, /* in: condition (ignored) */
- ibool reset) /* in: TRUE=reset cumulated counts */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond, /*!< in: condition (ignored) */
+ ibool reset) /*!< in: TRUE=reset cumulated counts */
{
TABLE* table = (TABLE *) tables->table;
int status = 0;
@@ -2315,42 +2318,42 @@ i_s_cmpmem_fill_low(
DBUG_RETURN(status);
}
-/***********************************************************************
-Fill the dynamic table information_schema.innodb_cmpmem. */
+/*******************************************************************//**
+Fill the dynamic table information_schema.innodb_cmpmem.
+@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_fill(
/*============*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (ignored) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmpmem_fill_low(thd, tables, cond, FALSE));
}
-/***********************************************************************
-Fill the dynamic table information_schema.innodb_cmpmem_reset. */
+/*******************************************************************//**
+Fill the dynamic table information_schema.innodb_cmpmem_reset.
+@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_reset_fill(
/*==================*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (ignored) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmpmem_fill_low(thd, tables, cond, TRUE));
}
-/***********************************************************************
-Bind the dynamic table information_schema.innodb_cmpmem. */
+/*******************************************************************//**
+Bind the dynamic table information_schema.innodb_cmpmem.
+@return 0 on success */
static
int
i_s_cmpmem_init(
/*============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmpmem_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@@ -2361,14 +2364,14 @@ i_s_cmpmem_init(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table information_schema.innodb_cmpmem_reset. */
+/*******************************************************************//**
+Bind the dynamic table information_schema.innodb_cmpmem_reset.
+@return 0 on success */
static
int
i_s_cmpmem_reset_init(
/*==================*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmpmem_reset_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@@ -2478,14 +2481,14 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
STRUCT_FLD(__reserved1, NULL)
};
-/***********************************************************************
-Unbind a dynamic INFORMATION_SCHEMA table. */
+/*******************************************************************//**
+Unbind a dynamic INFORMATION_SCHEMA table.
+@return 0 on success */
static
int
i_s_common_deinit(
/*==============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_common_deinit");
@@ -2952,3 +2955,170 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats =
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
+
+/***********************************************************************
+*/
+static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
+{
+ {STRUCT_FLD(field_name, "result_message"),
+ STRUCT_FLD(field_length, 1024),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ END_OF_ST_FIELD_INFO
+};
+
+#ifndef INNODB_COMPATIBILITY_HOOKS
+#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS
+#endif
+
+extern "C" {
+char **thd_query(MYSQL_THD thd);
+}
+
+static
+int
+i_s_innodb_admin_command_fill(
+/*==========================*/
+ THD* thd,
+ TABLE_LIST* tables,
+ COND* cond)
+{
+ TABLE* i_s_table = (TABLE *) tables->table;
+ CHARSET_INFO *cs= system_charset_info;
+ char** query_str;
+ char* ptr;
+ char quote = '\0';
+ const char* command_head = "XTRA_";
+
+ DBUG_ENTER("i_s_innodb_admin_command_fill");
+
+ /* deny access to non-superusers */
+ if (check_global_access(thd, PROCESS_ACL)) {
+ DBUG_RETURN(0);
+ }
+
+ if(thd_sql_command(thd) != SQLCOM_SELECT) {
+ field_store_string(i_s_table->field[0],
+ "SELECT command is only accepted.");
+ goto end_func;
+ }
+
+ query_str = thd_query(thd);
+ ptr = *query_str;
+
+ for (; *ptr; ptr++) {
+ if (*ptr == quote) {
+ quote = '\0';
+ } else if (quote) {
+ } else if (*ptr == '`' || *ptr == '"') {
+ quote = *ptr;
+ } else {
+ long i;
+ for (i = 0; command_head[i]; i++) {
+ if (toupper((int)(unsigned char)(ptr[i]))
+ != toupper((int)(unsigned char)
+ (command_head[i]))) {
+ goto nomatch;
+ }
+ }
+ break;
+nomatch:
+ ;
+ }
+ }
+
+ if (!*ptr) {
+ field_store_string(i_s_table->field[0],
+ "No XTRA_* command in the SQL statement."
+ " Please add /*!XTRA_xxxx*/ to the SQL.");
+ goto end_func;
+ }
+
+ if (!strncasecmp("XTRA_HELLO", ptr, 10)) {
+ /* This is example command XTRA_HELLO */
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: administration command test for XtraDB"
+ " 'XTRA_HELLO' was detected.\n");
+
+ field_store_string(i_s_table->field[0],
+ "Hello!");
+ goto end_func;
+ }
+ else if (!strncasecmp("XTRA_LRU_DUMP", ptr, 13)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_DUMP'"
+ " was detected.\n");
+
+ if (buf_LRU_file_dump()) {
+ field_store_string(i_s_table->field[0],
+ "XTRA_LRU_DUMP was succeeded.");
+ } else {
+ field_store_string(i_s_table->field[0],
+ "XTRA_LRU_DUMP was failed.");
+ }
+
+ goto end_func;
+ }
+ else if (!strncasecmp("XTRA_LRU_RESTORE", ptr, 16)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_RESTORE'"
+ " was detected.\n");
+
+ if (buf_LRU_file_restore()) {
+ field_store_string(i_s_table->field[0],
+ "XTRA_LRU_RESTORE was succeeded.");
+ } else {
+ field_store_string(i_s_table->field[0],
+ "XTRA_LRU_RESTORE was failed.");
+ }
+
+ goto end_func;
+ }
+
+ field_store_string(i_s_table->field[0],
+ "Undefined XTRA_* command.");
+ goto end_func;
+
+end_func:
+ if (schema_table_store_record(thd, i_s_table)) {
+ DBUG_RETURN(1);
+ } else {
+ DBUG_RETURN(0);
+ }
+}
+
+static
+int
+i_s_innodb_admin_command_init(
+/*==========================*/
+ void* p)
+{
+ DBUG_ENTER("i_s_innodb_admin_command_init");
+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
+
+ schema->fields_info = i_s_innodb_admin_command_info;
+ schema->fill_table = i_s_innodb_admin_command_fill;
+
+ DBUG_RETURN(0);
+}
+
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "XtraDB specific command acceptor"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_admin_command_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(__reserved1, NULL)
+};
diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h
index 8601cc086ea..6d0f426acc3 100644
--- a/storage/xtradb/handler/i_s.h
+++ b/storage/xtradb/handler/i_s.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file handler/i_s.h
InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov
@@ -39,5 +40,6 @@ extern struct st_mysql_plugin i_s_innodb_patches;
extern struct st_mysql_plugin i_s_innodb_rseg;
extern struct st_mysql_plugin i_s_innodb_table_stats;
extern struct st_mysql_plugin i_s_innodb_index_stats;
+extern struct st_mysql_plugin i_s_innodb_admin_command;
#endif /* i_s_h */
diff --git a/storage/xtradb/handler/innodb_patch_info.h b/storage/xtradb/handler/innodb_patch_info.h
index 770e74f39d1..253f6360aa0 100644
--- a/storage/xtradb/handler/innodb_patch_info.h
+++ b/storage/xtradb/handler/innodb_patch_info.h
@@ -31,12 +31,17 @@ struct innodb_enhancement {
{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
-{"innodb_pause_in_spin","use 'pause' instruction during spin loop for x86 (gcc)","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
{"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_relax_table_creation","Relax limitation of column size at table creation as builtin InnoDB.","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
{NULL, NULL, NULL, NULL}
};
diff --git a/storage/xtradb/handler/mysql_addons.cc b/storage/xtradb/handler/mysql_addons.cc
index a5d9c82c3e3..eae1fe9fbc2 100644
--- a/storage/xtradb/handler/mysql_addons.cc
+++ b/storage/xtradb/handler/mysql_addons.cc
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file handler/mysql_addons.cc
This file contains functions that need to be added to
MySQL code but have not been added yet.
diff --git a/storage/xtradb/handler/win_delay_loader.cc b/storage/xtradb/handler/win_delay_loader.cc
deleted file mode 100644
index 1572df42e30..00000000000
--- a/storage/xtradb/handler/win_delay_loader.cc
+++ /dev/null
@@ -1,1036 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2008, 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
-
-*****************************************************************************/
-
-/***********************************************************************
-This file contains functions that implement the delay loader on Windows.
-
-This is a customized version of delay loader with limited functionalities.
-It does not support:
-
-* (manual) unloading
-* multiple delay loaded DLLs
-* multiple loading of the same DLL
-
-This delay loader is used only by the InnoDB plugin. Other components (DLLs)
-can still use the default delay loader, provided by MSVC.
-
-Several acronyms used by Microsoft:
- * IAT: import address table
- * INT: import name table
- * RVA: Relative Virtual Address
-
-See http://msdn.microsoft.com/en-us/magazine/bb985992.aspx for details of
-PE format.
-***********************************************************************/
-#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# include <delayimp.h>
-# include <mysql_priv.h>
-
-extern "C" {
-# include "univ.i"
-# include "hash0hash.h"
-}
-
-/***********************************************************************
-This following contains a list of externals that can not be resolved by
-delay loading. They have to be resolved indirectly via their addresses
-in the .map file. All of them are external variables. */
-CHARSET_INFO* wdl_my_charset_bin;
-CHARSET_INFO* wdl_my_charset_latin1;
-CHARSET_INFO* wdl_my_charset_filename;
-CHARSET_INFO** wdl_system_charset_info;
-CHARSET_INFO** wdl_default_charset_info;
-CHARSET_INFO** wdl_all_charsets;
-system_variables* wdl_global_system_variables;
-char* wdl_mysql_real_data_home;
-char** wdl_mysql_data_home;
-char** wdl_tx_isolation_names;
-char** wdl_binlog_format_names;
-char* wdl_reg_ext;
-pthread_mutex_t* wdl_LOCK_thread_count;
-key_map* wdl_key_map_full;
-MY_TMPDIR* wdl_mysql_tmpdir_list;
-bool* wdl_mysqld_embedded;
-uint* wdl_lower_case_table_names;
-ulong* wdl_specialflag;
-int* wdl_my_umask;
-
-/***********************************************************************
-The following is defined in ha_innodb.cc. It is used for copying the
-system variables from the builtin innodb plugin to the dynamic plugin.
-*/
-extern struct st_mysql_plugin* builtin_innobase_plugin_ptr;
-
-/***********************************************************************
-The preffered load-address defined in PE (portable executable format).*/
-#if defined(_M_IA64)
-#pragma section(".base", long, read)
-extern "C"
-__declspec(allocate(".base"))
-const IMAGE_DOS_HEADER __ImageBase;
-#else
-extern "C"
-const IMAGE_DOS_HEADER __ImageBase;
-#endif
-
-/***********************************************************************
-A template function for converting a relative address (RVA) to an
-absolute address (VA). This is due to the pointers in the delay
-descriptor (ImgDelayDescr in delayimp.h) have been changed from
-VAs to RVAs to work on both 32- and 64-bit platforms. */
-template <class X>
-X PFromRva(RVA rva) {
- return X(PBYTE(&__ImageBase) + rva);
-}
-
-/***********************************************************************
-Convert to the old format for convenience. The structure as well as its
-element names follow the definition of ImgDelayDescr in delayimp.h. */
-struct InternalImgDelayDescr {
- DWORD grAttrs; /* attributes */
- LPCSTR szName; /* pointer to dll name */
- HMODULE* phmod; /* address of module handle */
- PImgThunkData pIAT; /* address of the IAT */
- PCImgThunkData pINT; /* address of the INT */
- PCImgThunkData pBoundIAT; /* address of the optional bound IAT */
- PCImgThunkData pUnloadIAT; /* address of optional copy of
- original IAT */
- DWORD dwTimeStamp; /* 0 if not bound,
- otherwise date/time stamp of DLL
- bound to (Old BIND) */
-};
-
-typedef struct map_hash_chain_struct map_hash_chain_t;
-
-struct map_hash_chain_struct {
- char* symbol; /* pointer to a symbol */
- ulint value; /* address of the symbol */
- map_hash_chain_t* next; /* pointer to the next cell
- in the same folder. */
- map_hash_chain_t* chain; /* a linear chain used for
- cleanup. */
-};
-
-static HMODULE my_hmod = 0;
-static struct hash_table_struct* m_htbl = NULL ;
-static map_hash_chain_t* chain_header = NULL;
-static ibool wdl_init = FALSE;
-const ulint MAP_HASH_CELLS_NUM = 10000;
-
-#ifndef DBUG_OFF
-/***********************************************************************
-In the dynamic plugin, it is required to call the following dbug functions
-in the server:
- _db_pargs_
- _db_doprnt_
- _db_enter_
- _db_return_
- _db_dump_
-
-The plugin will get those function pointers during the initialization.
-*/
-typedef void (__cdecl* pfn_db_enter_)(
- const char* _func_,
- const char* _file_,
- uint _line_,
- const char** _sfunc_,
- const char** _sfile_,
- uint* _slevel_,
- char***);
-
-typedef void (__cdecl* pfn_db_return_)(
- uint _line_,
- const char** _sfunc_,
- const char** _sfile_,
- uint* _slevel_);
-
-typedef void (__cdecl* pfn_db_pargs_)(
- uint _line_,
- const char* keyword);
-
-typedef void (__cdecl* pfn_db_doprnt_)(
- const char* format,
- ...);
-
-typedef void (__cdecl* pfn_db_dump_)(
- uint _line_,
- const char* keyword,
- const unsigned char* memory,
- size_t length);
-
-static pfn_db_enter_ wdl_db_enter_;
-static pfn_db_return_ wdl_db_return_;
-static pfn_db_pargs_ wdl_db_pargs_;
-static pfn_db_doprnt_ wdl_db_doprnt_;
-static pfn_db_dump_ wdl_db_dump_;
-#endif /* !DBUG_OFF */
-
-/*****************************************************************
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n.
-
-This is the same function as hash_create in hash0hash.c, except the
-memory allocation. This function is invoked before the engine is
-initialized, and buffer pools are not ready yet. */
-static
-hash_table_t*
-wdl_hash_create(
-/*============*/
- /* out, own: created hash table */
- ulint n) /* in: number of array cells */
-{
- hash_cell_t* array;
- ulint prime;
- hash_table_t* table;
-
- prime = ut_find_prime(n);
-
- table = (hash_table_t*) malloc(sizeof(hash_table_t));
- if (table == NULL) {
- return(NULL);
- }
-
- array = (hash_cell_t*) malloc(sizeof(hash_cell_t) * prime);
- if (array == NULL) {
- free(table);
- return(NULL);
- }
-
- table->array = array;
- table->n_cells = prime;
- table->n_mutexes = 0;
- table->mutexes = NULL;
- table->heaps = NULL;
- table->heap = NULL;
- table->magic_n = HASH_TABLE_MAGIC_N;
-
- /* Initialize the cell array */
- hash_table_clear(table);
-
- return(table);
-}
-
-/*****************************************************************
-Frees a hash table. */
-static
-void
-wdl_hash_table_free(
-/*================*/
- hash_table_t* table) /* in, own: hash table */
-{
- ut_a(table != NULL);
- ut_a(table->mutexes == NULL);
-
- free(table->array);
- free(table);
-}
-
-/***********************************************************************
-Function for calculating the count of imports given the base of the IAT. */
-static
-ulint
-wdl_import_count(
-/*=============*/
- /* out: number of imports */
- PCImgThunkData pitd_base) /* in: base of the IAT */
-{
- ulint ret = 0;
- PCImgThunkData pitd = pitd_base;
-
- while (pitd->u1.Function) {
- pitd++;
- ret++;
- }
-
- return(ret);
-}
-
-/***********************************************************************
-Read Mapfile to a hashtable for faster access */
-static
-ibool
-wdl_load_mapfile(
-/*=============*/
- /* out: TRUE if the mapfile is
- loaded successfully. */
- const char* filename) /* in: name of the mapfile. */
-{
- FILE* fp;
- const size_t nSize = 256;
- char tmp_buf[nSize];
- char* func_name;
- char* func_addr;
- ulint load_addr = 0;
- ibool valid_load_addr = FALSE;
-#ifdef _WIN64
- const char* tmp_string = " Preferred load address is %16llx";
-#else
- const char* tmp_string = " Preferred load address is %08x";
-#endif
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
-
- return(FALSE);
- }
-
- /* Check whether to create the hashtable */
- if (m_htbl == NULL) {
-
- m_htbl = wdl_hash_create(MAP_HASH_CELLS_NUM);
-
- if (m_htbl == NULL) {
-
- fclose(fp);
- return(FALSE);
- }
- }
-
- /* Search start of symbol list and get the preferred load address */
- while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
-
- if (sscanf(tmp_buf, tmp_string, &load_addr) == 1) {
-
- valid_load_addr = TRUE;
- }
-
- if (strstr(tmp_buf, "Rva+Base") != NULL) {
-
- break;
- }
- }
-
- if (valid_load_addr == FALSE) {
-
- /* No "Preferred load address", the map file is wrong. */
- fclose(fp);
- return(FALSE);
- }
-
- /* Read symbol list */
- while (fgets(tmp_buf, sizeof(tmp_buf), fp))
- {
- map_hash_chain_t* map_cell;
- ulint map_fold;
-
- if (*tmp_buf == 0) {
-
- continue;
- }
-
- func_name = strtok(tmp_buf, " ");
- func_name = strtok(NULL, " ");
- func_addr = strtok(NULL, " ");
-
- if (func_name && func_addr) {
-
- ut_snprintf(tmp_buf, nSize, "0x%s", func_addr);
- if (*func_name == '_') {
-
- func_name++;
- }
-
- map_cell = (map_hash_chain_t*)
- malloc(sizeof(map_hash_chain_t));
- if (map_cell == NULL) {
- return(FALSE);
- }
-
- /* Chain all cells together */
- map_cell->chain = chain_header;
- chain_header = map_cell;
-
- map_cell->symbol = strdup(func_name);
- map_cell->value = (ulint) strtoull(tmp_buf, NULL, 0)
- - load_addr;
- map_fold = ut_fold_string(map_cell->symbol);
-
- HASH_INSERT(map_hash_chain_t,
- next,
- m_htbl,
- map_fold,
- map_cell);
- }
- }
-
- fclose(fp);
-
- return(TRUE);
-}
-
-/*****************************************************************
-Cleanup.during DLL unload */
-static
-void
-wdl_cleanup(void)
-/*=============*/
-{
- while (chain_header != NULL) {
- map_hash_chain_t* tmp;
-
- tmp = chain_header->chain;
- free(chain_header->symbol);
- free(chain_header);
- chain_header = tmp;
- }
-
- if (m_htbl != NULL) {
-
- wdl_hash_table_free(m_htbl);
- }
-}
-
-/***********************************************************************
-Load the mapfile mysqld.map. */
-static
-HMODULE
-wdl_get_mysqld_mapfile(void)
-/*========================*/
- /* out: the module handle */
-{
- char file_name[MAX_PATH];
- char* ext;
- ulint err;
-
- if (my_hmod == 0) {
-
- size_t nSize = MAX_PATH - strlen(".map") -1;
-
- /* First find out the name of current executable */
- my_hmod = GetModuleHandle(NULL);
- if (my_hmod == 0) {
-
- return(my_hmod);
- }
-
- err = GetModuleFileName(my_hmod, file_name, nSize);
- if (err == 0) {
-
- my_hmod = 0;
- return(my_hmod);
- }
-
- ext = strrchr(file_name, '.');
- if (ext != NULL) {
-
- *ext = 0;
- strcat(file_name, ".map");
-
- err = wdl_load_mapfile(file_name);
- if (err == 0) {
-
- my_hmod = 0;
- }
- } else {
-
- my_hmod = 0;
- }
- }
-
- return(my_hmod);
-}
-
-/***********************************************************************
-Retrieves the address of an exported function. It follows the convention
-of GetProcAddress(). */
-static
-FARPROC
-wdl_get_procaddr_from_map(
-/*======================*/
- /* out: address of exported
- function. */
- HANDLE m_handle, /* in: module handle */
- const char* import_proc) /* in: procedure name */
-{
- map_hash_chain_t* hash_chain;
- ulint map_fold;
-
- map_fold = ut_fold_string(import_proc);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
- if (hash_chain == NULL) {
-
-#ifdef _WIN64
- /* On Win64, the leading '_' may not be taken out. In this
- case, search again without the leading '_'. */
- if (*import_proc == '_') {
-
- import_proc++;
- }
-
- map_fold = ut_fold_string(import_proc);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
- if (hash_chain == NULL) {
-#endif
- if (wdl_init == TRUE) {
-
- sql_print_error(
- "InnoDB: the procedure pointer of %s"
- " is not found.",
- import_proc);
- }
-
- return(0);
-#ifdef _WIN64
- }
-#endif
- }
-
- return((FARPROC) ((ulint) m_handle + hash_chain->value));
-}
-
-/***********************************************************************
-Retrieves the address of an exported variable.
-Note: It does not follow the Windows call convention FARPROC. */
-static
-void*
-wdl_get_varaddr_from_map(
-/*=====================*/
- /* out: address of exported
- variable. */
- HANDLE m_handle, /* in: module handle */
- const char* import_variable) /* in: variable name */
-{
- map_hash_chain_t* hash_chain;
- ulint map_fold;
-
- map_fold = ut_fold_string(import_variable);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
- if (hash_chain == NULL) {
-
-#ifdef _WIN64
- /* On Win64, the leading '_' may not be taken out. In this
- case, search again without the leading '_'. */
- if (*import_variable == '_') {
-
- import_variable++;
- }
-
- map_fold = ut_fold_string(import_variable);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
- if (hash_chain == NULL) {
-#endif
- if (wdl_init == TRUE) {
-
- sql_print_error(
- "InnoDB: the variable address of %s"
- " is not found.",
- import_variable);
- }
-
- return(0);
-#ifdef _WIN64
- }
-#endif
- }
-
- return((void*) ((ulint) m_handle + hash_chain->value));
-}
-
-/***********************************************************************
-Bind all unresolved external variables from the MySQL executable. */
-static
-bool
-wdl_get_external_variables(void)
-/*============================*/
- /* out: TRUE if successful */
-{
- HMODULE hmod = wdl_get_mysqld_mapfile();
-
- if (hmod == 0) {
-
- return(FALSE);
- }
-
-#define GET_SYM(sym, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym); \
- if (var == NULL) return(FALSE)
-#ifdef _WIN64
-#define GET_SYM2(sym1, sym2, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym1); \
- if (var == NULL) return(FALSE)
-#else
-#define GET_SYM2(sym1, sym2, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym2); \
- if (var == NULL) return(FALSE)
-#endif // (_WIN64)
-#define GET_C_SYM(sym, type) GET_SYM(#sym, wdl_##sym, type)
-#define GET_PROC_ADDR(sym) \
- wdl##sym = (pfn##sym) wdl_get_procaddr_from_map(hmod, #sym)
-
- GET_C_SYM(my_charset_bin, CHARSET_INFO);
- GET_C_SYM(my_charset_latin1, CHARSET_INFO);
- GET_C_SYM(my_charset_filename, CHARSET_INFO);
- GET_C_SYM(default_charset_info, CHARSET_INFO*);
- GET_C_SYM(all_charsets, CHARSET_INFO*);
- GET_C_SYM(my_umask, int);
-
- GET_SYM("?global_system_variables@@3Usystem_variables@@A",
- wdl_global_system_variables, struct system_variables);
- GET_SYM("?mysql_real_data_home@@3PADA",
- wdl_mysql_real_data_home, char);
- GET_SYM("?reg_ext@@3PADA", wdl_reg_ext, char);
- GET_SYM("?LOCK_thread_count@@3U_RTL_CRITICAL_SECTION@@A",
- wdl_LOCK_thread_count, pthread_mutex_t);
- GET_SYM("?key_map_full@@3V?$Bitmap@$0EA@@@A",
- wdl_key_map_full, key_map);
- GET_SYM("?mysql_tmpdir_list@@3Ust_my_tmpdir@@A",
- wdl_mysql_tmpdir_list, MY_TMPDIR);
- GET_SYM("?mysqld_embedded@@3_NA",
- wdl_mysqld_embedded, bool);
- GET_SYM("?lower_case_table_names@@3IA",
- wdl_lower_case_table_names, uint);
- GET_SYM("?specialflag@@3KA", wdl_specialflag, ulong);
-
- GET_SYM2("?system_charset_info@@3PEAUcharset_info_st@@EA",
- "?system_charset_info@@3PAUcharset_info_st@@A",
- wdl_system_charset_info, CHARSET_INFO*);
- GET_SYM2("?mysql_data_home@@3PEADEA",
- "?mysql_data_home@@3PADA",
- wdl_mysql_data_home, char*);
- GET_SYM2("?tx_isolation_names@@3PAPEBDA",
- "?tx_isolation_names@@3PAPBDA",
- wdl_tx_isolation_names, char*);
- GET_SYM2("?binlog_format_names@@3PAPEBDA",
- "?binlog_format_names@@3PAPBDA",
- wdl_binlog_format_names, char*);
-
- /* It is fine if builtin_innobase_plugin is not available. */
- builtin_innobase_plugin_ptr = (struct st_mysql_plugin*)
- wdl_get_varaddr_from_map(
- hmod,
- "?builtin_innobase_plugin@@3PAUst_mysql_plugin@@A");
-
-#ifndef DBUG_OFF
- GET_PROC_ADDR(_db_enter_);
- GET_PROC_ADDR(_db_return_);
- GET_PROC_ADDR(_db_pargs_);
- GET_PROC_ADDR(_db_doprnt_);
- GET_PROC_ADDR(_db_dump_);
-
- /* If any of the dbug functions is not available, just make them
- all invalid. This is the case when working with a non-debug
- version of the server. */
- if (wdl_db_enter_ == NULL || wdl_db_return_ == NULL
- || wdl_db_pargs_ == NULL || wdl_db_doprnt_ == NULL
- || wdl_db_dump_ == NULL) {
-
- wdl_db_enter_ = NULL;
- wdl_db_return_ = NULL;
- wdl_db_pargs_ = NULL;
- wdl_db_doprnt_ = NULL;
- wdl_db_dump_ = NULL;
- }
-#endif /* !DBUG_OFF */
-
- wdl_init = TRUE;
- return(TRUE);
-
-#undef GET_SYM
-#undef GET_SYM2
-#undef GET_C_SYM
-#undef GET_PROC_ADDR
-}
-
-/***********************************************************************
-The DLL Delayed Loading Helper Function for resolving externals.
-
-The function may fail due to one of the three reasons:
-
-* Invalid parameter, which happens if the attributes in pidd aren't
- specified correctly.
-* Failed to load the map file mysqld.map.
-* Failed to find an external name in the map file mysqld.map.
-
-Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
-So, it has to follow Windows call convention. */
-extern "C"
-FARPROC WINAPI
-__delayLoadHelper2(
-/*===============*/
- /* out: the address of the imported
- function*/
- PCImgDelayDescr pidd, /* in: a const pointer to a
- ImgDelayDescr, see delayimp.h. */
- FARPROC* iat_entry) /* in/out: A pointer to the slot in
- the delay load import address table
- to be updated with the address of the
- imported function. */
-{
- ulint iIAT, iINT;
- HMODULE hmod;
- PCImgThunkData pitd;
- FARPROC fun = NULL;
-
- /* Set up data used for the hook procs */
- InternalImgDelayDescr idd = {
- pidd->grAttrs,
- PFromRva<LPCSTR>(pidd->rvaDLLName),
- PFromRva<HMODULE*>(pidd->rvaHmod),
- PFromRva<PImgThunkData>(pidd->rvaIAT),
- PFromRva<PCImgThunkData>(pidd->rvaINT),
- PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
- PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
- pidd->dwTimeStamp
- };
-
- DelayLoadInfo dli = {
- sizeof(DelayLoadInfo),
- pidd,
- iat_entry,
- idd.szName,
- {0},
- 0,
- 0,
- 0
- };
-
- /* Check the Delay Load Attributes, log an error of invalid
- parameter, which happens if the attributes in pidd are not
- specified correctly. */
- if ((idd.grAttrs & dlattrRva) == 0) {
-
- sql_print_error("InnoDB: invalid parameter for delay loader.");
- return(0);
- }
-
- hmod = *idd.phmod;
-
- /* Calculate the index for the IAT entry in the import address table.
- The INT entries are ordered the same as the IAT entries so the
- calculation can be done on the IAT side. */
- iIAT = (PCImgThunkData) iat_entry - idd.pIAT;
- iINT = iIAT;
-
- pitd = &(idd.pINT[iINT]);
-
- dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);
-
- if (dli.dlp.fImportByName) {
-
- dli.dlp.szProcName = (LPCSTR) (PFromRva<PIMAGE_IMPORT_BY_NAME>
- ((RVA) ((UINT_PTR) pitd->u1.AddressOfData))->Name);
- } else {
-
- dli.dlp.dwOrdinal = (ulint) IMAGE_ORDINAL(pitd->u1.Ordinal);
- }
-
- /* Now, load the mapfile, if it has not been done yet */
- if (hmod == 0) {
-
- hmod = wdl_get_mysqld_mapfile();
- }
-
- if (hmod == 0) {
- /* LoadLibrary failed. */
- PDelayLoadInfo rgpdli[1] = {&dli};
-
- dli.dwLastError = ::GetLastError();
-
- sql_print_error(
- "InnoDB: failed to load mysqld.map with error %d.",
- dli.dwLastError);
-
- return(0);
- }
-
- /* Store the library handle. */
- idd.phmod = &hmod;
-
- /* Go for the procedure now. */
- dli.hmodCur = hmod;
-
- if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
-
- /* Bound imports exist, check the timestamp from the target
- image */
- PIMAGE_NT_HEADERS pinh;
-
- pinh = (PIMAGE_NT_HEADERS) ((byte*) hmod
- + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
-
- if (pinh->Signature == IMAGE_NT_SIGNATURE
- && pinh->FileHeader.TimeDateStamp == idd.dwTimeStamp
- && (DWORD) hmod == pinh->OptionalHeader.ImageBase) {
-
- /* We have a decent address in the bound IAT. */
- fun = (FARPROC) (UINT_PTR)
- idd.pBoundIAT[iIAT].u1.Function;
-
- if (fun) {
-
- *iat_entry = fun;
- return(fun);
- }
- }
- }
-
- fun = wdl_get_procaddr_from_map(hmod, dli.dlp.szProcName);
-
- if (fun == 0) {
-
- return(0);
- }
-
- *iat_entry = fun;
- return(fun);
-}
-
-/***********************************************************************
-Unload a DLL that was delay loaded. This function is called by run-time. */
-extern "C"
-BOOL WINAPI
-__FUnloadDelayLoadedDLL2(
-/*=====================*/
- /* out: TRUE is returned if the DLL is found
- and the IAT matches the original one. */
- LPCSTR module_name) /* in: DLL name */
-{
- return(TRUE);
-}
-
-/******************************************************************
-Load all imports from a DLL that was specified with the /delayload linker
-option.
-Note: this function is called by run-time. So, it has to follow Windows call
-convention. */
-extern "C"
-HRESULT WINAPI
-__HrLoadAllImportsForDll(
-/*=====================*/
- /* out: S_OK if the DLL matches, otherwise
- ERROR_MOD_NOT_FOUND is returned. */
- LPCSTR module_name) /* in: DLL name */
-{
- PIMAGE_NT_HEADERS img;
- PCImgDelayDescr pidd;
- IMAGE_DATA_DIRECTORY* image_data;
- LPCSTR current_module;
- HRESULT ret = ERROR_MOD_NOT_FOUND;
- HMODULE hmod = (HMODULE) &__ImageBase;
-
- img = (PIMAGE_NT_HEADERS) ((byte*) hmod
- + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
- image_data =
- &img->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
-
- /* Scan the delay load IAT/INT for the DLL */
- if (image_data->Size) {
-
- pidd = PFromRva<PCImgDelayDescr>(image_data->VirtualAddress);
-
- /* Check all of the listed DLLs we want to load. */
- while (pidd->rvaDLLName) {
-
- current_module = PFromRva<LPCSTR>(pidd->rvaDLLName);
-
- if (stricmp(module_name, current_module) == 0) {
-
- /* Found it, break out with pidd and
- current_module set appropriately */
- break;
- }
-
- /* To the next delay import descriptor */
- pidd++;
- }
-
- if (pidd->rvaDLLName) {
-
- /* Found a matching DLL, now process it. */
- FARPROC* iat_entry;
- size_t count;
-
- iat_entry = PFromRva<FARPROC*>(pidd->rvaIAT);
- count = wdl_import_count((PCImgThunkData) iat_entry);
-
- /* now load all the imports from the DLL */
- while (count > 0) {
-
- /* No need to check the return value */
- __delayLoadHelper2(pidd, iat_entry);
- iat_entry++;
- count--;
- }
-
- ret = S_OK;
- }
- }
-
- return ret;
-}
-
-/******************************************************************
-The main function of a DLL */
-BOOL
-WINAPI
-DllMain(
-/*====*/
- /* out: TRUE if the call succeeds */
- HINSTANCE hinstDLL, /* in: handle to the DLL module */
- DWORD fdwReason, /* Reason code that indicates why the
- DLL entry-point function is being
- called.*/
- LPVOID lpvReserved) /* in: additional parameter based on
- fdwReason */
-{
- BOOL success = TRUE;
-
- switch (fdwReason) {
-
- case DLL_PROCESS_ATTACH:
- success = wdl_get_external_variables();
- break;
-
- case DLL_PROCESS_DETACH:
- wdl_cleanup();
- break;
- }
-
- return(success);
-}
-
-#ifndef DBUG_OFF
-/******************************************************************
-Process entry point to user function. It makes the call to _db_enter_
-in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
-extern "C" UNIV_INTERN
-void
-_db_enter_(
- const char* _func_, /* in: current function name */
- const char* _file_, /* in: current file name */
- uint _line_, /* in: current source line number */
- const char** _sfunc_, /* out: previous _func_ */
- const char** _sfile_, /* out: previous _file_ */
- uint* _slevel_, /* out: previous nesting level */
- char*** _sframep_) /* out: previous frame pointer */
-{
- if (wdl_db_enter_ != NULL) {
-
- wdl_db_enter_(_func_, _file_, _line_, _sfunc_, _sfile_,
- _slevel_, _sframep_);
- }
-}
-
-/******************************************************************
-Process exit from user function. It makes the call to _db_return_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_return_(
- uint _line_, /* in: current source line number */
- const char** _sfunc_, /* out: previous _func_ */
- const char** _sfile_, /* out: previous _file_ */
- uint* _slevel_) /* out: previous level */
-{
- if (wdl_db_return_ != NULL) {
-
- wdl_db_return_(_line_, _sfunc_, _sfile_, _slevel_);
- }
-}
-
-/******************************************************************
-Log arguments for subsequent use. It makes the call to _db_pargs_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_pargs_(
- uint _line_, /* in: current source line number */
- const char* keyword) /* in: keyword for current macro */
-{
- if (wdl_db_pargs_ != NULL) {
-
- wdl_db_pargs_(_line_, keyword);
- }
-}
-
-/******************************************************************
-Handle print of debug lines. It saves the text into a buffer first,
-then makes the call to _db_doprnt_() in the server. The text is
-truncated to the size of buffer. */
-extern "C" UNIV_INTERN
-void
-_db_doprnt_(
- const char* format, /* in: the format string */
- ...) /* in: list of arguments */
-{
- va_list argp;
- char buffer[512];
-
- if (wdl_db_doprnt_ != NULL) {
-
- va_start(argp, format);
- /* it is ok to ignore the trunction. */
- _vsnprintf(buffer, sizeof(buffer), format, argp);
- wdl_db_doprnt_(buffer);
- va_end(argp);
- }
-}
-
-/******************************************************************
-Dump a string in hex. It makes the call to _db_dump_() in the server. */
-extern "C" UNIV_INTERN
-void
-_db_dump_(
- uint _line_, /* in: current source line
- number */
- const char* keyword, /* in: keyword list */
- const unsigned char* memory, /* in: memory to dump */
- size_t length) /* in: bytes to dump */
-{
- if (wdl_db_dump_ != NULL) {
-
- wdl_db_dump_(_line_, keyword, memory, length);
- }
-}
-
-#endif /* !DBUG_OFF */
-#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.c b/storage/xtradb/ibuf/ibuf0ibuf.c
index 5aacd9ae717..94f3751dd04 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.c
+++ b/storage/xtradb/ibuf/ibuf0ibuf.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file ibuf/ibuf0ibuf.c
Insert buffer
Created 7/19/1997 Heikki Tuuri
@@ -24,10 +25,20 @@ Created 7/19/1997 Heikki Tuuri
#include "ibuf0ibuf.h"
+/** Number of bits describing a single page */
+#define IBUF_BITS_PER_PAGE 4
+#if IBUF_BITS_PER_PAGE % 2
+# error "IBUF_BITS_PER_PAGE must be an even number!"
+#endif
+/** The start address for an insert buffer bitmap page bitmap */
+#define IBUF_BITMAP PAGE_DATA
+
#ifdef UNIV_NONINL
#include "ibuf0ibuf.ic"
#endif
+#ifndef UNIV_HOTBACKUP
+
#include "buf0buf.h"
#include "buf0rea.h"
#include "fsp0fsp.h"
@@ -150,10 +161,10 @@ level 2 i/o. However, if an OS thread does the i/o handling for itself, i.e.,
it uses synchronous aio, it can access any pages, as long as it obeys the
access order rules. */
-/* Buffer pool size per the maximum insert buffer size */
+/** Buffer pool size per the maximum insert buffer size */
#define IBUF_POOL_SIZE_PER_MAX_SIZE 2
-/* Table name for the insert buffer. */
+/** Table name for the insert buffer. */
#define IBUF_TABLE_NAME "SYS_IBUF_TABLE"
/** Operations that can currently be buffered. */
@@ -162,24 +173,26 @@ UNIV_INTERN ibuf_use_t ibuf_use = IBUF_USE_INSERT;
/** The insert buffer control structure */
UNIV_INTERN ibuf_t* ibuf = NULL;
+/** Counter for ibuf_should_try() */
UNIV_INTERN ulint ibuf_flush_count = 0;
#ifdef UNIV_IBUF_COUNT_DEBUG
-/* Dimensions for the ibuf_count array */
+/** Number of tablespaces in the ibuf_counts array */
#define IBUF_COUNT_N_SPACES 4
+/** Number of pages within each tablespace in the ibuf_counts array */
#define IBUF_COUNT_N_PAGES 130000
-/* Buffered entry counts for file pages, used in debugging */
+/** Buffered entry counts for file pages, used in debugging */
static ulint ibuf_counts[IBUF_COUNT_N_SPACES][IBUF_COUNT_N_PAGES];
-/**********************************************************************
+/******************************************************************//**
Checks that the indexes to ibuf_counts[][] are within limits. */
UNIV_INLINE
void
ibuf_count_check(
/*=============*/
- ulint space_id, /* in: space identifier */
- ulint page_no) /* in: page number */
+ ulint space_id, /*!< in: space identifier */
+ ulint page_no) /*!< in: page number */
{
if (space_id < IBUF_COUNT_N_SPACES && page_no < IBUF_COUNT_N_PAGES) {
return;
@@ -196,52 +209,52 @@ ibuf_count_check(
}
#endif
-/* The start address for an insert buffer bitmap page bitmap */
-#define IBUF_BITMAP PAGE_DATA
-
-/* Offsets in bits for the bits describing a single page in the bitmap */
-#define IBUF_BITMAP_FREE 0
-#define IBUF_BITMAP_BUFFERED 2
-#define IBUF_BITMAP_IBUF 3 /* TRUE if page is a part of the ibuf
- tree, excluding the root page, or is
- in the free list of the ibuf */
-
-/* Number of bits describing a single page */
-#define IBUF_BITS_PER_PAGE 4
-#if IBUF_BITS_PER_PAGE % 2
-# error "IBUF_BITS_PER_PAGE must be an even number!"
-#endif
-
-/* The mutex used to block pessimistic inserts to ibuf trees */
+/** @name Offsets to the per-page bits in the insert buffer bitmap */
+/* @{ */
+#define IBUF_BITMAP_FREE 0 /*!< Bits indicating the
+ amount of free space */
+#define IBUF_BITMAP_BUFFERED 2 /*!< TRUE if there are buffered
+ changes for the page */
+#define IBUF_BITMAP_IBUF 3 /*!< TRUE if page is a part of
+ the ibuf tree, excluding the
+ root page, or is in the free
+ list of the ibuf */
+/* @} */
+
+/** The mutex used to block pessimistic inserts to ibuf trees */
static mutex_t ibuf_pessimistic_insert_mutex;
-/* The mutex protecting the insert buffer structs */
+/** The mutex protecting the insert buffer structs */
static mutex_t ibuf_mutex;
-/* The mutex protecting the insert buffer bitmaps */
+/** The mutex protecting the insert buffer bitmaps */
static mutex_t ibuf_bitmap_mutex;
-/* The area in pages from which contract looks for page numbers for merge */
+/** The area in pages from which contract looks for page numbers for merge */
#define IBUF_MERGE_AREA 8
-/* Inside the merge area, pages which have at most 1 per this number less
+/** Inside the merge area, pages which have at most 1 per this number less
buffered entries compared to maximum volume that can buffered for a single
page are merged along with the page whose buffer became full */
#define IBUF_MERGE_THRESHOLD 4
-/* In ibuf_contract at most this number of pages is read to memory in one
+/** In ibuf_contract at most this number of pages is read to memory in one
batch, in order to merge the entries for them in the insert buffer */
#define IBUF_MAX_N_PAGES_MERGED IBUF_MERGE_AREA
-/* If the combined size of the ibuf trees exceeds ibuf->max_size by this
+/** If the combined size of the ibuf trees exceeds ibuf->max_size by this
many pages, we start to contract it in connection to inserts there, using
non-synchronous contract */
#define IBUF_CONTRACT_ON_INSERT_NON_SYNC 0
-/* Same as above, but use synchronous contract */
+/** If the combined size of the ibuf trees exceeds ibuf->max_size by this
+many pages, we start to contract it in connection to inserts there, using
+synchronous contract */
#define IBUF_CONTRACT_ON_INSERT_SYNC 5
-/* Same as above, but no insert is done, only contract is called */
+/** If the combined size of the ibuf trees exceeds ibuf->max_size by
+this many pages, we start to contract it synchronous contract, but do
+not insert */
#define IBUF_CONTRACT_DO_NOT_INSERT 10
/* TODO: how to cope with drop table if there are records in the insert
@@ -250,7 +263,7 @@ because ibuf merge is done to a page when it is read in, and it is
still physically like the index page even if the index would have been
dropped! So, there seems to be no problem. */
-/**********************************************************************
+/******************************************************************//**
Sets the flag in the current OS thread local storage denoting that it is
inside an insert buffer routine. */
UNIV_INLINE
@@ -267,7 +280,7 @@ ibuf_enter(void)
*ptr = TRUE;
}
-/**********************************************************************
+/******************************************************************//**
Sets the flag in the current OS thread local storage denoting that it is
exiting an insert buffer routine. */
UNIV_INLINE
@@ -284,27 +297,29 @@ ibuf_exit(void)
*ptr = FALSE;
}
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if the current OS thread is performing an insert buffer
-routine. */
+routine.
+
+For instance, a read-ahead of non-ibuf pages is forbidden by threads
+that are executing an insert buffer routine.
+@return TRUE if inside an insert buffer routine */
UNIV_INTERN
ibool
ibuf_inside(void)
/*=============*/
- /* out: TRUE if inside an insert buffer routine: for instance,
- a read-ahead of non-ibuf pages is then forbidden */
{
return(*thr_local_get_in_ibuf_field());
}
-/**********************************************************************
-Gets the ibuf header page and x-latches it. */
+/******************************************************************//**
+Gets the ibuf header page and x-latches it.
+@return insert buffer header page */
static
page_t*
ibuf_header_page_get(
/*=================*/
- /* out: insert buffer header page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -317,14 +332,14 @@ ibuf_header_page_get(
return(buf_block_get_frame(block));
}
-/**********************************************************************
-Gets the root page and x-latches it. */
+/******************************************************************//**
+Gets the root page and x-latches it.
+@return insert buffer tree root page */
static
page_t*
ibuf_tree_root_get(
/*===============*/
- /* out: insert buffer tree root page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -341,31 +356,31 @@ ibuf_tree_root_get(
}
#ifdef UNIV_IBUF_COUNT_DEBUG
-/**********************************************************************
-Gets the ibuf count for a given page. */
+/******************************************************************//**
+Gets the ibuf count for a given page.
+@return number of entries in the insert buffer currently buffered for
+this page */
UNIV_INTERN
ulint
ibuf_count_get(
/*===========*/
- /* out: number of entries in the insert buffer
- currently buffered for this page */
- ulint space, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
ibuf_count_check(space, page_no);
return(ibuf_counts[space][page_no]);
}
-/**********************************************************************
+/******************************************************************//**
Sets the ibuf count for a given page. */
static
void
ibuf_count_set(
/*===========*/
- ulint space, /* in: space id */
- ulint page_no,/* in: page number */
- ulint val) /* in: value to set */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: page number */
+ ulint val) /*!< in: value to set */
{
ibuf_count_check(space, page_no);
ut_a(val < UNIV_PAGE_SIZE);
@@ -374,15 +389,36 @@ ibuf_count_set(
}
#endif
-/**********************************************************************
+/******************************************************************//**
+Closes insert buffer and frees the data structures. */
+UNIV_INTERN
+void
+ibuf_close(void)
+/*============*/
+{
+ mutex_free(&ibuf_pessimistic_insert_mutex);
+ memset(&ibuf_pessimistic_insert_mutex,
+ 0x0, sizeof(ibuf_pessimistic_insert_mutex));
+
+ mutex_free(&ibuf_mutex);
+ memset(&ibuf_mutex, 0x0, sizeof(ibuf_mutex));
+
+ mutex_free(&ibuf_bitmap_mutex);
+ memset(&ibuf_bitmap_mutex, 0x0, sizeof(ibuf_mutex));
+
+ mem_free(ibuf);
+ ibuf = NULL;
+}
+
+/******************************************************************//**
Updates the size information of the ibuf, assuming the segment size has not
changed. */
static
void
ibuf_size_update(
/*=============*/
- const page_t* root, /* in: ibuf tree root */
- mtr_t* mtr) /* in: mtr */
+ const page_t* root, /*!< in: ibuf tree root */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mutex_own(&ibuf_mutex));
@@ -397,7 +433,7 @@ ibuf_size_update(
ibuf->empty = page_get_n_recs(root) == 0;
}
-/**********************************************************************
+/******************************************************************//**
Creates the insert buffer data structure at a database startup and initializes
the data structures for the insert buffer. */
UNIV_INTERN
@@ -495,15 +531,15 @@ ibuf_init_at_db_start(void)
ibuf->index = dict_table_get_first_index(table);
}
-
-/*************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
Initializes an ibuf bitmap page. */
UNIV_INTERN
void
ibuf_bitmap_page_init(
/*==================*/
- buf_block_t* block, /* in: bitmap page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: bitmap page */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
ulint byte_offset;
@@ -527,20 +563,22 @@ ibuf_bitmap_page_init(
/* The remaining area (up to the page trailer) is uninitialized. */
+#ifndef UNIV_HOTBACKUP
mlog_write_initial_log_record(page, MLOG_IBUF_BITMAP_INIT, mtr);
+#endif /* !UNIV_HOTBACKUP */
}
-/*************************************************************************
-Parses a redo log record of an ibuf bitmap page init. */
+/*********************************************************************//**
+Parses a redo log record of an ibuf bitmap page init.
+@return end of log record or NULL */
UNIV_INTERN
byte*
ibuf_parse_bitmap_init(
/*===================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- buf_block_t* block, /* in: block or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ buf_block_t* block, /*!< in: block or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(ptr && end_ptr);
@@ -550,22 +588,22 @@ ibuf_parse_bitmap_init(
return(ptr);
}
-
-/************************************************************************
-Gets the desired bits for a given page from a bitmap page. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Gets the desired bits for a given page from a bitmap page.
+@return value of bits */
UNIV_INLINE
ulint
ibuf_bitmap_page_get_bits(
/*======================*/
- /* out: value of bits */
- const page_t* page, /* in: bitmap page */
- ulint page_no,/* in: page whose bits to get */
- ulint zip_size,/* in: compressed page size in bytes;
+ const page_t* page, /*!< in: bitmap page */
+ ulint page_no,/*!< in: page whose bits to get */
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint bit, /* in: IBUF_BITMAP_FREE,
+ ulint bit, /*!< in: IBUF_BITMAP_FREE,
IBUF_BITMAP_BUFFERED, ... */
mtr_t* mtr __attribute__((unused)))
- /* in: mtr containing an
+ /*!< in: mtr containing an
x-latch to the bitmap page */
{
ulint byte_offset;
@@ -606,19 +644,19 @@ ibuf_bitmap_page_get_bits(
return(value);
}
-/************************************************************************
+/********************************************************************//**
Sets the desired bit for a given page in a bitmap page. */
static
void
ibuf_bitmap_page_set_bits(
/*======================*/
- page_t* page, /* in: bitmap page */
- ulint page_no,/* in: page whose bits to set */
- ulint zip_size,/* in: compressed page size in bytes;
+ page_t* page, /*!< in: bitmap page */
+ ulint page_no,/*!< in: page whose bits to set */
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
- ulint val, /* in: value to set */
- mtr_t* mtr) /* in: mtr containing an x-latch to the bitmap page */
+ ulint bit, /*!< in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
+ ulint val, /*!< in: value to set */
+ mtr_t* mtr) /*!< in: mtr containing an x-latch to the bitmap page */
{
ulint byte_offset;
ulint bit_offset;
@@ -665,17 +703,16 @@ ibuf_bitmap_page_set_bits(
MLOG_1BYTE, mtr);
}
-/************************************************************************
-Calculates the bitmap page number for a given page number. */
+/********************************************************************//**
+Calculates the bitmap page number for a given page number.
+@return the bitmap page number where the file page is mapped */
UNIV_INLINE
ulint
ibuf_bitmap_page_no_calc(
/*=====================*/
- /* out: the bitmap page number where
- the file page is mapped */
- ulint zip_size, /* in: compressed page size in bytes;
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no) /* in: tablespace page number */
+ ulint page_no) /*!< in: tablespace page number */
{
ut_ad(ut_is_2pow(zip_size));
@@ -688,22 +725,21 @@ ibuf_bitmap_page_no_calc(
}
}
-/************************************************************************
+/********************************************************************//**
Gets the ibuf bitmap page where the bits describing a given file page are
-stored. */
+stored.
+@return bitmap page where the file page is mapped, that is, the bitmap
+page containing the descriptor bits for the file page; the bitmap page
+is x-latched */
static
page_t*
ibuf_bitmap_get_map_page(
/*=====================*/
- /* out: bitmap page where the file page is mapped,
- that is, the bitmap page containing the descriptor
- bits for the file page; the bitmap page is
- x-latched */
- ulint space, /* in: space id of the file page */
- ulint page_no,/* in: page number of the file page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint space, /*!< in: space id of the file page */
+ ulint page_no,/*!< in: page number of the file page */
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -715,7 +751,7 @@ ibuf_bitmap_get_map_page(
return(buf_block_get_frame(block));
}
-/****************************************************************************
+/************************************************************************//**
Sets the free bits of the page in the ibuf bitmap. This is done in a separate
mini-transaction, hence this operation does not restrict further work to only
ibuf bitmap operations, which would result if the latch to the bitmap page
@@ -724,13 +760,13 @@ UNIV_INLINE
void
ibuf_set_free_bits_low(
/*===================*/
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- const buf_block_t* block, /* in: index page; free bits are set if
+ const buf_block_t* block, /*!< in: index page; free bits are set if
the index is non-clustered and page
level is 0 */
- ulint val, /* in: value to set: < 4 */
- mtr_t* mtr) /* in/out: mtr */
+ ulint val, /*!< in: value to set: < 4 */
+ mtr_t* mtr) /*!< in/out: mtr */
{
page_t* bitmap_page;
ulint space;
@@ -758,7 +794,7 @@ ibuf_set_free_bits_low(
IBUF_BITMAP_FREE, val, mtr);
}
-/****************************************************************************
+/************************************************************************//**
Sets the free bit of the page in the ibuf bitmap. This is done in a separate
mini-transaction, hence this operation does not restrict further work to only
ibuf bitmap operations, which would result if the latch to the bitmap page
@@ -767,14 +803,14 @@ UNIV_INTERN
void
ibuf_set_free_bits_func(
/*====================*/
- buf_block_t* block, /* in: index page of a non-clustered index;
+ buf_block_t* block, /*!< in: index page of a non-clustered index;
free bit is reset if page level is 0 */
#ifdef UNIV_IBUF_DEBUG
- ulint max_val,/* in: ULINT_UNDEFINED or a maximum
+ ulint max_val,/*!< in: ULINT_UNDEFINED or a maximum
value which the bits must have before
setting; this is for debugging */
#endif /* UNIV_IBUF_DEBUG */
- ulint val) /* in: value to set: < 4 */
+ ulint val) /*!< in: value to set: < 4 */
{
mtr_t mtr;
page_t* page;
@@ -828,7 +864,7 @@ ibuf_set_free_bits_func(
mtr_commit(&mtr);
}
-/****************************************************************************
+/************************************************************************//**
Resets the free bits of the page in the ibuf bitmap. This is done in a
separate mini-transaction, hence this operation does not restrict
further work to only ibuf bitmap operations, which would result if the
@@ -841,14 +877,14 @@ UNIV_INTERN
void
ibuf_reset_free_bits(
/*=================*/
- buf_block_t* block) /* in: index page; free bits are set to 0
+ buf_block_t* block) /*!< in: index page; free bits are set to 0
if the index is a non-clustered
non-unique, and page level is 0 */
{
ibuf_set_free_bits(block, 0, ULINT_UNDEFINED);
}
-/**************************************************************************
+/**********************************************************************//**
Updates the free bits for an uncompressed page to reflect the present
state. Does this in the mtr given, which means that the latching
order rules virtually prevent any further operations for this OS
@@ -860,13 +896,13 @@ UNIV_INTERN
void
ibuf_update_free_bits_low(
/*======================*/
- const buf_block_t* block, /* in: index page */
- ulint max_ins_size, /* in: value of
+ const buf_block_t* block, /*!< in: index page */
+ ulint max_ins_size, /*!< in: value of
maximum insert size
with reorganize before
the latest operation
performed to the page */
- mtr_t* mtr) /* in/out: mtr */
+ mtr_t* mtr) /*!< in/out: mtr */
{
ulint before;
ulint after;
@@ -886,7 +922,7 @@ ibuf_update_free_bits_low(
}
}
-/**************************************************************************
+/**********************************************************************//**
Updates the free bits for a compressed page to reflect the present
state. Does this in the mtr given, which means that the latching
order rules virtually prevent any further operations for this OS
@@ -898,8 +934,8 @@ UNIV_INTERN
void
ibuf_update_free_bits_zip(
/*======================*/
- buf_block_t* block, /* in/out: index page */
- mtr_t* mtr) /* in/out: mtr */
+ buf_block_t* block, /*!< in/out: index page */
+ mtr_t* mtr) /*!< in/out: mtr */
{
page_t* bitmap_page;
ulint space;
@@ -931,7 +967,7 @@ ibuf_update_free_bits_zip(
IBUF_BITMAP_FREE, after, mtr);
}
-/**************************************************************************
+/**********************************************************************//**
Updates the free bits for the two pages to reflect the present state.
Does this in the mtr given, which means that the latching order rules
virtually prevent any further operations until mtr is committed.
@@ -942,11 +978,11 @@ UNIV_INTERN
void
ibuf_update_free_bits_for_two_pages_low(
/*====================================*/
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- buf_block_t* block1, /* in: index page */
- buf_block_t* block2, /* in: index page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block1, /*!< in: index page */
+ buf_block_t* block2, /*!< in: index page */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint state;
@@ -967,34 +1003,34 @@ ibuf_update_free_bits_for_two_pages_low(
mutex_exit(&ibuf_bitmap_mutex);
}
-/**************************************************************************
-Returns TRUE if the page is one of the fixed address ibuf pages. */
+/**********************************************************************//**
+Returns TRUE if the page is one of the fixed address ibuf pages.
+@return TRUE if a fixed address ibuf i/o page */
UNIV_INLINE
ibool
ibuf_fixed_addr_page(
/*=================*/
- /* out: TRUE if a fixed address ibuf i/o page */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no)/* in: page number */
+ ulint page_no)/*!< in: page number */
{
return((space == IBUF_SPACE_ID && page_no == IBUF_TREE_ROOT_PAGE_NO)
|| ibuf_bitmap_page(zip_size, page_no));
}
-/***************************************************************************
+/***********************************************************************//**
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
-Must not be called when recv_no_ibuf_operations==TRUE. */
+Must not be called when recv_no_ibuf_operations==TRUE.
+@return TRUE if level 2 or level 3 page */
UNIV_INTERN
ibool
ibuf_page(
/*======*/
- /* out: TRUE if level 2 or level 3 page */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number */
- mtr_t* mtr) /* in: mtr which will contain an x-latch to the
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number */
+ mtr_t* mtr) /*!< in: mtr which will contain an x-latch to the
bitmap page if the page is not one of the fixed
address ibuf pages, or NULL, in which case a new
transaction is created. */
@@ -1032,14 +1068,14 @@ ibuf_page(
return(ret);
}
-/************************************************************************
-Returns the page number field of an ibuf record. */
+/********************************************************************//**
+Returns the page number field of an ibuf record.
+@return page number */
static
ulint
ibuf_rec_get_page_no(
/*=================*/
- /* out: page number */
- const rec_t* rec) /* in: ibuf record */
+ const rec_t* rec) /*!< in: ibuf record */
{
const byte* field;
ulint len;
@@ -1066,15 +1102,15 @@ ibuf_rec_get_page_no(
return(mach_read_from_4(field));
}
-/************************************************************************
+/********************************************************************//**
Returns the space id field of an ibuf record. For < 4.1.x format records
-returns 0. */
+returns 0.
+@return space id */
static
ulint
ibuf_rec_get_space(
/*===============*/
- /* out: space id */
- const rec_t* rec) /* in: ibuf record */
+ const rec_t* rec) /*!< in: ibuf record */
{
const byte* field;
ulint len;
@@ -1100,16 +1136,16 @@ ibuf_rec_get_space(
return(0);
}
-/************************************************************************
+/********************************************************************//**
Creates a dummy index for inserting a record to a non-clustered index.
-*/
+
+@return dummy index */
static
dict_index_t*
ibuf_dummy_index_create(
/*====================*/
- /* out: dummy index */
- ulint n, /* in: number of fields */
- ibool comp) /* in: TRUE=use compact record format */
+ ulint n, /*!< in: number of fields */
+ ibool comp) /*!< in: TRUE=use compact record format */
{
dict_table_t* table;
dict_index_t* index;
@@ -1128,15 +1164,15 @@ ibuf_dummy_index_create(
return(index);
}
-/************************************************************************
+/********************************************************************//**
Add a column to the dummy index */
static
void
ibuf_dummy_index_add_col(
/*=====================*/
- dict_index_t* index, /* in: dummy index */
- const dtype_t* type, /* in: the data type of the column */
- ulint len) /* in: length of the column */
+ dict_index_t* index, /*!< in: dummy index */
+ const dtype_t* type, /*!< in: the data type of the column */
+ ulint len) /*!< in: length of the column */
{
ulint i = index->table->n_def;
dict_mem_table_add_col(index->table, NULL, NULL,
@@ -1146,14 +1182,13 @@ ibuf_dummy_index_add_col(
dict_index_add_col(index, index->table,
dict_table_get_nth_col(index->table, i), len);
}
-/************************************************************************
-Deallocates a dummy index for inserting a record to a non-clustered index.
-*/
+/********************************************************************//**
+Deallocates a dummy index for inserting a record to a non-clustered index. */
static
void
ibuf_dummy_index_free(
/*==================*/
- dict_index_t* index) /* in: dummy index */
+ dict_index_t* index) /*!< in, own: dummy index */
{
dict_table_t* table = index->table;
@@ -1161,22 +1196,21 @@ ibuf_dummy_index_free(
dict_mem_table_free(table);
}
-/*************************************************************************
+/*********************************************************************//**
Builds the entry to insert into a non-clustered index when we have the
-corresponding record in an ibuf index. */
+corresponding record in an ibuf index.
+
+NOTE that as we copy pointers to fields in ibuf_rec, the caller must
+hold a latch to the ibuf_rec page as long as the entry is used!
+
+@return own: entry to insert to a non-clustered index */
UNIV_INLINE
dtuple_t*
ibuf_build_entry_pre_4_1_x(
/*=======================*/
- /* out, own: entry to insert to
- a non-clustered index; NOTE that
- as we copy pointers to fields in
- ibuf_rec, the caller must hold a
- latch to the ibuf_rec page as long
- as the entry is used! */
- const rec_t* ibuf_rec, /* in: record in an insert buffer */
- mem_heap_t* heap, /* in: heap where built */
- dict_index_t** pindex) /* out, own: dummy index that
+ const rec_t* ibuf_rec, /*!< in: record in an insert buffer */
+ mem_heap_t* heap, /*!< in: heap where built */
+ dict_index_t** pindex) /*!< out, own: dummy index that
describes the entry */
{
ulint i;
@@ -1214,22 +1248,21 @@ ibuf_build_entry_pre_4_1_x(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Builds the entry to insert into a non-clustered index when we have the
-corresponding record in an ibuf index. */
+corresponding record in an ibuf index.
+
+NOTE that as we copy pointers to fields in ibuf_rec, the caller must
+hold a latch to the ibuf_rec page as long as the entry is used!
+
+@return own: entry to insert to a non-clustered index */
static
dtuple_t*
ibuf_build_entry_from_ibuf_rec(
/*===========================*/
- /* out, own: entry to insert to
- a non-clustered index; NOTE that
- as we copy pointers to fields in
- ibuf_rec, the caller must hold a
- latch to the ibuf_rec page as long
- as the entry is used! */
- const rec_t* ibuf_rec, /* in: record in an insert buffer */
- mem_heap_t* heap, /* in: heap where built */
- dict_index_t** pindex) /* out, own: dummy index that
+ const rec_t* ibuf_rec, /*!< in: record in an insert buffer */
+ mem_heap_t* heap, /*!< in: heap where built */
+ dict_index_t** pindex) /*!< out, own: dummy index that
describes the entry */
{
dtuple_t* tuple;
@@ -1300,17 +1333,16 @@ ibuf_build_entry_from_ibuf_rec(
return(tuple);
}
-/************************************************************************
+/********************************************************************//**
Returns the space taken by a stored non-clustered index entry if converted to
-an index record. */
+an index record.
+@return size of index record in bytes + an upper limit of the space
+taken in the page directory */
static
ulint
ibuf_rec_get_volume(
/*================*/
- /* out: size of index record in bytes
- + an upper limit of the space taken in the
- page directory */
- const rec_t* ibuf_rec)/* in: ibuf record */
+ const rec_t* ibuf_rec)/*!< in: ibuf record */
{
dtype_t dtype;
ibool new_format = FALSE;
@@ -1320,6 +1352,7 @@ ibuf_rec_get_volume(
const byte* data;
ulint len;
ulint i;
+ ulint comp;
ut_ad(ibuf_inside());
ut_ad(rec_get_n_fields_old(ibuf_rec) > 2);
@@ -1337,6 +1370,7 @@ ibuf_rec_get_volume(
types = rec_get_nth_field_old(ibuf_rec, 1, &len);
ut_ad(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE);
+ comp = 0;
} else {
/* >= 4.1.x format record */
@@ -1345,8 +1379,10 @@ ibuf_rec_get_volume(
types = rec_get_nth_field_old(ibuf_rec, 3, &len);
- ut_a(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE <= 1);
- if (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) {
+ comp = len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
+
+ ut_a(comp <= 1);
+ if (comp) {
/* compact record format */
ulint volume;
dict_index_t* dummy_index;
@@ -1380,7 +1416,7 @@ ibuf_rec_get_volume(
}
if (len == UNIV_SQL_NULL) {
- data_size += dtype_get_sql_null_size(&dtype);
+ data_size += dtype_get_sql_null_size(&dtype, comp);
} else {
data_size += len;
}
@@ -1390,23 +1426,24 @@ ibuf_rec_get_volume(
+ page_dir_calc_reserved_space(1));
}
-/*************************************************************************
+/*********************************************************************//**
Builds the tuple to insert to an ibuf tree when we have an entry for a
-non-clustered index. */
+non-clustered index.
+
+NOTE that the original entry must be kept because we copy pointers to
+its fields.
+
+@return own: entry to insert into an ibuf index tree */
static
dtuple_t*
ibuf_entry_build(
/*=============*/
- /* out, own: entry to insert into an ibuf
- index tree; NOTE that the original entry
- must be kept because we copy pointers to its
- fields */
- dict_index_t* index, /* in: non-clustered index */
- const dtuple_t* entry, /* in: entry for a non-clustered index */
- ulint space, /* in: space id */
- ulint page_no,/* in: index page number where entry should
+ dict_index_t* index, /*!< in: non-clustered index */
+ const dtuple_t* entry, /*!< in: entry for a non-clustered index */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: index page number where entry should
be inserted */
- mem_heap_t* heap) /* in: heap into which to build */
+ mem_heap_t* heap) /*!< in: heap into which to build */
{
dtuple_t* tuple;
dfield_t* field;
@@ -1530,17 +1567,17 @@ ibuf_entry_build(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Builds a search tuple used to search buffered inserts for an index page.
-This is for < 4.1.x format records */
+This is for < 4.1.x format records
+@return own: search tuple */
static
dtuple_t*
ibuf_search_tuple_build(
/*====================*/
- /* out, own: search tuple */
- ulint space, /* in: space id */
- ulint page_no,/* in: index page number */
- mem_heap_t* heap) /* in: heap into which to build */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: index page number */
+ mem_heap_t* heap) /*!< in: heap into which to build */
{
dtuple_t* tuple;
dfield_t* field;
@@ -1567,17 +1604,17 @@ ibuf_search_tuple_build(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Builds a search tuple used to search buffered inserts for an index page.
-This is for >= 4.1.x format records. */
+This is for >= 4.1.x format records.
+@return own: search tuple */
static
dtuple_t*
ibuf_new_search_tuple_build(
/*========================*/
- /* out, own: search tuple */
- ulint space, /* in: space id */
- ulint page_no,/* in: index page number */
- mem_heap_t* heap) /* in: heap into which to build */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: index page number */
+ mem_heap_t* heap) /*!< in: heap into which to build */
{
dtuple_t* tuple;
dfield_t* field;
@@ -1622,14 +1659,14 @@ ibuf_new_search_tuple_build(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if there are enough pages in the free list of the ibuf tree that we
-dare to start a pessimistic insert to the insert buffer. */
+dare to start a pessimistic insert to the insert buffer.
+@return TRUE if enough free pages in list */
UNIV_INLINE
ibool
ibuf_data_enough_free_for_insert(void)
/*==================================*/
- /* out: TRUE if enough free pages in list */
{
ut_ad(mutex_own(&ibuf_mutex));
@@ -1642,29 +1679,28 @@ ibuf_data_enough_free_for_insert(void)
return(ibuf->free_list_len >= (ibuf->size / 2) + 3 * ibuf->height);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if there are enough pages in the free list of the ibuf tree that we
-should remove them and free to the file space management. */
+should remove them and free to the file space management.
+@return TRUE if enough free pages in list */
UNIV_INLINE
ibool
ibuf_data_too_much_free(void)
/*=========================*/
- /* out: TRUE if enough free pages in list */
{
ut_ad(mutex_own(&ibuf_mutex));
return(ibuf->free_list_len >= 3 + (ibuf->size / 2) + 3 * ibuf->height);
}
-/*************************************************************************
+/*********************************************************************//**
Allocates a new page from the ibuf file segment and adds it to the free
-list. */
+list.
+@return DB_SUCCESS, or DB_STRONG_FAIL if no space left */
static
ulint
ibuf_add_free_page(void)
/*====================*/
- /* out: DB_SUCCESS, or DB_STRONG_FAIL
- if no space left */
{
mtr_t mtr;
page_t* header_page;
@@ -1751,7 +1787,7 @@ ibuf_add_free_page(void)
return(DB_SUCCESS);
}
-/*************************************************************************
+/*********************************************************************//**
Removes a page from the free list and frees it to the fsp system. */
static
void
@@ -1876,7 +1912,7 @@ ibuf_remove_free_page(void)
ibuf_exit();
}
-/***************************************************************************
+/***********************************************************************//**
Frees excess pages from the ibuf free list. This function is called when an OS
thread calls fsp services to allocate a new file segment, or a new page to a
file segment, and the thread did not own the fsp latch before this call. */
@@ -1928,28 +1964,28 @@ ibuf_free_excess_pages(void)
}
}
-/*************************************************************************
-Reads page numbers from a leaf in an ibuf tree. */
+/*********************************************************************//**
+Reads page numbers from a leaf in an ibuf tree.
+@return a lower limit for the combined volume of records which will be
+merged */
static
ulint
ibuf_get_merge_page_nos(
/*====================*/
- /* out: a lower limit for the combined volume
- of records which will be merged */
- ibool contract,/* in: TRUE if this function is called to
+ ibool contract,/*!< in: TRUE if this function is called to
contract the tree, FALSE if this is called
when a single page becomes full and we look
if it pays to read also nearby pages */
- rec_t* rec, /* in: record from which we read up and down
+ rec_t* rec, /*!< in: record from which we read up and down
in the chain of records */
- ulint* space_ids,/* in/out: space id's of the pages */
- ib_int64_t* space_versions,/* in/out: tablespace version
+ ulint* space_ids,/*!< in/out: space id's of the pages */
+ ib_int64_t* space_versions,/*!< in/out: tablespace version
timestamps; used to prevent reading in old
pages after DISCARD + IMPORT tablespace */
- ulint* page_nos,/* in/out: buffer for at least
+ ulint* page_nos,/*!< in/out: buffer for at least
IBUF_MAX_N_PAGES_MERGED many page numbers;
the page numbers are in an ascending order */
- ulint* n_stored)/* out: number of page numbers stored to
+ ulint* n_stored)/*!< out: number of page numbers stored to
page_nos in this function */
{
ulint prev_page_no;
@@ -2101,17 +2137,17 @@ ibuf_get_merge_page_nos(
return(sum_volumes);
}
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
static
ulint
ibuf_contract_ext(
/*==============*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ulint* n_pages,/* out: number of pages to which merged */
- ibool sync) /* in: TRUE if the caller wants to wait for the
+ ulint* n_pages,/*!< out: number of pages to which merged */
+ ibool sync) /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
{
@@ -2182,16 +2218,16 @@ ibuf_is_empty:
return(sum_sizes + 1);
}
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
UNIV_INTERN
ulint
ibuf_contract(
/*==========*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ibool sync) /* in: TRUE if the caller wants to wait for the
+ ibool sync) /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
{
@@ -2200,19 +2236,19 @@ ibuf_contract(
return(ibuf_contract_ext(&n_pages, sync));
}
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
UNIV_INTERN
ulint
ibuf_contract_for_n_pages(
/*======================*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ibool sync, /* in: TRUE if the caller wants to wait for the
+ ibool sync, /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
- ulint n_pages)/* in: try to read at least this many pages to
+ ulint n_pages)/*!< in: try to read at least this many pages to
the buffer pool and merge the ibuf contents to
them */
{
@@ -2235,13 +2271,13 @@ ibuf_contract_for_n_pages(
return(sum_bytes);
}
-/*************************************************************************
+/*********************************************************************//**
Contract insert buffer trees after insert if they are too big. */
UNIV_INLINE
void
ibuf_contract_after_insert(
/*=======================*/
- ulint entry_size) /* in: size of a record which was inserted
+ ulint entry_size) /*!< in: size of a record which was inserted
into an ibuf tree */
{
ibool sync;
@@ -2278,26 +2314,24 @@ ibuf_contract_after_insert(
}
}
-/*************************************************************************
+/*********************************************************************//**
Gets an upper limit for the combined size of entries buffered in the insert
-buffer for a given page. */
+buffer for a given page.
+@return upper limit for the volume of buffered inserts for the index
+page, in bytes; UNIV_PAGE_SIZE, if the entries for the index page span
+several pages in the insert buffer */
static
ulint
ibuf_get_volume_buffered(
/*=====================*/
- /* out: upper limit for the volume of
- buffered inserts for the index page, in bytes;
- we may also return UNIV_PAGE_SIZE, if the
- entries for the index page span on several
- pages in the insert buffer */
- btr_pcur_t* pcur, /* in: pcur positioned at a place in an
+ btr_pcur_t* pcur, /*!< in: pcur positioned at a place in an
insert buffer tree where we would insert an
entry for the index page whose number is
page_no, latch mode has to be BTR_MODIFY_PREV
or BTR_MODIFY_TREE */
- ulint space, /* in: space id */
- ulint page_no,/* in: page number of an index page */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: page number of an index page */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint volume;
rec_t* rec;
@@ -2463,7 +2497,7 @@ count_later:
}
}
-/*************************************************************************
+/*********************************************************************//**
Reads the biggest tablespace id from the high end of the insert buffer
tree and updates the counter in fil_system. */
UNIV_INTERN
@@ -2511,24 +2545,24 @@ ibuf_update_max_tablespace_id(void)
fil_set_max_space_id_if_bigger(max_space_id);
}
-/*************************************************************************
+/*********************************************************************//**
Makes an index insert to the insert buffer, instead of directly to the disk
-page, if this is possible. */
+page, if this is possible.
+@return DB_SUCCESS, DB_FAIL, DB_STRONG_FAIL */
static
ulint
ibuf_insert_low(
/*============*/
- /* out: DB_SUCCESS, DB_FAIL, DB_STRONG_FAIL */
- ulint mode, /* in: BTR_MODIFY_PREV or BTR_MODIFY_TREE */
- const dtuple_t* entry, /* in: index entry to insert */
+ ulint mode, /*!< in: BTR_MODIFY_PREV or BTR_MODIFY_TREE */
+ const dtuple_t* entry, /*!< in: index entry to insert */
ulint entry_size,
- /* in: rec_get_converted_size(index, entry) */
- dict_index_t* index, /* in: index where to insert; must not be
+ /*!< in: rec_get_converted_size(index, entry) */
+ dict_index_t* index, /*!< in: index where to insert; must not be
unique or clustered */
- ulint space, /* in: space id where to insert */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number where to insert */
- que_thr_t* thr) /* in: query thread */
+ ulint space, /*!< in: space id where to insert */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number where to insert */
+ que_thr_t* thr) /*!< in: query thread */
{
big_rec_t* dummy_big_rec;
btr_pcur_t pcur;
@@ -2690,7 +2724,7 @@ ibuf_insert_low(
if (err == DB_SUCCESS) {
/* Update the page max trx id field */
page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
- thr_get_trx(thr)->id);
+ thr_get_trx(thr)->id, &mtr);
}
} else {
ut_ad(mode == BTR_MODIFY_TREE);
@@ -2710,7 +2744,7 @@ ibuf_insert_low(
if (err == DB_SUCCESS) {
/* Update the page max trx id field */
page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
- thr_get_trx(thr)->id);
+ thr_get_trx(thr)->id, &mtr);
}
ibuf_size_update(root, &mtr);
@@ -2764,21 +2798,21 @@ function_exit:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Makes an index insert to the insert buffer, instead of directly to the disk
page, if this is possible. Does not do insert if the index is clustered
-or unique. */
+or unique.
+@return TRUE if success */
UNIV_INTERN
ibool
ibuf_insert(
/*========*/
- /* out: TRUE if success */
- const dtuple_t* entry, /* in: index entry to insert */
- dict_index_t* index, /* in: index where to insert */
- ulint space, /* in: space id where to insert */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number where to insert */
- que_thr_t* thr) /* in: query thread */
+ const dtuple_t* entry, /*!< in: index entry to insert */
+ dict_index_t* index, /*!< in: index where to insert */
+ ulint space, /*!< in: space id where to insert */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number where to insert */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
ulint entry_size;
@@ -2830,18 +2864,18 @@ do_insert:
}
}
-/************************************************************************
+/********************************************************************//**
During merge, inserts to an index page a secondary index entry extracted
from the insert buffer. */
static
void
ibuf_insert_to_index_page(
/*======================*/
- dtuple_t* entry, /* in: buffered entry to insert */
- buf_block_t* block, /* in/out: index page where the buffered entry
+ dtuple_t* entry, /*!< in: buffered entry to insert */
+ buf_block_t* block, /*!< in/out: index page where the buffered entry
should be placed */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t page_cur;
ulint low_match;
@@ -2957,24 +2991,23 @@ dump:
}
}
-/*************************************************************************
+/*********************************************************************//**
Deletes from ibuf the record on which pcur is positioned. If we have to
resort to a pessimistic delete, this function commits mtr and closes
-the cursor. */
+the cursor.
+@return TRUE if mtr was committed and pcur closed in this operation */
static
ibool
ibuf_delete_rec(
/*============*/
- /* out: TRUE if mtr was committed and pcur
- closed in this operation */
- ulint space, /* in: space id */
- ulint page_no,/* in: index page number where the record
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: index page number where the record
should belong */
- btr_pcur_t* pcur, /* in: pcur positioned on the record to
+ btr_pcur_t* pcur, /*!< in: pcur positioned on the record to
delete, having latch mode BTR_MODIFY_LEAF */
const dtuple_t* search_tuple,
- /* in: search tuple for entries of page_no */
- mtr_t* mtr) /* in: mtr */
+ /*!< in: search tuple for entries of page_no */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool success;
page_t* root;
@@ -3073,7 +3106,7 @@ func_exit:
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
When an index page is read from a disk to the buffer pool, this function
inserts to the page the possible index entries buffered in the insert buffer.
The entries are deleted from the insert buffer. If the page is not read, but
@@ -3084,14 +3117,14 @@ UNIV_INTERN
void
ibuf_merge_or_delete_for_page(
/*==========================*/
- buf_block_t* block, /* in: if page has been read from
+ buf_block_t* block, /*!< in: if page has been read from
disk, pointer to the page x-latched,
else NULL */
- ulint space, /* in: space id of the index page */
- ulint page_no,/* in: page number of the index page */
- ulint zip_size,/* in: compressed page size in bytes,
+ ulint space, /*!< in: space id of the index page */
+ ulint page_no,/*!< in: page number of the index page */
+ ulint zip_size,/*!< in: compressed page size in bytes,
or 0 */
- ibool update_ibuf_bitmap)/* in: normally this is set
+ ibool update_ibuf_bitmap)/*!< in: normally this is set
to TRUE, but if we have deleted or are
deleting the tablespace, then we
naturally do not want to update a
@@ -3312,11 +3345,12 @@ loop:
keep the latch to the rec page until the
insertion is finished! */
dtuple_t* entry;
- dulint max_trx_id;
+ trx_id_t max_trx_id;
dict_index_t* dummy_index;
max_trx_id = page_get_max_trx_id(page_align(rec));
- page_update_max_trx_id(block, page_zip, max_trx_id);
+ page_update_max_trx_id(block, page_zip, max_trx_id,
+ &mtr);
entry = ibuf_build_entry_from_ibuf_rec(
rec, heap, &dummy_index);
@@ -3405,7 +3439,7 @@ reset_bit:
#endif
}
-/*************************************************************************
+/*********************************************************************//**
Deletes all entries in the insert buffer for a given space id. This is used
in DISCARD TABLESPACE and IMPORT TABLESPACE.
NOTE: this does not update the page free bitmaps in the space. The space will
@@ -3414,7 +3448,7 @@ UNIV_INTERN
void
ibuf_delete_for_discarded_space(
/*============================*/
- ulint space) /* in: space id */
+ ulint space) /*!< in: space id */
{
mem_heap_t* heap;
btr_pcur_t pcur;
@@ -3504,13 +3538,13 @@ leave_loop:
mem_heap_free(heap);
}
-/**********************************************************************
-Looks if the insert buffer is empty. */
+/******************************************************************//**
+Looks if the insert buffer is empty.
+@return TRUE if empty */
UNIV_INTERN
ibool
ibuf_is_empty(void)
/*===============*/
- /* out: TRUE if empty */
{
ibool is_empty;
const page_t* root;
@@ -3551,13 +3585,13 @@ ibuf_is_empty(void)
return(is_empty);
}
-/**********************************************************************
+/******************************************************************//**
Prints info of ibuf. */
UNIV_INTERN
void
ibuf_print(
/*=======*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
#ifdef UNIV_IBUF_COUNT_DEBUG
ulint i;
@@ -3592,3 +3626,4 @@ ibuf_print(
mutex_exit(&ibuf_mutex);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/btr0btr.h b/storage/xtradb/include/btr0btr.h
index 298942bd542..d5c8258513c 100644
--- a/storage/xtradb/include/btr0btr.h
+++ b/storage/xtradb/include/btr0btr.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0btr.h
The B-tree
Created 6/2/1994 Heikki Tuuri
@@ -33,315 +34,327 @@ Created 6/2/1994 Heikki Tuuri
#include "mtr0mtr.h"
#include "btr0types.h"
-/* Maximum record size which can be stored on a page, without using the
+#ifndef UNIV_HOTBACKUP
+/** Maximum record size which can be stored on a page, without using the
special big record storage structure */
-
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
-/* Maximum depth of a B-tree in InnoDB. Note that this isn't a maximum as
-such; none of the tree operations avoid producing trees bigger than this. It
-is instead a "max depth that other code must work with", useful for e.g.
-fixed-size arrays that must store some information about each level in a
-tree. In other words: if a B-tree with bigger depth than this is
-encountered, it is not acceptable for it to lead to mysterious memory
-corruption, but it is acceptable for the program to die with a clear assert
-failure. */
+/** @brief Maximum depth of a B-tree in InnoDB.
+
+Note that this isn't a maximum as such; none of the tree operations
+avoid producing trees bigger than this. It is instead a "max depth
+that other code must work with", useful for e.g. fixed-size arrays
+that must store some information about each level in a tree. In other
+words: if a B-tree with bigger depth than this is encountered, it is
+not acceptable for it to lead to mysterious memory corruption, but it
+is acceptable for the program to die with a clear assert failure. */
#define BTR_MAX_LEVELS 100
-/* Latching modes for btr_cur_search_to_nth_level(). */
-#define BTR_SEARCH_LEAF RW_S_LATCH
-#define BTR_MODIFY_LEAF RW_X_LATCH
-#define BTR_NO_LATCHES RW_NO_LATCH
-#define BTR_MODIFY_TREE 33
-#define BTR_CONT_MODIFY_TREE 34
-#define BTR_SEARCH_PREV 35
-#define BTR_MODIFY_PREV 36
+/** Latching modes for btr_cur_search_to_nth_level(). */
+enum btr_latch_mode {
+ /** Search a record on a leaf page and S-latch it. */
+ BTR_SEARCH_LEAF = RW_S_LATCH,
+ /** (Prepare to) modify a record on a leaf page and X-latch it. */
+ BTR_MODIFY_LEAF = RW_X_LATCH,
+ /** Obtain no latches. */
+ BTR_NO_LATCHES = RW_NO_LATCH,
+ /** Start modifying the entire B-tree. */
+ BTR_MODIFY_TREE = 33,
+ /** Continue modifying the entire B-tree. */
+ BTR_CONT_MODIFY_TREE = 34,
+ /** Search the previous record. */
+ BTR_SEARCH_PREV = 35,
+ /** Modify the previous record. */
+ BTR_MODIFY_PREV = 36
+};
-/* If this is ORed to the latch mode, it means that the search tuple will be
-inserted to the index, at the searched position */
+/** If this is ORed to btr_latch_mode, it means that the search tuple
+will be inserted to the index, at the searched position */
#define BTR_INSERT 512
-/* This flag ORed to latch mode says that we do the search in query
+/** This flag ORed to btr_latch_mode says that we do the search in query
optimization */
#define BTR_ESTIMATE 1024
-/* This flag ORed to latch mode says that we can ignore possible
-UNIQUE definition on secondary indexes when we decide if we can use the
-insert buffer to speed up inserts */
+/** This flag ORed to btr_latch_mode says that we can ignore possible
+UNIQUE definition on secondary indexes when we decide if we can use
+the insert buffer to speed up inserts */
#define BTR_IGNORE_SEC_UNIQUE 2048
-/******************************************************************
-Gets the root node of a tree and x-latches it. */
+/**************************************************************//**
+Gets the root node of a tree and x-latches it.
+@return root page, x-latched */
UNIV_INTERN
page_t*
btr_root_get(
/*=========*/
- /* out: root page, x-latched */
- dict_index_t* index, /* in: index tree */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ dict_index_t* index, /*!< in: index tree */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
buf_block_t*
btr_block_get(
/*==========*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- ulint mode, /* in: latch mode */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ ulint page_no, /*!< in: page number */
+ ulint mode, /*!< in: latch mode */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
page_t*
btr_page_get(
/*=========*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- ulint mode, /* in: latch mode */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
-Gets the index id field of a page. */
+ ulint page_no, /*!< in: page number */
+ ulint mode, /*!< in: latch mode */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/**************************************************************//**
+Gets the index id field of a page.
+@return index id */
UNIV_INLINE
dulint
btr_page_get_index_id(
/*==================*/
- /* out: index id */
- const page_t* page); /* in: index page */
-/************************************************************
-Gets the node level field in an index page. */
+ const page_t* page); /*!< in: index page */
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
+Gets the node level field in an index page.
+@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level_low(
/*===================*/
- /* out: level, leaf level == 0 */
- const page_t* page); /* in: index page */
-/************************************************************
-Gets the node level field in an index page. */
+ const page_t* page); /*!< in: index page */
+/********************************************************//**
+Gets the node level field in an index page.
+@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level(
/*===============*/
- /* out: level, leaf level == 0 */
- const page_t* page, /* in: index page */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
-Gets the next index page number. */
+ const page_t* page, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
+Gets the next index page number.
+@return next page number */
UNIV_INLINE
ulint
btr_page_get_next(
/*==============*/
- /* out: next page number */
- const page_t* page, /* in: index page */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
-Gets the previous index page number. */
+ const page_t* page, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
+Gets the previous index page number.
+@return prev page number */
UNIV_INLINE
ulint
btr_page_get_prev(
/*==============*/
- /* out: prev page number */
- const page_t* page, /* in: index page */
- mtr_t* mtr); /* in: mini-transaction handle */
-/*****************************************************************
+ const page_t* page, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/*************************************************************//**
Gets pointer to the previous user record in the tree. It is assumed
-that the caller has appropriate latches on the page and its neighbor. */
+that the caller has appropriate latches on the page and its neighbor.
+@return previous user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_prev_user_rec(
/*==================*/
- /* out: previous user record, NULL if there is none */
- rec_t* rec, /* in: record on leaf level */
- mtr_t* mtr); /* in: mtr holding a latch on the page, and if
+ rec_t* rec, /*!< in: record on leaf level */
+ mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
needed, also to the previous page */
-/*****************************************************************
+/*************************************************************//**
Gets pointer to the next user record in the tree. It is assumed
-that the caller has appropriate latches on the page and its neighbor. */
+that the caller has appropriate latches on the page and its neighbor.
+@return next user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_next_user_rec(
/*==================*/
- /* out: next user record, NULL if there is none */
- rec_t* rec, /* in: record on leaf level */
- mtr_t* mtr); /* in: mtr holding a latch on the page, and if
+ rec_t* rec, /*!< in: record on leaf level */
+ mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
needed, also to the next page */
-/******************************************************************
+/**************************************************************//**
Releases the latch on a leaf page and bufferunfixes it. */
UNIV_INLINE
void
btr_leaf_page_release(
/*==================*/
- buf_block_t* block, /* in: buffer block */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF or
+ buf_block_t* block, /*!< in: buffer block */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
-Gets the child node file address in a node pointer. */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
+Gets the child node file address in a node pointer.
+@return child node address */
UNIV_INLINE
ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
- /* out: child node address */
- const rec_t* rec, /* in: node pointer record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/****************************************************************
-Creates the root node for a new index tree. */
+ const rec_t* rec, /*!< in: node pointer record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/************************************************************//**
+Creates the root node for a new index tree.
+@return page number of the created root, FIL_NULL if did not succeed */
UNIV_INTERN
ulint
btr_create(
/*=======*/
- /* out: page number of the created root,
- FIL_NULL if did not succeed */
- ulint type, /* in: type of the index */
- ulint space, /* in: space where created */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint type, /*!< in: type of the index */
+ ulint space, /*!< in: space where created */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- dulint index_id,/* in: index id */
- dict_index_t* index, /* in: index */
- mtr_t* mtr); /* in: mini-transaction handle */
-/****************************************************************
+ dulint index_id,/*!< in: index id */
+ dict_index_t* index, /*!< in: index */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/************************************************************//**
Frees a B-tree except the root page, which MUST be freed after this
by calling btr_free_root. */
UNIV_INTERN
void
btr_free_but_not_root(
/*==================*/
- ulint space, /* in: space where created */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where created */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint root_page_no); /* in: root page number */
-/****************************************************************
+ ulint root_page_no); /*!< in: root page number */
+/************************************************************//**
Frees the B-tree root page. Other tree MUST already have been freed. */
UNIV_INTERN
void
btr_free_root(
/*==========*/
- ulint space, /* in: space where created */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where created */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint root_page_no, /* in: root page number */
- mtr_t* mtr); /* in: a mini-transaction which has already
+ ulint root_page_no, /*!< in: root page number */
+ mtr_t* mtr); /*!< in: a mini-transaction which has already
been started */
-/*****************************************************************
+/*************************************************************//**
Makes tree one level higher by splitting the root, and inserts
the tuple. It is assumed that mtr contains an x-latch on the tree.
NOTE that the operation of this function must always succeed,
we cannot reverse it: therefore enough free disk space must be
-guaranteed to be available before this function is called. */
+guaranteed to be available before this function is called.
+@return inserted record */
UNIV_INTERN
rec_t*
btr_root_raise_and_insert(
/*======================*/
- /* out: inserted record */
- btr_cur_t* cursor, /* in: cursor at which to insert: must be
+ btr_cur_t* cursor, /*!< in: cursor at which to insert: must be
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Reorganizes an index page.
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
page of a non-clustered index, the caller must update the insert
buffer free bits in the same mini-transaction in such a way that the
-modification will be redo-logged. */
+modification will be redo-logged.
+@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
btr_page_reorganize(
/*================*/
- /* out: TRUE on success, FALSE on failure */
- buf_block_t* block, /* in: page to be reorganized */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ buf_block_t* block, /*!< in: page to be reorganized */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Decides if the page should be split at the convergence point of
-inserts converging to left. */
+inserts converging to left.
+@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_left(
/*===========================*/
- /* out: TRUE if split recommended */
- btr_cur_t* cursor, /* in: cursor at which to insert */
- rec_t** split_rec);/* out: if split recommended,
+ btr_cur_t* cursor, /*!< in: cursor at which to insert */
+ rec_t** split_rec);/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
-/*****************************************************************
+/*************************************************************//**
Decides if the page should be split at the convergence point of
-inserts converging to right. */
+inserts converging to right.
+@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_right(
/*============================*/
- /* out: TRUE if split recommended */
- btr_cur_t* cursor, /* in: cursor at which to insert */
- rec_t** split_rec);/* out: if split recommended,
+ btr_cur_t* cursor, /*!< in: cursor at which to insert */
+ rec_t** split_rec);/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
-/*****************************************************************
+/*************************************************************//**
Splits an index page to halves and inserts the tuple. It is assumed
-that mtr holds an x-latch to the index tree. NOTE: the tree x-latch
-is released within this function! NOTE that the operation of this
-function must always succeed, we cannot reverse it: therefore
-enough free disk space must be guaranteed to be available before
-this function is called. */
+that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
+released within this function! NOTE that the operation of this
+function must always succeed, we cannot reverse it: therefore enough
+free disk space (2 pages) must be guaranteed to be available before
+this function is called.
+
+@return inserted record */
UNIV_INTERN
rec_t*
btr_page_split_and_insert(
/*======================*/
- /* out: inserted record; NOTE: the tree
- x-latch is released! NOTE: 2 free disk
- pages must be available! */
- btr_cur_t* cursor, /* in: cursor at which to insert; when the
+ 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 */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr); /* in: mtr */
-/***********************************************************
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr); /*!< in: mtr */
+/*******************************************************//**
Inserts a data tuple to a tree on a non-leaf level. It is assumed
that mtr holds an x-latch on the tree. */
UNIV_INTERN
void
btr_insert_on_non_leaf_level(
/*=========================*/
- dict_index_t* index, /* in: index */
- ulint level, /* in: level, must be > 0 */
- dtuple_t* tuple, /* in: the record to be inserted */
- mtr_t* mtr); /* in: mtr */
-/********************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: level, must be > 0 */
+ dtuple_t* tuple, /*!< in: the record to be inserted */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/****************************************************************//**
Sets a record as the predefined minimum record. */
UNIV_INTERN
void
btr_set_min_rec_mark(
/*=================*/
- rec_t* rec, /* in/out: record */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ rec_t* rec, /*!< in/out: record */
+ mtr_t* mtr); /*!< in: mtr */
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Deletes on the upper level the node pointer to a page. */
UNIV_INTERN
void
btr_node_ptr_delete(
/*================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: page whose node pointer is deleted */
- mtr_t* mtr); /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: page whose node pointer is deleted */
+ mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_DEBUG
-/****************************************************************
-Checks that the node pointer to a page is appropriate. */
+/************************************************************//**
+Checks that the node pointer to a page is appropriate.
+@return TRUE */
UNIV_INTERN
ibool
btr_check_node_ptr(
/*===============*/
- /* out: TRUE */
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: index page */
- mtr_t* mtr); /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mtr */
#endif /* UNIV_DEBUG */
-/*****************************************************************
+/*************************************************************//**
Tries to merge the page first to the left immediate brother if such a
brother exists, and the node pointers to the current page and to the
brother reside on the same page. If the left brother does not satisfy these
@@ -349,18 +362,18 @@ conditions, looks at the right brother. If the page is the only one on that
level lifts the records of the page to the father page, thus reducing the
tree height. It is assumed that mtr holds an x-latch on the tree and on the
page. If cursor is on the leaf level, mtr must also hold x-latches to
-the brothers, if they exist. */
+the brothers, if they exist.
+@return TRUE on success */
UNIV_INTERN
ibool
btr_compress(
/*=========*/
- /* out: TRUE on success */
- btr_cur_t* cursor, /* in: cursor on the page to merge or lift;
+ btr_cur_t* cursor, /*!< in: cursor on the page to merge or lift;
the page must not be empty: in record delete
use btr_discard_page if the page would become
empty */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Discards a page from a B-tree. This is used to remove the last record from
a B-tree page: the whole page must be removed at the same time. This cannot
be used for the root page, which is allowed to be empty. */
@@ -368,70 +381,71 @@ UNIV_INTERN
void
btr_discard_page(
/*=============*/
- btr_cur_t* cursor, /* in: cursor on the page to discard: not on
+ btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
the root page */
- mtr_t* mtr); /* in: mtr */
-/********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/****************************************************************//**
Parses the redo log record for setting an index record as the predefined
-minimum record. */
+minimum record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_set_min_rec_mark(
/*=======================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint comp, /* in: nonzero=compact page format */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses a redo log record of reorganizing a page. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint comp, /*!< in: nonzero=compact page format */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses a redo log record of reorganizing a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_page_reorganize(
/*======================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- dict_index_t* index, /* in: record descriptor */
- buf_block_t* block, /* in: page to be reorganized, or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/******************************************************************
-Gets the number of pages in a B-tree. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ dict_index_t* index, /*!< in: record descriptor */
+ buf_block_t* block, /*!< in: page to be reorganized, or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+#ifndef UNIV_HOTBACKUP
+/**************************************************************//**
+Gets the number of pages in a B-tree.
+@return number of pages */
UNIV_INTERN
ulint
btr_get_size(
/*=========*/
- /* out: number of pages */
- dict_index_t* index, /* in: index */
- ulint flag); /* in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
-/******************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint flag); /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
+/**************************************************************//**
Allocates a new file page to be used in an index tree. NOTE: we assume
-that the caller has made the reservation for free extents! */
+that the caller has made the reservation for free extents!
+@return new allocated block, x-latched; NULL if out of space */
UNIV_INTERN
buf_block_t*
btr_page_alloc(
/*===========*/
- /* out: new allocated block, x-latched;
- NULL if out of space */
- dict_index_t* index, /* in: index tree */
- ulint hint_page_no, /* in: hint of a good page */
- byte file_direction, /* in: direction where a possible
+ dict_index_t* index, /*!< in: index tree */
+ ulint hint_page_no, /*!< in: hint of a good page */
+ byte file_direction, /*!< in: direction where a possible
page split is made */
- ulint level, /* in: level where the page is placed
+ ulint level, /*!< in: level where the page is placed
in the tree */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Frees a file page used in an index tree. NOTE: cannot free field external
storage pages because the page must contain info on its level. */
UNIV_INTERN
void
btr_page_free(
/*==========*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Frees a file page used in an index tree. Can be used also to BLOB
external storage pages, because the page level 0 can be given as an
argument. */
@@ -439,53 +453,54 @@ UNIV_INTERN
void
btr_page_free_low(
/*==============*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- ulint level, /* in: page level */
- mtr_t* mtr); /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ ulint level, /*!< in: page level */
+ mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_BTR_PRINT
-/*****************************************************************
+/*************************************************************//**
Prints size info of a B-tree. */
UNIV_INTERN
void
btr_print_size(
/*===========*/
- dict_index_t* index); /* in: index tree */
-/******************************************************************
+ dict_index_t* index); /*!< in: index tree */
+/**************************************************************//**
Prints directories and other info of all nodes in the index. */
UNIV_INTERN
void
btr_print_index(
/*============*/
- dict_index_t* index, /* in: index */
- ulint width); /* in: print this many entries from start
+ dict_index_t* index, /*!< in: index */
+ ulint width); /*!< in: print this many entries from start
and end */
#endif /* UNIV_BTR_PRINT */
-/****************************************************************
+/************************************************************//**
Checks the size and number of fields in a record based on the definition of
-the index. */
+the index.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_index_rec_validate(
/*===================*/
- /* out: TRUE if ok */
- const rec_t* rec, /* in: index record */
- const dict_index_t* index, /* in: index */
- ibool dump_on_error); /* in: TRUE if the function
+ const rec_t* rec, /*!< in: index record */
+ const dict_index_t* index, /*!< in: index */
+ ibool dump_on_error); /*!< in: TRUE if the function
should print hex dump of record
and page on error */
-/******************************************************************
-Checks the consistency of an index tree. */
+/**************************************************************//**
+Checks the consistency of an index tree.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_validate_index(
/*===============*/
- /* out: TRUE if ok */
- dict_index_t* index, /* in: index */
- trx_t* trx); /* in: transaction or NULL */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx); /*!< in: transaction or NULL */
#define BTR_N_LEAF_PAGES 1
#define BTR_TOTAL_SIZE 2
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "btr0btr.ic"
diff --git a/storage/xtradb/include/btr0btr.ic b/storage/xtradb/include/btr0btr.ic
index a8d934ecc87..2259d22c9a6 100644
--- a/storage/xtradb/include/btr0btr.ic
+++ b/storage/xtradb/include/btr0btr.ic
@@ -16,31 +16,37 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0btr.ic
The B-tree
Created 6/2/1994 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
+#ifndef UNIV_HOTBACKUP
#include "mtr0mtr.h"
#include "mtr0log.h"
#include "page0zip.h"
-#define BTR_MAX_NODE_LEVEL 50 /* used in debug checking */
+#define BTR_MAX_NODE_LEVEL 50 /*!< Maximum B-tree page level
+ (not really a hard limit).
+ Used in debug assertions
+ in btr_page_set_level and
+ btr_page_get_level_low */
-/******************************************************************
+/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
buf_block_t*
btr_block_get(
/*==========*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- ulint mode, /* in: latch mode */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number */
+ ulint mode, /*!< in: latch mode */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -54,34 +60,34 @@ btr_block_get(
return(block);
}
-/******************************************************************
+/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
page_t*
btr_page_get(
/*=========*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- ulint mode, /* in: latch mode */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number */
+ ulint mode, /*!< in: latch mode */
+ mtr_t* mtr) /*!< in: mtr */
{
return(buf_block_get_frame(btr_block_get(space, zip_size, page_no,
mode, mtr)));
}
-/******************************************************************
+/**************************************************************//**
Sets the index id field of a page. */
UNIV_INLINE
void
btr_page_set_index_id(
/*==================*/
- page_t* page, /* in: page to be created */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ page_t* page, /*!< in: page to be created */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- dulint id, /* in: index id */
- mtr_t* mtr) /* in: mtr */
+ dulint id, /*!< in: index id */
+ mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_LIKELY_NULL(page_zip)) {
mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), id);
@@ -93,27 +99,29 @@ btr_page_set_index_id(
id, mtr);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/******************************************************************
-Gets the index id field of a page. */
+/**************************************************************//**
+Gets the index id field of a page.
+@return index id */
UNIV_INLINE
dulint
btr_page_get_index_id(
/*==================*/
- /* out: index id */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
}
-/************************************************************
-Gets the node level field in an index page. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
+Gets the node level field in an index page.
+@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level_low(
/*===================*/
- /* out: level, leaf level == 0 */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
ulint level;
@@ -126,33 +134,33 @@ btr_page_get_level_low(
return(level);
}
-/************************************************************
-Gets the node level field in an index page. */
+/********************************************************//**
+Gets the node level field in an index page.
+@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level(
/*===============*/
- /* out: level, leaf level == 0 */
- const page_t* page, /* in: index page */
+ const page_t* page, /*!< in: index page */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
return(btr_page_get_level_low(page));
}
-/************************************************************
+/********************************************************//**
Sets the node level field in an index page. */
UNIV_INLINE
void
btr_page_set_level(
/*===============*/
- page_t* page, /* in: index page */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ page_t* page, /*!< in: index page */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- ulint level, /* in: level, leaf level == 0 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint level, /*!< in: level, leaf level == 0 */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
ut_ad(level <= BTR_MAX_NODE_LEVEL);
@@ -168,16 +176,16 @@ btr_page_set_level(
}
}
-/************************************************************
-Gets the next index page number. */
+/********************************************************//**
+Gets the next index page number.
+@return next page number */
UNIV_INLINE
ulint
btr_page_get_next(
/*==============*/
- /* out: next page number */
- const page_t* page, /* in: index page */
+ const page_t* page, /*!< in: index page */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)
@@ -186,17 +194,17 @@ btr_page_get_next(
return(mach_read_from_4(page + FIL_PAGE_NEXT));
}
-/************************************************************
+/********************************************************//**
Sets the next index page field. */
UNIV_INLINE
void
btr_page_set_next(
/*==============*/
- page_t* page, /* in: index page */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ page_t* page, /*!< in: index page */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- ulint next, /* in: next page number */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint next, /*!< in: next page number */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
@@ -208,32 +216,32 @@ btr_page_set_next(
}
}
-/************************************************************
-Gets the previous index page number. */
+/********************************************************//**
+Gets the previous index page number.
+@return prev page number */
UNIV_INLINE
ulint
btr_page_get_prev(
/*==============*/
- /* out: prev page number */
- const page_t* page, /* in: index page */
- mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
+ const page_t* page, /*!< in: index page */
+ mtr_t* mtr __attribute__((unused))) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
return(mach_read_from_4(page + FIL_PAGE_PREV));
}
-/************************************************************
+/********************************************************//**
Sets the previous index page field. */
UNIV_INLINE
void
btr_page_set_prev(
/*==============*/
- page_t* page, /* in: index page */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ page_t* page, /*!< in: index page */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- ulint prev, /* in: previous page number */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint prev, /*!< in: previous page number */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
@@ -245,15 +253,15 @@ btr_page_set_prev(
}
}
-/******************************************************************
-Gets the child node file address in a node pointer. */
+/**************************************************************//**
+Gets the child node file address in a node pointer.
+@return child node address */
UNIV_INLINE
ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
- /* out: child node address */
- const rec_t* rec, /* in: node pointer record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const rec_t* rec, /*!< in: node pointer record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
const byte* field;
ulint len;
@@ -280,16 +288,16 @@ btr_node_ptr_get_child_page_no(
return(page_no);
}
-/******************************************************************
+/**************************************************************//**
Releases the latches on a leaf page and bufferunfixes it. */
UNIV_INLINE
void
btr_leaf_page_release(
/*==================*/
- buf_block_t* block, /* in: buffer block */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF or
+ buf_block_t* block, /*!< in: buffer block */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
ut_ad(!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY));
@@ -299,3 +307,4 @@ btr_leaf_page_release(
? MTR_MEMO_PAGE_S_FIX
: MTR_MEMO_PAGE_X_FIX);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h
index c3a478c4bb7..480a3877e54 100644
--- a/storage/xtradb/include/btr0cur.h
+++ b/storage/xtradb/include/btr0cur.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0cur.h
The index tree cursor
Created 10/16/1994 Heikki Tuuri
@@ -29,9 +30,6 @@ Created 10/16/1994 Heikki Tuuri
#include "dict0dict.h"
#include "page0cur.h"
#include "btr0types.h"
-#include "que0types.h"
-#include "row0types.h"
-#include "ha0ha.h"
/* Mode flags for btr_cur operations; these can be ORed */
#define BTR_NO_UNDO_LOG_FLAG 1 /* do no undo logging */
@@ -39,81 +37,84 @@ Created 10/16/1994 Heikki Tuuri
#define BTR_KEEP_SYS_FLAG 4 /* sys fields will be found from the
update vector or inserted entry */
+#ifndef UNIV_HOTBACKUP
+#include "que0types.h"
+#include "row0types.h"
+#include "ha0ha.h"
+
#define BTR_CUR_ADAPT
#define BTR_CUR_HASH_ADAPT
#ifdef UNIV_DEBUG
-/*************************************************************
-Returns the page cursor component of a tree cursor. */
+/*********************************************************//**
+Returns the page cursor component of a tree cursor.
+@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_cur_get_page_cur(
/*=================*/
- /* out: pointer to page cursor
- component */
- const btr_cur_t* cursor);/* in: tree cursor */
+ const btr_cur_t* cursor);/*!< in: tree cursor */
#else /* UNIV_DEBUG */
# define btr_cur_get_page_cur(cursor) (&(cursor)->page_cur)
#endif /* UNIV_DEBUG */
-/*************************************************************
-Returns the buffer block on which the tree cursor is positioned. */
+/*********************************************************//**
+Returns the buffer block on which the tree cursor is positioned.
+@return pointer to buffer block */
UNIV_INLINE
buf_block_t*
btr_cur_get_block(
/*==============*/
- /* out: pointer to buffer block */
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
-Returns the record pointer of a tree cursor. */
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
+Returns the record pointer of a tree cursor.
+@return pointer to record */
UNIV_INLINE
rec_t*
btr_cur_get_rec(
/*============*/
- /* out: pointer to record */
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
-Returns the compressed page on which the tree cursor is positioned. */
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
+Returns the compressed page on which the tree cursor is positioned.
+@return pointer to compressed page, or NULL if the page is not compressed */
UNIV_INLINE
page_zip_des_t*
btr_cur_get_page_zip(
/*=================*/
- /* out: pointer to compressed page,
- or NULL if the page is not compressed */
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
Invalidates a tree cursor by setting record pointer to NULL. */
UNIV_INLINE
void
btr_cur_invalidate(
/*===============*/
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
-Returns the page of a tree cursor. */
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
+Returns the page of a tree cursor.
+@return pointer to page */
UNIV_INLINE
page_t*
btr_cur_get_page(
/*=============*/
- /* out: pointer to page */
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
-Returns the index of a cursor. */
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
+Returns the index of a cursor.
+@return index */
UNIV_INLINE
dict_index_t*
btr_cur_get_index(
/*==============*/
- /* out: index */
- btr_cur_t* cursor);/* in: B-tree cursor */
-/*************************************************************
+ btr_cur_t* cursor);/*!< in: B-tree cursor */
+/*********************************************************//**
Positions a tree cursor at a given record. */
UNIV_INLINE
void
btr_cur_position(
/*=============*/
- dict_index_t* index, /* in: index */
- rec_t* rec, /* in: record in tree */
- buf_block_t* block, /* in: buffer block of rec */
- btr_cur_t* cursor);/* in: cursor */
-/************************************************************************
+ dict_index_t* index, /*!< in: index */
+ rec_t* rec, /*!< in: record in tree */
+ buf_block_t* block, /*!< in: buffer block of rec */
+ btr_cur_t* cursor);/*!< in: cursor */
+/********************************************************************//**
Searches an index tree and positions a tree cursor on a given level.
NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
to node pointer page number fields on the upper levels of the tree!
@@ -124,19 +125,19 @@ UNIV_INTERN
void
btr_cur_search_to_nth_level(
/*========================*/
- 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
+ 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! */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be PAGE_CUR_LE,
not PAGE_CUR_GE, as the latter may end up on
the previous page of the record! Inserts
should always be made using PAGE_CUR_LE to
search the position! */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
BTR_INSERT and BTR_ESTIMATE;
cursor->left_block is used to store a pointer
to the left neighbor page, in the cases
@@ -146,309 +147,305 @@ btr_cur_search_to_nth_level(
on the cursor page, we assume
the caller uses his search latch
to protect the record! */
- btr_cur_t* cursor, /* in/out: tree cursor; the cursor page is
+ btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
- ulint has_search_latch,/* in: latch mode the caller
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, or 0 */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Opens a cursor at either end of an index. */
UNIV_INTERN
void
btr_cur_open_at_index_side(
/*=======================*/
- ibool from_left, /* in: TRUE if open to the low end,
+ ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: latch mode */
- btr_cur_t* cursor, /* in: cursor */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: latch mode */
+ btr_cur_t* cursor, /*!< in: cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INTERN
void
btr_cur_open_at_rnd_pos(
/*====================*/
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_cur_t* cursor, /* in/out: B-tree cursor */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_cur_t* cursor, /*!< in/out: B-tree cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Tries to perform an insert to a page in an index tree, next to cursor.
It is assumed that mtr holds an x-latch on the page. The operation does
not succeed if there is too little space on the page. If there is just
one record on the page, the insert will always succeed; this is to
-prevent trying to split a page with just one record. */
+prevent trying to split a page with just one record.
+@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
UNIV_INTERN
ulint
btr_cur_optimistic_insert(
/*======================*/
- /* out: DB_SUCCESS, DB_WAIT_LOCK,
- DB_FAIL, or error number */
- ulint flags, /* in: undo logging and locking flags: if not
+ ulint flags, /*!< in: undo logging and locking flags: if not
zero, the parameters index and thr should be
specified */
- btr_cur_t* cursor, /* in: cursor on page after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
- dtuple_t* entry, /* in/out: entry to insert */
- rec_t** rec, /* out: pointer to inserted record if
+ dtuple_t* entry, /*!< in/out: entry to insert */
+ rec_t** rec, /*!< out: pointer to inserted record if
succeed */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or
NULL */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr, /* in: query thread or NULL */
- mtr_t* mtr); /* in: mtr; if this function returns
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr); /*!< in: mtr; if this function returns
DB_SUCCESS on a leaf page of a secondary
index in a compressed tablespace, the
mtr must be committed before latching
any further pages */
-/*****************************************************************
+/*************************************************************//**
Performs an insert on a page of an index tree. It is assumed that mtr
holds an x-latch on the tree and on the cursor page. If the insert is
made on the leaf level, to avoid deadlocks, mtr must also own x-latches
-to brothers of page, if those brothers exist. */
+to brothers of page, if those brothers exist.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
btr_cur_pessimistic_insert(
/*=======================*/
- /* out: DB_SUCCESS or error number */
- ulint flags, /* in: undo logging and locking flags: if not
+ ulint flags, /*!< in: undo logging and locking flags: if not
zero, the parameter thr should be
specified; if no undo logging is specified,
then the caller must have reserved enough
free extents in the file space so that the
insertion will certainly succeed */
- btr_cur_t* cursor, /* in: cursor after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor after which to insert;
cursor stays valid */
- dtuple_t* entry, /* in/out: entry to insert */
- rec_t** rec, /* out: pointer to inserted record if
+ dtuple_t* entry, /*!< in/out: entry to insert */
+ rec_t** rec, /*!< out: pointer to inserted record if
succeed */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or
NULL */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr, /* in: query thread or NULL */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
-Updates a record when the update causes no size changes in its fields. */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
+Updates a record when the update causes no size changes in its fields.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
btr_cur_update_in_place(
/*====================*/
- /* out: DB_SUCCESS or error number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on the record to update;
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- const upd_t* update, /* in: update vector */
- ulint cmpl_info,/* in: compiler info on secondary index
+ const upd_t* update, /*!< in: update vector */
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr; must be committed before
latching any further pages */
-/*****************************************************************
+/*************************************************************//**
Tries to update a record on a page in an index tree. It is assumed that mtr
holds an x-latch on the page. The operation does not succeed if there is too
little space on the page or if the update would result in too empty a page,
-so that tree compression is recommended. */
+so that tree compression is recommended.
+@return DB_SUCCESS, or DB_OVERFLOW if the updated record does not fit,
+DB_UNDERFLOW if the page would become too empty, or DB_ZIP_OVERFLOW if
+there is not enough space left on the compressed page */
UNIV_INTERN
ulint
btr_cur_optimistic_update(
/*======================*/
- /* out: DB_SUCCESS, or DB_OVERFLOW if the
- updated record does not fit, DB_UNDERFLOW
- if the page would become too empty, or
- DB_ZIP_OVERFLOW if there is not enough
- space left on the compressed page */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on the record to update;
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- const upd_t* update, /* in: update vector; this must also
+ const upd_t* update, /*!< in: update vector; this must also
contain trx id and roll ptr fields */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr; must be committed before
latching any further pages */
-/*****************************************************************
+/*************************************************************//**
Performs an update of a record on a page of a tree. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. If the
update is made on the leaf level, to avoid deadlocks, mtr must also
-own x-latches to brothers of page, if those brothers exist. */
+own x-latches to brothers of page, if those brothers exist.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
btr_cur_pessimistic_update(
/*=======================*/
- /* out: DB_SUCCESS or error code */
- ulint flags, /* in: undo logging, locking, and rollback
+ ulint flags, /*!< in: undo logging, locking, and rollback
flags */
- btr_cur_t* cursor, /* in: cursor on the record to update */
- mem_heap_t** heap, /* in/out: pointer to memory heap, or NULL */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ btr_cur_t* cursor, /*!< in: cursor on the record to update */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or NULL */
- const upd_t* update, /* in: update vector; this is allowed also
+ const upd_t* update, /*!< in: update vector; this is allowed also
contain trx id and roll ptr fields, but
the values in update vector have no effect */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr; must be committed before
latching any further pages */
-/***************************************************************
+/***********************************************************//**
Marks a clustered index record deleted. Writes an undo log record to
undo log on this delete marking. Writes in the trx id field the id
of the deleting transaction, and in the roll ptr field pointer to the
-undo log record created. */
+undo log record created.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
UNIV_INTERN
ulint
btr_cur_del_mark_set_clust_rec(
/*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor */
- ibool val, /* in: value to set */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************
-Sets a secondary index record delete mark to TRUE or FALSE. */
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor */
+ ibool val, /*!< in: value to set */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************//**
+Sets a secondary index record delete mark to TRUE or FALSE.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
UNIV_INTERN
ulint
btr_cur_del_mark_set_sec_rec(
/*=========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- number */
- ulint flags, /* in: locking flag */
- btr_cur_t* cursor, /* in: cursor */
- ibool val, /* in: value to set */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************
+ ulint flags, /*!< in: locking flag */
+ btr_cur_t* cursor, /*!< in: cursor */
+ ibool val, /*!< in: value to set */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************//**
Clear a secondary index record's delete mark. This function is only
used by the insert buffer insert merge mechanism. */
UNIV_INTERN
void
btr_cur_del_unmark_for_ibuf(
/*========================*/
- rec_t* rec, /* in/out: record to delete unmark */
- page_zip_des_t* page_zip, /* in/out: compressed page
+ rec_t* rec, /*!< in/out: record to delete unmark */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page
corresponding to rec, or NULL
when the tablespace is
uncompressed */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Tries to compress a page of the tree if it seems useful. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. To avoid
deadlocks, mtr must also own x-latches to brothers of page, if those
brothers exist. NOTE: it is assumed that the caller has reserved enough
-free extents so that the compression will always succeed if done! */
+free extents so that the compression will always succeed if done!
+@return TRUE if compression occurred */
UNIV_INTERN
ibool
btr_cur_compress_if_useful(
/*=======================*/
- /* out: TRUE if compression occurred */
- btr_cur_t* cursor, /* in: cursor on the page to compress;
+ btr_cur_t* cursor, /*!< in: cursor on the page to compress;
cursor does not stay valid if compression
occurs */
- mtr_t* mtr); /* in: mtr */
-/***********************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*******************************************************//**
Removes the record on which the tree cursor is positioned. It is assumed
that the mtr has an x-latch on the page where the cursor is positioned,
-but no latch on the whole tree. */
+but no latch on the whole tree.
+@return TRUE if success, i.e., the page did not become too empty */
UNIV_INTERN
ibool
btr_cur_optimistic_delete(
/*======================*/
- /* out: TRUE if success, i.e., the page
- did not become too empty */
- btr_cur_t* cursor, /* in: cursor on the record to delete;
+ btr_cur_t* cursor, /*!< in: cursor on the record to delete;
cursor stays valid: if deletion succeeds,
on function exit it points to the successor
of the deleted record */
- mtr_t* mtr); /* in: mtr; if this function returns
+ mtr_t* mtr); /*!< in: mtr; if this function returns
TRUE on a leaf page of a secondary
index, the mtr must be committed
before latching any further pages */
-/*****************************************************************
+/*************************************************************//**
Removes the record on which the tree cursor is positioned. Tries
to compress the page if its fillfactor drops below a threshold
or if it is the only page on the level. It is assumed that mtr holds
an x-latch on the tree and on the cursor page. To avoid deadlocks,
mtr must also own x-latches to brothers of page, if those brothers
-exist. */
+exist.
+@return TRUE if compression occurred */
UNIV_INTERN
ibool
btr_cur_pessimistic_delete(
/*=======================*/
- /* out: TRUE if compression occurred */
- ulint* err, /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
+ ulint* err, /*!< out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
the latter may occur because we may have
to update node pointers on upper levels,
and in the case of variable length keys
these may actually grow in size */
- ibool has_reserved_extents, /* in: TRUE if the
+ ibool has_reserved_extents, /*!< in: TRUE if the
caller has already reserved enough free
extents so that he knows that the operation
will succeed */
- btr_cur_t* cursor, /* in: cursor on the record to delete;
+ btr_cur_t* cursor, /*!< in: cursor on the record to delete;
if compression does not occur, the cursor
stays valid: it points to successor of
deleted record on function exit */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************
-Parses a redo log record of updating a record in-place. */
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
+Parses a redo log record of updating a record in-place.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_update_in_place(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index); /* in: index corresponding to page */
-/********************************************************************
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index); /*!< in: index corresponding to page */
+/****************************************************************//**
Parses the redo log record for delete marking or unmarking of a clustered
-index record. */
+index record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_del_mark_set_clust_rec(
/*=================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index); /* in: index corresponding to page */
-/********************************************************************
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index); /*!< in: index corresponding to page */
+/****************************************************************//**
Parses the redo log record for delete marking or unmarking of a secondary
-index record. */
+index record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_del_mark_set_sec_rec(
/*===============================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip);/* in/out: compressed page, or NULL */
-/***********************************************************************
-Estimates the number of rows in a given index range. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip);/*!< in/out: compressed page, or NULL */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Estimates the number of rows in a given index range.
+@return estimated number of rows */
UNIV_INTERN
ib_int64_t
btr_estimate_n_rows_in_range(
/*=========================*/
- /* out: estimated number of rows */
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple1, /* in: range start, may also be empty tuple */
- ulint mode1, /* in: search mode for range start */
- const dtuple_t* tuple2, /* in: range end, may also be empty tuple */
- ulint mode2); /* in: search mode for range end */
-/***********************************************************************
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
+ ulint mode1, /*!< in: search mode for range start */
+ const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
+ ulint mode2); /*!< in: search mode for range end */
+/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
The estimates are stored in the array index->stat_n_diff_key_vals. */
@@ -456,8 +453,8 @@ UNIV_INTERN
void
btr_estimate_number_of_different_key_vals(
/*======================================*/
- dict_index_t* index); /* in: index */
-/***********************************************************************
+ dict_index_t* index); /*!< in: index */
+/*******************************************************************//**
Marks not updated extern fields as not-owned by this record. The ownership
is transferred to the updated record which is inserted elsewhere in the
index tree. In purge only the owner of externally stored field is allowed
@@ -466,14 +463,14 @@ UNIV_INTERN
void
btr_cur_mark_extern_inherited_fields(
/*=================================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
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 upd_t* update, /* in: update vector */
- mtr_t* mtr); /* in: mtr, or NULL if not logged */
-/***********************************************************************
+ 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 upd_t* update, /*!< in: update vector */
+ mtr_t* mtr); /*!< in: mtr, or NULL if not logged */
+/*******************************************************************//**
The complement of the previous function: in an update entry may inherit
some externally stored fields from a record. We must mark them as inherited
in entry, so that they are not freed in a rollback. */
@@ -481,39 +478,39 @@ UNIV_INTERN
void
btr_cur_mark_dtuple_inherited_extern(
/*=================================*/
- dtuple_t* entry, /* in/out: updated entry to be
+ dtuple_t* entry, /*!< in/out: updated entry to be
inserted to clustered index */
- const upd_t* update); /* in: update vector */
-/***********************************************************************
+ const upd_t* update); /*!< in: update vector */
+/*******************************************************************//**
Marks all extern fields in a dtuple as owned by the record. */
UNIV_INTERN
void
btr_cur_unmark_dtuple_extern_fields(
/*================================*/
- dtuple_t* entry); /* in/out: clustered index entry */
-/***********************************************************************
+ dtuple_t* entry); /*!< in/out: clustered index entry */
+/*******************************************************************//**
Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
The fields are stored on pages allocated from leaf node
-file segment of the index tree. */
+file segment of the index tree.
+@return DB_SUCCESS or error */
UNIV_INTERN
ulint
btr_store_big_rec_extern_fields(
/*============================*/
- /* out: DB_SUCCESS or error */
- dict_index_t* index, /* in: index of rec; the index tree
+ dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
- buf_block_t* rec_block, /* in/out: block containing rec */
- rec_t* rec, /* in: record */
- const ulint* offsets, /* in: rec_get_offsets(rec, index);
+ buf_block_t* rec_block, /*!< in/out: block containing rec */
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index);
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
- big_rec_t* big_rec_vec, /* in: vector containing fields
+ big_rec_t* big_rec_vec, /*!< in: vector containing fields
to be stored externally */
- mtr_t* local_mtr); /* in: mtr containing the latch to
+ mtr_t* local_mtr); /*!< in: mtr containing the latch to
rec and to the tree */
-/***********************************************************************
+/*******************************************************************//**
Frees the space in an externally stored field to the file space
management if the field in data is owned the externally stored field,
in a rollback we may have the additional condition that the field must
@@ -522,7 +519,7 @@ UNIV_INTERN
void
btr_free_externally_stored_field(
/*=============================*/
- dict_index_t* index, /* in: index of the data, the index
+ dict_index_t* index, /*!< in: index of the data, the index
tree MUST be X-latched; if the tree
height is 1, then also the root page
must be X-latched! (this is relevant
@@ -530,120 +527,131 @@ btr_free_externally_stored_field(
from purge where 'data' is located on
an undo log page, not an index
page) */
- byte* field_ref, /* in/out: field reference */
- const rec_t* rec, /* in: record containing field_ref, for
+ 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 ulint* offsets, /*!< in: rec_get_offsets(rec, index),
or NULL */
- page_zip_des_t* page_zip, /* in: compressed page corresponding
+ page_zip_des_t* page_zip, /*!< in: compressed page corresponding
to rec, or NULL if rec == NULL */
- ulint i, /* in: field number of field_ref;
+ ulint i, /*!< in: field number of field_ref;
ignored if rec == NULL */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* local_mtr); /* in: mtr containing the latch to
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* local_mtr); /*!< in: mtr containing the latch to
data an an X-latch to the index
tree */
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of an externally stored field of a record. The
-clustered index record must be protected by a lock or a page latch. */
+clustered index record must be protected by a lock or a page latch.
+@return the length of the copied field, or 0 if the column was being
+or has been deleted */
UNIV_INTERN
ulint
btr_copy_externally_stored_field_prefix(
/*====================================*/
- /* out: the length of the copied field,
- or 0 if the column is being or has been
- deleted */
- byte* buf, /* out: the field, or a prefix of it */
- ulint len, /* in: length of buf, in bytes */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ byte* buf, /*!< out: the field, or a prefix of it */
+ ulint len, /*!< in: length of buf, in bytes */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- const byte* data, /* in: 'internally' stored part of the
+ const byte* data, /*!< in: 'internally' stored part of the
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len);/* in: length of data, in bytes */
-/***********************************************************************
-Copies an externally stored field of a record to mem heap. */
+ ulint local_len);/*!< in: length of data, in bytes */
+/*******************************************************************//**
+Copies an externally stored field of a record to mem heap.
+@return the field copied to heap */
UNIV_INTERN
byte*
btr_rec_copy_externally_stored_field(
/*=================================*/
- /* out: the field copied to heap */
- const rec_t* rec, /* in: record in a clustered index;
+ const rec_t* rec, /*!< in: record in a clustered index;
must be protected by a lock or a page latch */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- ulint no, /* in: field number */
- ulint* len, /* out: length of the field */
- mem_heap_t* heap); /* in: mem heap */
-/***********************************************************************
+ ulint no, /*!< in: field number */
+ ulint* len, /*!< out: length of the field */
+ mem_heap_t* heap); /*!< in: mem 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. */
+mark as extern storage in a record inserted for an update.
+@return number of flagged external columns */
UNIV_INTERN
ulint
btr_push_update_extern_fields(
/*==========================*/
- /* out: number of flagged external columns */
- dtuple_t* tuple, /* in/out: data tuple */
- const upd_t* update, /* in: update vector */
- mem_heap_t* heap) /* in: memory heap */
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const upd_t* update, /*!< in: update vector */
+ mem_heap_t* heap) /*!< in: memory heap */
__attribute__((nonnull));
/*######################################################################*/
-/* In the pessimistic delete, if the page data size drops below this
+/** In the pessimistic delete, if the page data size drops below this
limit, merging it to a neighbor is tried */
-
#define BTR_CUR_PAGE_COMPRESS_LIMIT (UNIV_PAGE_SIZE / 2)
-/* A slot in the path array. We store here info on a search path down the
+/** A slot in the path array. We store here info on a search path down the
tree. Each slot contains data on a single level of the tree. */
typedef struct btr_path_struct btr_path_t;
struct btr_path_struct{
- ulint nth_rec; /* index of the record
+ ulint nth_rec; /*!< index of the record
where the page cursor stopped on
this level (index in alphabetical
order); value ULINT_UNDEFINED
denotes array end */
- ulint n_recs; /* number of records on the page */
+ ulint n_recs; /*!< number of records on the page */
};
-#define BTR_PATH_ARRAY_N_SLOTS 250 /* size of path array (in slots) */
+#define BTR_PATH_ARRAY_N_SLOTS 250 /*!< size of path array (in slots) */
-/* The tree cursor: the definition appears here only for the compiler
-to know struct size! */
+/** Values for the flag documenting the used search method */
+enum btr_cur_method {
+ BTR_CUR_HASH = 1, /*!< successful shortcut using
+ the hash index */
+ BTR_CUR_HASH_FAIL, /*!< failure using hash, success using
+ binary search: the misleading hash
+ reference is stored in the field
+ hash_node, and might be necessary to
+ update */
+ BTR_CUR_BINARY, /*!< success using the binary search */
+ BTR_CUR_INSERT_TO_IBUF /*!< performed the intended insert to
+ the insert buffer */
+};
+/** The tree cursor: the definition appears here only for the compiler
+to know struct size! */
struct btr_cur_struct {
- dict_index_t* index; /* index where positioned */
- page_cur_t page_cur; /* page cursor */
- buf_block_t* left_block; /* this field is used to store
+ dict_index_t* index; /*!< index where positioned */
+ page_cur_t page_cur; /*!< page cursor */
+ buf_block_t* left_block; /*!< this field is used to store
a pointer to the left neighbor
page, in the cases
BTR_SEARCH_PREV and
BTR_MODIFY_PREV */
/*------------------------------*/
- que_thr_t* thr; /* this field is only used when
- btr_cur_search_... is called for an
- index entry insertion: the calling
- query thread is passed here to be
+ que_thr_t* thr; /*!< this field is only used
+ when btr_cur_search_to_nth_level
+ is called for an index entry
+ insertion: the calling query
+ thread is passed here to be
used in the insert buffer */
/*------------------------------*/
- /* The following fields are used in btr_cur_search... to pass
- information: */
- ulint flag; /* BTR_CUR_HASH, BTR_CUR_HASH_FAIL,
- BTR_CUR_BINARY, or
- BTR_CUR_INSERT_TO_IBUF */
- ulint tree_height; /* Tree height if the search is done
+ /** The following fields are used in
+ btr_cur_search_to_nth_level to pass information: */
+ /* @{ */
+ enum btr_cur_method flag; /*!< Search method used */
+ ulint tree_height; /*!< Tree height if the search is done
for a pessimistic insert or update
operation */
- ulint up_match; /* If the search mode was PAGE_CUR_LE,
+ ulint up_match; /*!< If the search mode was PAGE_CUR_LE,
the number of matched fields to the
the first user record to the right of
the cursor record after
- btr_cur_search_...;
+ btr_cur_search_to_nth_level;
for the mode PAGE_CUR_GE, the matched
fields to the first user record AT THE
CURSOR or to the right of it;
@@ -653,87 +661,90 @@ struct btr_cur_struct {
record if that record is on a
different leaf page! (See the note in
row_ins_duplicate_key.) */
- ulint up_bytes; /* number of matched bytes to the
+ ulint up_bytes; /*!< number of matched bytes to the
right at the time cursor positioned;
only used internally in searches: not
defined after the search */
- ulint low_match; /* if search mode was PAGE_CUR_LE,
+ ulint low_match; /*!< if search mode was PAGE_CUR_LE,
the number of matched fields to the
first user record AT THE CURSOR or
to the left of it after
- btr_cur_search_...;
+ btr_cur_search_to_nth_level;
NOT defined for PAGE_CUR_GE or any
other search modes; see also the NOTE
in up_match! */
- ulint low_bytes; /* number of matched bytes to the
+ ulint low_bytes; /*!< number of matched bytes to the
right at the time cursor positioned;
only used internally in searches: not
defined after the search */
- ulint n_fields; /* prefix length used in a hash
+ ulint n_fields; /*!< prefix length used in a hash
search if hash_node != NULL */
- ulint n_bytes; /* hash prefix bytes if hash_node !=
+ ulint n_bytes; /*!< hash prefix bytes if hash_node !=
NULL */
- ulint fold; /* fold value used in the search if
+ ulint fold; /*!< fold value used in the search if
flag is BTR_CUR_HASH */
/*------------------------------*/
- btr_path_t* path_arr; /* in estimating the number of
+ /* @} */
+ btr_path_t* path_arr; /*!< in estimating the number of
rows in range, we store in this array
information of the path through
the tree */
};
-/* Values for the flag documenting the used search method */
-#define BTR_CUR_HASH 1 /* successful shortcut using the hash
- index */
-#define BTR_CUR_HASH_FAIL 2 /* failure using hash, success using
- binary search: the misleading hash
- reference is stored in the field
- hash_node, and might be necessary to
- update */
-#define BTR_CUR_BINARY 3 /* success using the binary search */
-#define BTR_CUR_INSERT_TO_IBUF 4 /* performed the intended insert to
- the insert buffer */
-
-/* If pessimistic delete fails because of lack of file space,
-there is still a good change of success a little later: try this many times,
-and sleep this many microseconds in between */
+/** If pessimistic delete fails because of lack of file space, there
+is still a good change of success a little later. Try this many
+times. */
#define BTR_CUR_RETRY_DELETE_N_TIMES 100
+/** If pessimistic delete fails because of lack of file space, there
+is still a good change of success a little later. Sleep this many
+microseconds between retries. */
#define BTR_CUR_RETRY_SLEEP_TIME 50000
-/* The reference in a field for which data is stored on a different page.
+/** The reference in a field for which data is stored on a different page.
The reference is at the end of the 'locally' stored part of the field.
'Locally' means storage in the index record.
We store locally a long enough prefix of each column so that we can determine
the ordering parts of each index record without looking into the externally
stored part. */
-
-/*--------------------------------------*/
-#define BTR_EXTERN_SPACE_ID 0 /* space id where stored */
-#define BTR_EXTERN_PAGE_NO 4 /* page no where stored */
-#define BTR_EXTERN_OFFSET 8 /* offset of BLOB header
+/*-------------------------------------- @{ */
+#define BTR_EXTERN_SPACE_ID 0 /*!< space id where stored */
+#define BTR_EXTERN_PAGE_NO 4 /*!< page no where stored */
+#define BTR_EXTERN_OFFSET 8 /*!< offset of BLOB header
on that page */
-#define BTR_EXTERN_LEN 12 /* 8 bytes containing the
+#define BTR_EXTERN_LEN 12 /*!< 8 bytes containing the
length of the externally
stored part of the BLOB.
The 2 highest bits are
reserved to the flags below. */
-/*--------------------------------------*/
+/*-------------------------------------- @} */
/* #define BTR_EXTERN_FIELD_REF_SIZE 20 // moved to btr0types.h */
-/* The highest bit of BTR_EXTERN_LEN (i.e., the highest bit of the byte
-at lowest address) is set to 1 if this field does not 'own' the externally
-stored field; only the owner field is allowed to free the field in purge!
-If the 2nd highest bit is 1 then it means that the externally stored field
-was inherited from an earlier version of the row. In rollback we are not
-allowed to free an inherited external field. */
-
+/** The most significant bit of BTR_EXTERN_LEN (i.e., the most
+significant bit of the byte at smallest address) is set to 1 if this
+field does not 'own' the externally stored field; only the owner field
+is allowed to free the field in purge! */
#define BTR_EXTERN_OWNER_FLAG 128
+/** If the second most significant bit of BTR_EXTERN_LEN (i.e., the
+second most significant bit of the byte at smallest address) is 1 then
+it means that the externally stored field was inherited from an
+earlier version of the row. In rollback we are not allowed to free an
+inherited external field. */
#define BTR_EXTERN_INHERITED_FLAG 64
+/** Number of searches down the B-tree in btr_cur_search_to_nth_level(). */
extern ulint btr_cur_n_non_sea;
+/** Number of successful adaptive hash index lookups in
+btr_cur_search_to_nth_level(). */
extern ulint btr_cur_n_sea;
+/** Old value of btr_cur_n_non_sea. Copied by
+srv_refresh_innodb_monitor_stats(). Referenced by
+srv_printf_innodb_monitor(). */
extern ulint btr_cur_n_non_sea_old;
+/** Old value of btr_cur_n_sea. Copied by
+srv_refresh_innodb_monitor_stats(). Referenced by
+srv_printf_innodb_monitor(). */
extern ulint btr_cur_n_sea_old;
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "btr0cur.ic"
diff --git a/storage/xtradb/include/btr0cur.ic b/storage/xtradb/include/btr0cur.ic
index 84a3a5cba0b..280583f6ccf 100644
--- a/storage/xtradb/include/btr0cur.ic
+++ b/storage/xtradb/include/btr0cur.ic
@@ -16,110 +16,110 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0cur.ic
The index tree cursor
Created 10/16/1994 Heikki Tuuri
*******************************************************/
+#ifndef UNIV_HOTBACKUP
#include "btr0btr.h"
#ifdef UNIV_DEBUG
-/*************************************************************
-Returns the page cursor component of a tree cursor. */
+/*********************************************************//**
+Returns the page cursor component of a tree cursor.
+@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_cur_get_page_cur(
/*=================*/
- /* out: pointer to page cursor
- component */
- const btr_cur_t* cursor) /* in: tree cursor */
+ const btr_cur_t* cursor) /*!< in: tree cursor */
{
return(&((btr_cur_t*) cursor)->page_cur);
}
#endif /* UNIV_DEBUG */
-/*************************************************************
-Returns the buffer block on which the tree cursor is positioned. */
+/*********************************************************//**
+Returns the buffer block on which the tree cursor is positioned.
+@return pointer to buffer block */
UNIV_INLINE
buf_block_t*
btr_cur_get_block(
/*==============*/
- /* out: pointer to buffer block */
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_cur_get_block(btr_cur_get_page_cur(cursor)));
}
-/*************************************************************
-Returns the record pointer of a tree cursor. */
+/*********************************************************//**
+Returns the record pointer of a tree cursor.
+@return pointer to record */
UNIV_INLINE
rec_t*
btr_cur_get_rec(
/*============*/
- /* out: pointer to record */
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_cur_get_rec(&(cursor->page_cur)));
}
-/*************************************************************
-Returns the compressed page on which the tree cursor is positioned. */
+/*********************************************************//**
+Returns the compressed page on which the tree cursor is positioned.
+@return pointer to compressed page, or NULL if the page is not compressed */
UNIV_INLINE
page_zip_des_t*
btr_cur_get_page_zip(
/*=================*/
- /* out: pointer to compressed page,
- or NULL if the page is not compressed */
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
return(buf_block_get_page_zip(btr_cur_get_block(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Invalidates a tree cursor by setting record pointer to NULL. */
UNIV_INLINE
void
btr_cur_invalidate(
/*===============*/
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
page_cur_invalidate(&(cursor->page_cur));
}
-/*************************************************************
-Returns the page of a tree cursor. */
+/*********************************************************//**
+Returns the page of a tree cursor.
+@return pointer to page */
UNIV_INLINE
page_t*
btr_cur_get_page(
/*=============*/
- /* out: pointer to page */
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_align(page_cur_get_rec(&(cursor->page_cur))));
}
-/*************************************************************
-Returns the index of a cursor. */
+/*********************************************************//**
+Returns the index of a cursor.
+@return index */
UNIV_INLINE
dict_index_t*
btr_cur_get_index(
/*==============*/
- /* out: index */
- btr_cur_t* cursor) /* in: B-tree cursor */
+ btr_cur_t* cursor) /*!< in: B-tree cursor */
{
return(cursor->index);
}
-/*************************************************************
+/*********************************************************//**
Positions a tree cursor at a given record. */
UNIV_INLINE
void
btr_cur_position(
/*=============*/
- dict_index_t* index, /* in: index */
- rec_t* rec, /* in: record in tree */
- buf_block_t* block, /* in: buffer block of rec */
- btr_cur_t* cursor) /* out: cursor */
+ dict_index_t* index, /*!< in: index */
+ rec_t* rec, /*!< in: record in tree */
+ buf_block_t* block, /*!< in: buffer block of rec */
+ btr_cur_t* cursor) /*!< out: cursor */
{
ut_ad(page_align(rec) == block->frame);
@@ -128,16 +128,16 @@ btr_cur_position(
cursor->index = index;
}
-/*************************************************************************
+/*********************************************************************//**
Checks if compressing an index page where a btr cursor is placed makes
-sense. */
+sense.
+@return TRUE if compression is recommended */
UNIV_INLINE
ibool
btr_cur_compress_recommendation(
/*============================*/
- /* out: TRUE if compression is recommended */
- btr_cur_t* cursor, /* in: btr cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_cur_t* cursor, /*!< in: btr cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
@@ -162,18 +162,17 @@ btr_cur_compress_recommendation(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if the record on which the cursor is placed can be deleted without
-making tree compression necessary (or, recommended). */
+making tree compression necessary (or, recommended).
+@return TRUE if can be deleted without recommended compression */
UNIV_INLINE
ibool
btr_cur_can_delete_without_compress(
/*================================*/
- /* out: TRUE if can be deleted without
- recommended compression */
- btr_cur_t* cursor, /* in: btr cursor */
- ulint rec_size,/* in: rec_get_size(btr_cur_get_rec(cursor))*/
- mtr_t* mtr) /* in: mtr */
+ btr_cur_t* cursor, /*!< in: btr cursor */
+ ulint rec_size,/*!< in: rec_get_size(btr_cur_get_rec(cursor))*/
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
@@ -198,3 +197,4 @@ btr_cur_can_delete_without_compress(
return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/btr0pcur.h b/storage/xtradb/include/btr0pcur.h
index 1fdd102d32a..12b1375d8b7 100644
--- a/storage/xtradb/include/btr0pcur.h
+++ b/storage/xtradb/include/btr0pcur.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0pcur.h
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
@@ -45,114 +46,112 @@ of a scroll cursor easier */
#define BTR_PCUR_BEFORE_FIRST_IN_TREE 4 /* in an empty tree */
#define BTR_PCUR_AFTER_LAST_IN_TREE 5 /* in an empty tree */
-/******************************************************************
-Allocates memory for a persistent cursor object and initializes the cursor. */
+/**************************************************************//**
+Allocates memory for a persistent cursor object and initializes the cursor.
+@return own: persistent cursor */
UNIV_INTERN
btr_pcur_t*
btr_pcur_create_for_mysql(void);
/*============================*/
- /* out, own: persistent cursor */
-/******************************************************************
+/**************************************************************//**
Frees the memory for a persistent cursor object. */
UNIV_INTERN
void
btr_pcur_free_for_mysql(
/*====================*/
- btr_pcur_t* cursor); /* in, own: persistent cursor */
-/******************************************************************
+ btr_pcur_t* cursor); /*!< in, own: persistent cursor */
+/**************************************************************//**
Copies the stored position of a pcur to another pcur. */
UNIV_INTERN
void
btr_pcur_copy_stored_position(
/*==========================*/
- btr_pcur_t* pcur_receive, /* in: pcur which will receive the
+ btr_pcur_t* pcur_receive, /*!< in: pcur which will receive the
position info */
- btr_pcur_t* pcur_donate); /* in: pcur from which the info is
+ btr_pcur_t* pcur_donate); /*!< in: pcur from which the info is
copied */
-/******************************************************************
+/**************************************************************//**
Sets the old_rec_buf field to NULL. */
UNIV_INLINE
void
btr_pcur_init(
/*==========*/
- btr_pcur_t* pcur); /* in: persistent cursor */
-/******************************************************************
+ btr_pcur_t* pcur); /*!< in: persistent cursor */
+/**************************************************************//**
Initializes and opens a persistent cursor to an index tree. It should be
closed with btr_pcur_close. */
UNIV_INLINE
void
btr_pcur_open(
/*==========*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page from the
record! */
- ulint latch_mode,/* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Opens an persistent cursor to an index tree without initializing the
cursor. */
UNIV_INLINE
void
btr_pcur_open_with_no_init(
/*=======================*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page of the
record! */
- ulint latch_mode,/* in: BTR_SEARCH_LEAF, ...;
+ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
NOTE that if has_search_latch != 0 then
we maybe do not acquire a latch on the cursor
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 */
- ulint has_search_latch,/* in: latch mode the caller
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, or 0 */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
UNIV_INLINE
void
btr_pcur_open_at_index_side(
/*========================*/
- ibool from_left, /* in: TRUE if open to the low end,
+ ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: latch mode */
- btr_pcur_t* pcur, /* in: cursor */
- ibool do_init, /* in: TRUE if should be initialized */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
-Gets the up_match value for a pcur after a search. */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: latch mode */
+ btr_pcur_t* pcur, /*!< in: cursor */
+ ibool do_init, /*!< in: TRUE if should be initialized */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
+Gets the up_match value for a pcur after a search.
+@return number of matched fields at the cursor or to the right if
+search mode was PAGE_CUR_GE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_up_match(
/*==================*/
- /* out: number of matched fields at the cursor
- or to the right if search mode was PAGE_CUR_GE,
- otherwise undefined */
- btr_pcur_t* cursor); /* in: memory buffer for persistent cursor */
-/******************************************************************
-Gets the low_match value for a pcur after a search. */
+ btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */
+/**************************************************************//**
+Gets the low_match value for a pcur after a search.
+@return number of matched fields at the cursor or to the right if
+search mode was PAGE_CUR_LE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_low_match(
/*===================*/
- /* out: number of matched fields at the cursor
- or to the right if search mode was PAGE_CUR_LE,
- otherwise undefined */
- btr_pcur_t* cursor); /* in: memory buffer for persistent cursor */
-/******************************************************************
+ btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */
+/**************************************************************//**
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
user record satisfying the search condition, in the case PAGE_CUR_L or
PAGE_CUR_LE, on the last user record. If no such user record exists, then
@@ -163,33 +162,33 @@ UNIV_INTERN
void
btr_pcur_open_on_user_rec(
/*======================*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ... */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF or
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ... */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- btr_pcur_t* cursor, /* in: memory buffer for persistent
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INLINE
void
btr_pcur_open_at_rnd_pos(
/*=====================*/
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in/out: B-tree pcur */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in/out: B-tree pcur */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Frees the possible old_rec_buf buffer of a persistent cursor and sets the
latch mode of the persistent cursor to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_close(
/*===========*/
- btr_pcur_t* cursor); /* in: persistent cursor */
-/******************************************************************
+ btr_pcur_t* cursor); /*!< in: persistent cursor */
+/**************************************************************//**
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
cursor data structure, or just setting a flag if the cursor id before the
@@ -200,9 +199,9 @@ UNIV_INTERN
void
btr_pcur_store_position(
/*====================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Restores the stored position of a persistent cursor bufferfixing the page and
obtaining the specified latches. If the cursor position was saved when the
(1) cursor was positioned on a user record: this function restores the position
@@ -213,20 +212,18 @@ infimum;
(3) cursor was positioned on the page supremum: restores to the first record
GREATER than the user record which was the predecessor of the supremum.
(4) cursor was positioned before the first or after the last in an empty tree:
-restores to before first or after the last in the tree. */
+restores to before first or after the last in the tree.
+@return TRUE if the cursor position was stored when it was on a user
+record and it can be restored on a user record whose ordering fields
+are identical to the ones of the original user record */
UNIV_INTERN
ibool
btr_pcur_restore_position(
/*======================*/
- /* out: TRUE if the cursor position
- was stored when it was on a user record
- and it can be restored on a user record
- whose ordering fields are identical to
- the ones of the original user record */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in: detached persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in: detached persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
releases the page latch and bufferfix reserved by the cursor.
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
@@ -236,33 +233,33 @@ UNIV_INTERN
void
btr_pcur_release_leaf(
/*==================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
-Gets the rel_pos field for a cursor whose position has been stored. */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
+Gets the rel_pos field for a cursor whose position has been stored.
+@return BTR_PCUR_ON, ... */
UNIV_INLINE
ulint
btr_pcur_get_rel_pos(
/*=================*/
- /* out: BTR_PCUR_ON, ... */
- const btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ const btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Sets the mtr field for a pcur. */
UNIV_INLINE
void
btr_pcur_set_mtr(
/*=============*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in, own: mtr */
-/*************************************************************
-Gets the mtr field for a pcur. */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in, own: mtr */
+/*********************************************************//**
+Gets the mtr field for a pcur.
+@return mtr */
UNIV_INLINE
mtr_t*
btr_pcur_get_mtr(
/*=============*/
- /* out: mtr */
- btr_pcur_t* cursor); /* in: persistent cursor */
-/******************************************************************
+ btr_pcur_t* cursor); /*!< in: persistent cursor */
+/**************************************************************//**
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
that is, the cursor becomes detached. If there have been modifications
to the page where pcur is positioned, this can be used instead of
@@ -272,68 +269,65 @@ UNIV_INLINE
void
btr_pcur_commit(
/*============*/
- btr_pcur_t* pcur); /* in: persistent cursor */
-/******************************************************************
+ btr_pcur_t* pcur); /*!< in: persistent cursor */
+/**************************************************************//**
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
UNIV_INLINE
void
btr_pcur_commit_specify_mtr(
/*========================*/
- btr_pcur_t* pcur, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr to commit */
-/******************************************************************
-Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. */
+ btr_pcur_t* pcur, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr to commit */
+/**************************************************************//**
+Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
+@return TRUE if detached */
UNIV_INLINE
ibool
btr_pcur_is_detached(
/*=================*/
- /* out: TRUE if detached */
- btr_pcur_t* pcur); /* in: persistent cursor */
-/*************************************************************
+ btr_pcur_t* pcur); /*!< in: persistent cursor */
+/*********************************************************//**
Moves the persistent cursor to the next record in the tree. If no records are
-left, the cursor stays 'after last in tree'. */
+left, the cursor stays 'after last in tree'.
+@return TRUE if the cursor was not after last in tree */
UNIV_INLINE
ibool
btr_pcur_move_to_next(
/*==================*/
- /* out: TRUE if the cursor was not after last
- in tree */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the previous record in the tree. If no records
-are left, the cursor stays 'before first in tree'. */
+are left, the cursor stays 'before first in tree'.
+@return TRUE if the cursor was not before first in tree */
UNIV_INTERN
ibool
btr_pcur_move_to_prev(
/*==================*/
- /* out: TRUE if the cursor was not before first
- in tree */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the last record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_last_on_page(
/*==========================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the next user record in the tree. If no user
-records are left, the cursor ends up 'after last in tree'. */
+records are left, the cursor ends up 'after last in tree'.
+@return TRUE if the cursor moved forward, ending on a user record */
UNIV_INLINE
ibool
btr_pcur_move_to_next_user_rec(
/*===========================*/
- /* out: TRUE if the cursor moved forward,
- ending on a user record */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the first record on the next page.
Releases the latch on the current page, and bufferunfixes it.
Note that there must not be modifications on the current page,
@@ -342,10 +336,10 @@ UNIV_INTERN
void
btr_pcur_move_to_next_page(
/*=======================*/
- btr_pcur_t* cursor, /* in: persistent cursor; must be on the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; must be on the
last record of the current page */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor backward if it is on the first record
of the page. Releases the latch on the current page, and bufferunfixes
it. Note that to prevent a possible deadlock, the operation first
@@ -359,119 +353,117 @@ UNIV_INTERN
void
btr_pcur_move_backward_from_page(
/*=============================*/
- btr_pcur_t* cursor, /* in: persistent cursor, must be on the
+ btr_pcur_t* cursor, /*!< in: persistent cursor, must be on the
first record of the current page */
- mtr_t* mtr); /* in: mtr */
+ mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_DEBUG
-/*************************************************************
-Returns the btr cursor component of a persistent cursor. */
+/*********************************************************//**
+Returns the btr cursor component of a persistent cursor.
+@return pointer to btr cursor component */
UNIV_INLINE
btr_cur_t*
btr_pcur_get_btr_cur(
/*=================*/
- /* out: pointer to
- btr cursor component */
- const btr_pcur_t* cursor); /* in: persistent cursor */
-/*************************************************************
-Returns the page cursor component of a persistent cursor. */
+ const btr_pcur_t* cursor); /*!< in: persistent cursor */
+/*********************************************************//**
+Returns the page cursor component of a persistent cursor.
+@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_pcur_get_page_cur(
/*==================*/
- /* out: pointer to
- page cursor component */
- const btr_pcur_t* cursor); /* in: persistent cursor */
+ const btr_pcur_t* cursor); /*!< in: persistent cursor */
#else /* UNIV_DEBUG */
# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur)
# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur)
#endif /* UNIV_DEBUG */
-/*************************************************************
-Returns the page of a persistent cursor. */
+/*********************************************************//**
+Returns the page of a persistent cursor.
+@return pointer to the page */
UNIV_INLINE
page_t*
btr_pcur_get_page(
/*==============*/
- /* out: pointer to the page */
- btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
-Returns the buffer block of a persistent cursor. */
+ btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
+Returns the buffer block of a persistent cursor.
+@return pointer to the block */
UNIV_INLINE
buf_block_t*
btr_pcur_get_block(
/*===============*/
- /* out: pointer to the block */
- btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
-Returns the record of a persistent cursor. */
+ btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
+Returns the record of a persistent cursor.
+@return pointer to the record */
UNIV_INLINE
rec_t*
btr_pcur_get_rec(
/*=============*/
- /* out: pointer to the record */
- btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Checks if the persistent cursor is on a user record. */
UNIV_INLINE
ibool
btr_pcur_is_on_user_rec(
/*====================*/
- const btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ const btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Checks if the persistent cursor is after the last user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_on_page(
/*===========================*/
- const btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ const btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Checks if the persistent cursor is before the first user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_on_page(
/*=============================*/
- const btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ const btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Checks if the persistent cursor is before the first user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_in_tree(
/*=============================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Checks if the persistent cursor is after the last user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_in_tree(
/*===========================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the next record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_next_on_page(
/*==========================*/
- btr_pcur_t* cursor);/* in/out: persistent cursor */
-/*************************************************************
+ btr_pcur_t* cursor);/*!< in/out: persistent cursor */
+/*********************************************************//**
Moves the persistent cursor to the previous record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_prev_on_page(
/*==========================*/
- btr_pcur_t* cursor);/* in/out: persistent cursor */
+ btr_pcur_t* cursor);/*!< in/out: persistent cursor */
/* The persistent B-tree cursor structure. This is used mainly for SQL
selects, updates, and deletes. */
struct btr_pcur_struct{
- btr_cur_t btr_cur; /* a B-tree cursor */
- ulint latch_mode; /* see TODO note below!
+ btr_cur_t btr_cur; /*!< a B-tree cursor */
+ ulint latch_mode; /*!< see TODO note below!
BTR_SEARCH_LEAF, BTR_MODIFY_LEAF,
BTR_MODIFY_TREE, or BTR_NO_LATCHES,
depending on the latching state of
@@ -482,28 +474,28 @@ struct btr_pcur_struct{
detached; it can be restored to
attached if the old position was
stored in old_rec */
- ulint old_stored; /* BTR_PCUR_OLD_STORED
+ ulint old_stored; /*!< BTR_PCUR_OLD_STORED
or BTR_PCUR_OLD_NOT_STORED */
- rec_t* old_rec; /* if cursor position is stored,
+ rec_t* old_rec; /*!< if cursor position is stored,
contains an initial segment of the
latest record cursor was positioned
either on, before, or after */
- ulint old_n_fields; /* number of fields in old_rec */
- ulint rel_pos; /* BTR_PCUR_ON, BTR_PCUR_BEFORE, or
+ ulint old_n_fields; /*!< number of fields in old_rec */
+ ulint rel_pos; /*!< BTR_PCUR_ON, BTR_PCUR_BEFORE, or
BTR_PCUR_AFTER, depending on whether
cursor was on, before, or after the
old_rec record */
buf_block_t* block_when_stored;/* buffer block when the position was
stored */
- ib_uint64_t modify_clock; /* the modify clock value of the
+ ib_uint64_t modify_clock; /*!< the modify clock value of the
buffer block when the cursor position
was stored */
- ulint pos_state; /* see TODO note below!
+ ulint pos_state; /*!< see TODO note below!
BTR_PCUR_IS_POSITIONED,
BTR_PCUR_WAS_POSITIONED,
BTR_PCUR_NOT_POSITIONED */
- ulint search_mode; /* PAGE_CUR_G, ... */
- trx_t* trx_if_known; /* the transaction, if we know it;
+ ulint search_mode; /*!< PAGE_CUR_G, ... */
+ trx_t* trx_if_known; /*!< the transaction, if we know it;
otherwise this field is not defined;
can ONLY BE USED in error prints in
fatal assertion failures! */
@@ -511,12 +503,12 @@ struct btr_pcur_struct{
/* NOTE that the following fields may possess dynamically allocated
memory which should be freed if not needed anymore! */
- mtr_t* mtr; /* NULL, or this field may contain
+ mtr_t* mtr; /*!< NULL, or this field may contain
a mini-transaction which holds the
latch on the cursor page */
- byte* old_rec_buf; /* NULL, or a dynamically allocated
+ byte* old_rec_buf; /*!< NULL, or a dynamically allocated
buffer for old_rec */
- ulint buf_size; /* old_rec_buf size if old_rec_buf
+ ulint buf_size; /*!< old_rec_buf size if old_rec_buf
is not NULL */
};
diff --git a/storage/xtradb/include/btr0pcur.ic b/storage/xtradb/include/btr0pcur.ic
index bde7413820a..0ca7223f861 100644
--- a/storage/xtradb/include/btr0pcur.ic
+++ b/storage/xtradb/include/btr0pcur.ic
@@ -16,21 +16,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0pcur.ic
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
*******************************************************/
-/*************************************************************
-Gets the rel_pos field for a cursor whose position has been stored. */
+/*********************************************************//**
+Gets the rel_pos field for a cursor whose position has been stored.
+@return BTR_PCUR_ON, ... */
UNIV_INLINE
ulint
btr_pcur_get_rel_pos(
/*=================*/
- /* out: BTR_PCUR_ON, ... */
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor);
ut_ad(cursor->old_rec);
@@ -41,28 +42,28 @@ btr_pcur_get_rel_pos(
return(cursor->rel_pos);
}
-/*************************************************************
+/*********************************************************//**
Sets the mtr field for a pcur. */
UNIV_INLINE
void
btr_pcur_set_mtr(
/*=============*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in, own: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in, own: mtr */
{
ut_ad(cursor);
cursor->mtr = mtr;
}
-/*************************************************************
-Gets the mtr field for a pcur. */
+/*********************************************************//**
+Gets the mtr field for a pcur.
+@return mtr */
UNIV_INLINE
mtr_t*
btr_pcur_get_mtr(
/*=============*/
- /* out: mtr */
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor);
@@ -70,69 +71,67 @@ btr_pcur_get_mtr(
}
#ifdef UNIV_DEBUG
-/*************************************************************
-Returns the btr cursor component of a persistent cursor. */
+/*********************************************************//**
+Returns the btr cursor component of a persistent cursor.
+@return pointer to btr cursor component */
UNIV_INLINE
btr_cur_t*
btr_pcur_get_btr_cur(
/*=================*/
- /* out: pointer to
- btr cursor component */
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
const btr_cur_t* btr_cur = &cursor->btr_cur;
return((btr_cur_t*) btr_cur);
}
-/*************************************************************
-Returns the page cursor component of a persistent cursor. */
+/*********************************************************//**
+Returns the page cursor component of a persistent cursor.
+@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_pcur_get_page_cur(
/*==================*/
- /* out: pointer to page cursor
- component */
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
return(btr_cur_get_page_cur(btr_pcur_get_btr_cur(cursor)));
}
#endif /* UNIV_DEBUG */
-/*************************************************************
-Returns the page of a persistent cursor. */
+/*********************************************************//**
+Returns the page of a persistent cursor.
+@return pointer to the page */
UNIV_INLINE
page_t*
btr_pcur_get_page(
/*==============*/
- /* out: pointer to the page */
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
return(btr_cur_get_page(btr_pcur_get_btr_cur(cursor)));
}
-/*************************************************************
-Returns the buffer block of a persistent cursor. */
+/*********************************************************//**
+Returns the buffer block of a persistent cursor.
+@return pointer to the block */
UNIV_INLINE
buf_block_t*
btr_pcur_get_block(
/*===============*/
- /* out: pointer to the block */
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
return(btr_cur_get_block(btr_pcur_get_btr_cur(cursor)));
}
-/*************************************************************
-Returns the record of a persistent cursor. */
+/*********************************************************//**
+Returns the record of a persistent cursor.
+@return pointer to the record */
UNIV_INLINE
rec_t*
btr_pcur_get_rec(
/*=============*/
- /* out: pointer to the record */
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -140,16 +139,15 @@ btr_pcur_get_rec(
return(btr_cur_get_rec(btr_pcur_get_btr_cur(cursor)));
}
-/******************************************************************
-Gets the up_match value for a pcur after a search. */
+/**************************************************************//**
+Gets the up_match value for a pcur after a search.
+@return number of matched fields at the cursor or to the right if
+search mode was PAGE_CUR_GE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_up_match(
/*==================*/
- /* out: number of matched fields at the cursor
- or to the right if search mode was PAGE_CUR_GE,
- otherwise undefined */
- btr_pcur_t* cursor) /* in: memory buffer for persistent cursor */
+ btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */
{
btr_cur_t* btr_cursor;
@@ -163,16 +161,15 @@ btr_pcur_get_up_match(
return(btr_cursor->up_match);
}
-/******************************************************************
-Gets the low_match value for a pcur after a search. */
+/**************************************************************//**
+Gets the low_match value for a pcur after a search.
+@return number of matched fields at the cursor or to the right if
+search mode was PAGE_CUR_LE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_low_match(
/*===================*/
- /* out: number of matched fields at the cursor
- or to the right if search mode was PAGE_CUR_LE,
- otherwise undefined */
- btr_pcur_t* cursor) /* in: memory buffer for persistent cursor */
+ btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */
{
btr_cur_t* btr_cursor;
@@ -185,14 +182,14 @@ btr_pcur_get_low_match(
return(btr_cursor->low_match);
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is after the last user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_on_page(
/*===========================*/
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -200,14 +197,14 @@ btr_pcur_is_after_last_on_page(
return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is before the first user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_on_page(
/*=============================*/
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -215,13 +212,13 @@ btr_pcur_is_before_first_on_page(
return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is on a user record. */
UNIV_INLINE
ibool
btr_pcur_is_on_user_rec(
/*====================*/
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -235,15 +232,15 @@ btr_pcur_is_on_user_rec(
return(TRUE);
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is before the first user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_in_tree(
/*=============================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -256,15 +253,15 @@ btr_pcur_is_before_first_in_tree(
return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is after the last user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_in_tree(
/*===========================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -277,13 +274,13 @@ btr_pcur_is_after_last_in_tree(
return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the next record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_next_on_page(
/*==========================*/
- btr_pcur_t* cursor) /* in/out: persistent cursor */
+ btr_pcur_t* cursor) /*!< in/out: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -293,13 +290,13 @@ btr_pcur_move_to_next_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the previous record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_prev_on_page(
/*==========================*/
- btr_pcur_t* cursor) /* in/out: persistent cursor */
+ btr_pcur_t* cursor) /*!< in/out: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -309,14 +306,14 @@ btr_pcur_move_to_prev_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the last record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_last_on_page(
/*==========================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
UT_NOT_USED(mtr);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -327,18 +324,17 @@ btr_pcur_move_to_last_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the next user record in the tree. If no user
-records are left, the cursor ends up 'after last in tree'. */
+records are left, the cursor ends up 'after last in tree'.
+@return TRUE if the cursor moved forward, ending on a user record */
UNIV_INLINE
ibool
btr_pcur_move_to_next_user_rec(
/*===========================*/
- /* out: TRUE if the cursor moved forward,
- ending on a user record */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -364,18 +360,17 @@ loop:
goto loop;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the next record in the tree. If no records are
-left, the cursor stays 'after last in tree'. */
+left, the cursor stays 'after last in tree'.
+@return TRUE if the cursor was not after last in tree */
UNIV_INLINE
ibool
btr_pcur_move_to_next(
/*==================*/
- /* out: TRUE if the cursor was not after last
- in tree */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -399,7 +394,7 @@ btr_pcur_move_to_next(
return(TRUE);
}
-/******************************************************************
+/**************************************************************//**
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
that is, the cursor becomes detached. If there have been modifications
to the page where pcur is positioned, this can be used instead of
@@ -409,7 +404,7 @@ UNIV_INLINE
void
btr_pcur_commit(
/*============*/
- btr_pcur_t* pcur) /* in: persistent cursor */
+ btr_pcur_t* pcur) /*!< in: persistent cursor */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@@ -420,14 +415,14 @@ btr_pcur_commit(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
-/******************************************************************
+/**************************************************************//**
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
UNIV_INLINE
void
btr_pcur_commit_specify_mtr(
/*========================*/
- btr_pcur_t* pcur, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr to commit */
+ btr_pcur_t* pcur, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr to commit */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@@ -438,13 +433,13 @@ btr_pcur_commit_specify_mtr(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
-/******************************************************************
+/**************************************************************//**
Sets the pcur latch mode to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_detach(
/*============*/
- btr_pcur_t* pcur) /* in: persistent cursor */
+ btr_pcur_t* pcur) /*!< in: persistent cursor */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@@ -453,14 +448,14 @@ btr_pcur_detach(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
-/******************************************************************
-Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. */
+/**************************************************************//**
+Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
+@return TRUE if detached */
UNIV_INLINE
ibool
btr_pcur_is_detached(
/*=================*/
- /* out: TRUE if detached */
- btr_pcur_t* pcur) /* in: persistent cursor */
+ btr_pcur_t* pcur) /*!< in: persistent cursor */
{
if (pcur->latch_mode == BTR_NO_LATCHES) {
@@ -470,37 +465,37 @@ btr_pcur_is_detached(
return(FALSE);
}
-/******************************************************************
+/**************************************************************//**
Sets the old_rec_buf field to NULL. */
UNIV_INLINE
void
btr_pcur_init(
/*==========*/
- btr_pcur_t* pcur) /* in: persistent cursor */
+ btr_pcur_t* pcur) /*!< in: persistent cursor */
{
pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
pcur->old_rec_buf = NULL;
pcur->old_rec = NULL;
}
-/******************************************************************
+/**************************************************************//**
Initializes and opens a persistent cursor to an index tree. It should be
closed with btr_pcur_close. */
UNIV_INLINE
void
btr_pcur_open(
/*==========*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page from the
record! */
- ulint latch_mode,/* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
btr_cur_t* btr_cursor;
@@ -522,31 +517,31 @@ btr_pcur_open(
cursor->trx_if_known = NULL;
}
-/******************************************************************
+/**************************************************************//**
Opens an persistent cursor to an index tree without initializing the
cursor. */
UNIV_INLINE
void
btr_pcur_open_with_no_init(
/*=======================*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page of the
record! */
- ulint latch_mode,/* in: BTR_SEARCH_LEAF, ...;
+ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
NOTE that if has_search_latch != 0 then
we maybe do not acquire a latch on the cursor
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 */
- ulint has_search_latch,/* in: latch mode the caller
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, or 0 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
btr_cur_t* btr_cursor;
@@ -566,19 +561,19 @@ btr_pcur_open_with_no_init(
cursor->trx_if_known = NULL;
}
-/*********************************************************************
+/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
UNIV_INLINE
void
btr_pcur_open_at_index_side(
/*========================*/
- ibool from_left, /* in: TRUE if open to the low end,
+ ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: latch mode */
- btr_pcur_t* pcur, /* in: cursor */
- ibool do_init, /* in: TRUE if should be initialized */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: latch mode */
+ btr_pcur_t* pcur, /*!< in: cursor */
+ ibool do_init, /*!< in: TRUE if should be initialized */
+ mtr_t* mtr) /*!< in: mtr */
{
pcur->latch_mode = latch_mode;
@@ -601,16 +596,16 @@ btr_pcur_open_at_index_side(
pcur->trx_if_known = NULL;
}
-/**************************************************************************
+/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INLINE
void
btr_pcur_open_at_rnd_pos(
/*=====================*/
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in/out: B-tree pcur */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in/out: B-tree pcur */
+ mtr_t* mtr) /*!< in: mtr */
{
/* Initialize the cursor */
@@ -627,14 +622,14 @@ btr_pcur_open_at_rnd_pos(
cursor->trx_if_known = NULL;
}
-/******************************************************************
+/**************************************************************//**
Frees the possible memory heap of a persistent cursor and sets the latch
mode of the persistent cursor to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_close(
/*===========*/
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
if (cursor->old_rec_buf != NULL) {
diff --git a/storage/xtradb/include/btr0sea.h b/storage/xtradb/include/btr0sea.h
index 074e6595258..7f4842d0897 100644
--- a/storage/xtradb/include/btr0sea.h
+++ b/storage/xtradb/include/btr0sea.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/btr0sea.h
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@@ -33,81 +34,87 @@ Created 2/17/1996 Heikki Tuuri
#include "mtr0mtr.h"
#include "ha0ha.h"
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the adaptive search system at a database start. */
UNIV_INTERN
void
btr_search_sys_create(
/*==================*/
- ulint hash_size); /* in: hash index hash table size */
+ ulint hash_size); /*!< in: hash index hash table size */
+/*****************************************************************//**
+Frees the adaptive search system at a database shutdown. */
+UNIV_INTERN
+void
+btr_search_sys_free(void);
+/*=====================*/
-/************************************************************************
+/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
UNIV_INTERN
void
btr_search_disable(void);
/*====================*/
-/************************************************************************
+/********************************************************************//**
Enable the adaptive hash search system. */
UNIV_INTERN
void
btr_search_enable(void);
/*====================*/
-/************************************************************************
-Returns search info for an index. */
+/********************************************************************//**
+Returns search info for an index.
+@return search info; search mutex reserved */
UNIV_INLINE
btr_search_t*
btr_search_get_info(
/*================*/
- /* out: search info; search mutex reserved */
- dict_index_t* index); /* in: index */
-/*********************************************************************
-Creates and initializes a search info struct. */
+ dict_index_t* index); /*!< in: index */
+/*****************************************************************//**
+Creates and initializes a search info struct.
+@return own: search info struct */
UNIV_INTERN
btr_search_t*
btr_search_info_create(
/*===================*/
- /* out, own: search info struct */
- mem_heap_t* heap); /* in: heap where created */
-/*********************************************************************
+ mem_heap_t* heap); /*!< in: heap where created */
+/*****************************************************************//**
Returns the value of ref_count. The value is protected by
-btr_search_latch. */
+btr_search_latch.
+@return ref_count value. */
UNIV_INTERN
ulint
btr_search_info_get_ref_count(
/*==========================*/
- /* out: ref_count value. */
- btr_search_t* info); /* in: search info. */
-/*************************************************************************
+ btr_search_t* info); /*!< in: search info. */
+/*********************************************************************//**
Updates the search info. */
UNIV_INLINE
void
btr_search_info_update(
/*===================*/
- dict_index_t* index, /* in: index of the cursor */
- btr_cur_t* cursor);/* in: cursor which was just positioned */
-/**********************************************************************
+ dict_index_t* index, /*!< in: index of the cursor */
+ btr_cur_t* cursor);/*!< in: cursor which was just positioned */
+/******************************************************************//**
Tries to guess the right search position based on the hash search info
of the index. Note that if mode is PAGE_CUR_LE, which is used in inserts,
and the function returns TRUE, then cursor->up_match and cursor->low_match
-both have sensible values. */
+both have sensible values.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
btr_search_guess_on_hash(
/*=====================*/
- /* out: TRUE if succeeded */
- dict_index_t* index, /* in: index */
- btr_search_t* info, /* in: index search info */
- const dtuple_t* tuple, /* in: logical record */
- ulint mode, /* in: PAGE_CUR_L, ... */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_cur_t* cursor, /* out: tree cursor */
- ulint has_search_latch,/* in: latch mode the caller
+ dict_index_t* index, /*!< in: index */
+ btr_search_t* info, /*!< in: index search info */
+ const dtuple_t* tuple, /*!< in: logical record */
+ ulint mode, /*!< in: PAGE_CUR_L, ... */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_cur_t* cursor, /*!< out: tree cursor */
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, RW_X_LATCH, or 0 */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
Moves or deletes hash entries for moved records. If new_page is already hashed,
then the hash index for page, if any, is dropped. If new_page is not hashed,
and page is hashed, then a new hash index is built to new_page with the same
@@ -116,139 +123,153 @@ UNIV_INTERN
void
btr_search_move_or_delete_hash_entries(
/*===================================*/
- buf_block_t* new_block, /* in: records are copied
+ buf_block_t* new_block, /*!< in: records are copied
to this page */
- buf_block_t* block, /* in: index page from which
+ buf_block_t* block, /*!< in: index page from which
records were copied, and the
copied records will be deleted
from this page */
- dict_index_t* index); /* in: record descriptor */
-/************************************************************************
+ dict_index_t* index); /*!< in: record descriptor */
+/********************************************************************//**
Drops a page hash index. */
UNIV_INTERN
void
btr_search_drop_page_hash_index(
/*============================*/
- buf_block_t* block); /* in: block containing index page,
+ buf_block_t* block); /*!< in: block containing index page,
s- or x-latched, or an index page
for which we know that
block->buf_fix_count == 0 */
/************************************************************************
+Drops a page hash index based on index */
+UNIV_INTERN
+void
+btr_search_drop_page_hash_index_on_index(
+/*=====================================*/
+ dict_index_t* index); /* in: record descriptor */
+/********************************************************************//**
Drops a page hash index when a page is freed from a fseg to the file system.
Drops possible hash index if the page happens to be in the buffer pool. */
UNIV_INTERN
void
btr_search_drop_page_hash_when_freed(
/*=================================*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no); /* in: page number */
-/************************************************************************
+ ulint page_no); /*!< in: page number */
+/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_node_on_insert(
/*==================================*/
- btr_cur_t* cursor);/* in: cursor which was positioned to the
+ btr_cur_t* cursor);/*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_on_insert(
/*=============================*/
- btr_cur_t* cursor);/* in: cursor which was positioned to the
+ btr_cur_t* cursor);/*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is deleted from a page. */
UNIV_INTERN
void
btr_search_update_hash_on_delete(
/*=============================*/
- btr_cur_t* cursor);/* in: cursor which was positioned on the
+ btr_cur_t* cursor);/*!< in: cursor which was positioned on the
record to delete using btr_cur_search_...,
the record is not yet deleted */
-/************************************************************************
-Validates the search system. */
+/********************************************************************//**
+Validates the search system.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_search_validate(void);
/*======================*/
- /* out: TRUE if ok */
-/* Flag: has the search system been enabled?
+/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
extern char btr_search_enabled;
-/* The search info struct in an index */
-
+/** The search info struct in an index */
struct btr_search_struct{
- ulint ref_count; /* Number of blocks in this index tree
+ ulint ref_count; /*!< Number of blocks in this index tree
that have search index built
i.e. block->index points to this index.
Protected by btr_search_latch except
when during initialization in
btr_search_info_create(). */
- /* The following fields are not protected by any latch.
+ /* @{ The following fields are not protected by any latch.
Unfortunately, this means that they must be aligned to
the machine word, i.e., they cannot be turned into bit-fields. */
- buf_block_t* root_guess;/* the root page frame when it was last time
+ buf_block_t* root_guess;/*!< the root page frame when it was last time
fetched, or NULL */
- ulint hash_analysis; /* when this exceeds BTR_SEARCH_HASH_ANALYSIS,
- the hash analysis starts; this is reset if no
+ ulint hash_analysis; /*!< when this exceeds
+ BTR_SEARCH_HASH_ANALYSIS, the hash
+ analysis starts; this is reset if no
success noticed */
- ibool last_hash_succ; /* TRUE if the last search would have
+ ibool last_hash_succ; /*!< TRUE if the last search would have
succeeded, or did succeed, using the hash
index; NOTE that the value here is not exact:
it is not calculated for every search, and the
calculation itself is not always accurate! */
ulint n_hash_potential;
- /* number of consecutive searches
+ /*!< number of consecutive searches
which would have succeeded, or did succeed,
using the hash index;
the range is 0 .. BTR_SEARCH_BUILD_LIMIT + 5 */
- /*----------------------*/
- ulint n_fields; /* recommended prefix length for hash search:
+ /* @} */
+ /*---------------------- @{ */
+ ulint n_fields; /*!< recommended prefix length for hash search:
number of full fields */
- ulint n_bytes; /* recommended prefix: number of bytes in
- an incomplete field;
- see also BTR_PAGE_MAX_REC_SIZE */
- ibool left_side; /* TRUE or FALSE, depending on whether
+ ulint n_bytes; /*!< recommended prefix: number of bytes in
+ an incomplete field
+ @see BTR_PAGE_MAX_REC_SIZE */
+ ibool left_side; /*!< TRUE or FALSE, depending on whether
the leftmost record of several records with
the same prefix should be indexed in the
hash index */
- /*----------------------*/
+ /*---------------------- @} */
#ifdef UNIV_SEARCH_PERF_STAT
- ulint n_hash_succ; /* number of successful hash searches thus
+ ulint n_hash_succ; /*!< number of successful hash searches thus
far */
- ulint n_hash_fail; /* number of failed hash searches */
- ulint n_patt_succ; /* number of successful pattern searches thus
+ ulint n_hash_fail; /*!< number of failed hash searches */
+ ulint n_patt_succ; /*!< number of successful pattern searches thus
far */
- ulint n_searches; /* number of searches */
+ ulint n_searches; /*!< number of searches */
#endif /* UNIV_SEARCH_PERF_STAT */
#ifdef UNIV_DEBUG
- ulint magic_n; /* magic number */
+ ulint magic_n; /*!< magic number @see BTR_SEARCH_MAGIC_N */
+/** value of btr_search_struct::magic_n, used in assertions */
# define BTR_SEARCH_MAGIC_N 1112765
#endif /* UNIV_DEBUG */
};
-/* The hash index system */
-
+/** The hash index system */
typedef struct btr_search_sys_struct btr_search_sys_t;
+/** The hash index system */
struct btr_search_sys_struct{
- hash_table_t* hash_index;
+ hash_table_t* hash_index; /*!< the adaptive hash index,
+ mapping dtuple_fold values
+ to rec_t pointers on index pages */
};
+/** The adaptive hash index */
extern btr_search_sys_t* btr_search_sys;
-/* The latch protecting the adaptive search system: this latch protects the
+/** @brief The latch protecting the adaptive search system
+
+This latch protects the
(1) hash index;
(2) columns of a record to which we have a pointer in the hash index;
@@ -259,36 +280,34 @@ but does NOT protect:
Bear in mind (3) and (4) when using the hash index.
*/
-
extern rw_lock_t* btr_search_latch_temp;
+/** The latch protecting the adaptive search system */
#define btr_search_latch (*btr_search_latch_temp)
#ifdef UNIV_SEARCH_PERF_STAT
+/** Number of successful adaptive hash index lookups */
extern ulint btr_search_n_succ;
+/** Number of failed adaptive hash index lookups */
extern ulint btr_search_n_hash_fail;
#endif /* UNIV_SEARCH_PERF_STAT */
-/* After change in n_fields or n_bytes in info, this many rounds are waited
+/** After change in n_fields or n_bytes in info, this many rounds are waited
before starting the hash analysis again: this is to save CPU time when there
is no hope in building a hash index. */
-
#define BTR_SEARCH_HASH_ANALYSIS 17
-/* Limit of consecutive searches for trying a search shortcut on the search
+/** Limit of consecutive searches for trying a search shortcut on the search
pattern */
-
#define BTR_SEARCH_ON_PATTERN_LIMIT 3
-/* Limit of consecutive searches for trying a search shortcut using the hash
-index */
-
+/** Limit of consecutive searches for trying a search shortcut using
+the hash index */
#define BTR_SEARCH_ON_HASH_LIMIT 3
-/* We do this many searches before trying to keep the search latch over calls
-from MySQL. If we notice someone waiting for the latch, we again set this
-much timeout. This is to reduce contention. */
-
+/** We do this many searches before trying to keep the search latch
+over calls from MySQL. If we notice someone waiting for the latch, we
+again set this much timeout. This is to reduce contention. */
#define BTR_SEA_TIMEOUT 10000
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/btr0sea.ic b/storage/xtradb/include/btr0sea.ic
index c948d7e92af..beadeeb8d02 100644
--- a/storage/xtradb/include/btr0sea.ic
+++ b/storage/xtradb/include/btr0sea.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/btr0sea.ic
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@@ -26,37 +27,37 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0cur.h"
#include "buf0buf.h"
-/*************************************************************************
+/*********************************************************************//**
Updates the search info. */
UNIV_INTERN
void
btr_search_info_update_slow(
/*========================*/
- btr_search_t* info, /* in/out: search info */
- btr_cur_t* cursor);/* in: cursor which was just positioned */
+ btr_search_t* info, /*!< in/out: search info */
+ btr_cur_t* cursor);/*!< in: cursor which was just positioned */
-/************************************************************************
-Returns search info for an index. */
+/********************************************************************//**
+Returns search info for an index.
+@return search info; search mutex reserved */
UNIV_INLINE
btr_search_t*
btr_search_get_info(
/*================*/
- /* out: search info; search mutex reserved */
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
ut_ad(index);
return(index->search_info);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the search info. */
UNIV_INLINE
void
btr_search_info_update(
/*===================*/
- dict_index_t* index, /* in: index of the cursor */
- btr_cur_t* cursor) /* in: cursor which was just positioned */
+ dict_index_t* index, /*!< in: index of the cursor */
+ btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
btr_search_t* info;
diff --git a/storage/xtradb/include/btr0types.h b/storage/xtradb/include/btr0types.h
index 074b15fa68d..ef4a6b04b34 100644
--- a/storage/xtradb/include/btr0types.h
+++ b/storage/xtradb/include/btr0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/btr0types.h
The index tree general types
Created 2/17/1996 Heikki Tuuri
@@ -30,16 +31,19 @@ Created 2/17/1996 Heikki Tuuri
#include "rem0types.h"
#include "page0types.h"
+/** Persistent cursor */
typedef struct btr_pcur_struct btr_pcur_t;
+/** B-tree cursor */
typedef struct btr_cur_struct btr_cur_t;
+/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
-/* The size of a reference to data stored on a different page.
+/** The size of a reference to data stored on a different page.
The reference is stored at the end of the prefix of the field
in the index record. */
#define BTR_EXTERN_FIELD_REF_SIZE 20
-/* A BLOB field reference full of zero, for use in assertions and tests.
+/** 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[BTR_EXTERN_FIELD_REF_SIZE];
diff --git a/storage/xtradb/include/buf0buddy.h b/storage/xtradb/include/buf0buddy.h
index 2afef7913fc..a3b9fe1c9cd 100644
--- a/storage/xtradb/include/buf0buddy.h
+++ b/storage/xtradb/include/buf0buddy.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0buddy.h
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@@ -33,7 +34,7 @@ Created December 2006 by Marko Makela
#include "univ.i"
#include "buf0types.h"
-/**************************************************************************
+/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex. The buf_pool_mutex may only be released and reacquired
@@ -41,30 +42,29 @@ if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
-buf_pool_mutex. */
+buf_pool_mutex.
+@return allocated block, possibly NULL if lru == NULL */
UNIV_INLINE
void*
buf_buddy_alloc(
/*============*/
- /* out: allocated block,
- possibly NULL if lru == NULL */
- ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
- ibool* lru, /* in: pointer to a variable that will be assigned
+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
+ ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
__attribute__((malloc));
-/**************************************************************************
+/**********************************************************************//**
Release a block. */
UNIV_INLINE
void
buf_buddy_free(
/*===========*/
- void* buf, /* in: block to be freed, must not be
+ void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
- ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool have_page_hash_mutex)
__attribute__((nonnull));
@@ -78,6 +78,7 @@ struct buf_buddy_stat_struct {
ib_uint64_t relocated_usec;
};
+/** Statistics of buddy blocks of a given size. */
typedef struct buf_buddy_stat_struct buf_buddy_stat_t;
/** Statistics of the buddy system, indexed by block size.
diff --git a/storage/xtradb/include/buf0buddy.ic b/storage/xtradb/include/buf0buddy.ic
index 668959cdba2..69659fb69d6 100644
--- a/storage/xtradb/include/buf0buddy.ic
+++ b/storage/xtradb/include/buf0buddy.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0buddy.ic
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@@ -32,47 +33,45 @@ Created December 2006 by Marko Makela
#include "ut0ut.h"
#include "sync0sync.h"
-/**************************************************************************
+/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
-The buf_pool_mutex may only be released and reacquired if lru != NULL. */
+The buf_pool_mutex may only be released and reacquired if lru != NULL.
+@return allocated block, possibly NULL if lru==NULL */
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
- /* out: allocated block,
- possibly NULL if lru==NULL */
- ulint i, /* in: index of buf_pool->zip_free[],
+ ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
- ibool* lru, /* in: pointer to a variable that will be assigned
+ ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
__attribute__((malloc));
-/**************************************************************************
+/**********************************************************************//**
Deallocate a block. */
UNIV_INTERN
void
buf_buddy_free_low(
/*===============*/
- void* buf, /* in: block to be freed, must not be
+ void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
- ulint i, /* in: index of buf_pool->zip_free[],
+ ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool have_page_hash_mutex)
__attribute__((nonnull));
-/**************************************************************************
-Get the index of buf_pool->zip_free[] for a given block size. */
+/**********************************************************************//**
+Get the index of buf_pool->zip_free[] for a given block size.
+@return index of buf_pool->zip_free[], or BUF_BUDDY_SIZES */
UNIV_INLINE
ulint
buf_buddy_get_slot(
/*===============*/
- /* out: index of buf_pool->zip_free[],
- or BUF_BUDDY_SIZES */
- ulint size) /* in: block size */
+ ulint size) /*!< in: block size */
{
ulint i;
ulint s;
@@ -84,7 +83,7 @@ buf_buddy_get_slot(
return(i);
}
-/**************************************************************************
+/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex. The buf_pool_mutex may only be released and reacquired
@@ -92,15 +91,14 @@ if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
-buf_pool_mutex. */
+buf_pool_mutex.
+@return allocated block, possibly NULL if lru == NULL */
UNIV_INLINE
void*
buf_buddy_alloc(
/*============*/
- /* out: allocated block,
- possibly NULL if lru == NULL */
- ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
- ibool* lru, /* in: pointer to a variable that will be assigned
+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
+ ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
@@ -111,15 +109,15 @@ buf_buddy_alloc(
return(buf_buddy_alloc_low(buf_buddy_get_slot(size), lru, have_page_hash_mutex));
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate a block. */
UNIV_INLINE
void
buf_buddy_free(
/*===========*/
- void* buf, /* in: block to be freed, must not be
+ void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
- ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool have_page_hash_mutex)
{
//ut_ad(buf_pool_mutex_own());
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index f89e772513a..ddd08c49a12 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0buf.h
The database buffer pool high-level routines
Created 11/5/1995 Heikki Tuuri
@@ -29,64 +30,85 @@ Created 11/5/1995 Heikki Tuuri
#include "fil0fil.h"
#include "mtr0types.h"
#include "buf0types.h"
-#include "sync0rw.h"
#include "hash0hash.h"
#include "ut0byte.h"
-#include "os0proc.h"
#include "page0types.h"
+#ifndef UNIV_HOTBACKUP
+#include "os0proc.h"
-/* Modes for buf_page_get_gen */
-#define BUF_GET 10 /* get always */
-#define BUF_GET_IF_IN_POOL 11 /* get if in pool */
-#define BUF_GET_NO_LATCH 14 /* get and bufferfix, but set no latch;
- we have separated this case, because
- it is error-prone programming not to
- set a latch, and it should be used
- with care */
-/* Modes for buf_page_get_known_nowait */
-#define BUF_MAKE_YOUNG 51
-#define BUF_KEEP_OLD 52
-/* Magic value to use instead of checksums when they are disabled */
-#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
-
-extern buf_pool_t* buf_pool; /* The buffer pool of the database */
+/** @name Modes for buf_page_get_gen */
+/* @{ */
+#define BUF_GET 10 /*!< get always */
+#define BUF_GET_IF_IN_POOL 11 /*!< get if in pool */
+#define BUF_GET_NO_LATCH 14 /*!< get and bufferfix, but
+ set no latch; we have
+ separated this case, because
+ it is error-prone programming
+ not to set a latch, and it
+ should be used with care */
+/* @} */
+/** @name Modes for buf_page_get_known_nowait */
+/* @{ */
+#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*/
+#define BUF_KEEP_OLD 52 /*!< Preserve the current LRU
+ position of the block. */
+/* @} */
+
+extern buf_pool_t* buf_pool; /*!< The buffer pool of the database */
#ifdef UNIV_DEBUG
-extern ibool buf_debug_prints;/* If this is set TRUE, the program
+extern ibool buf_debug_prints;/*!< If this is set TRUE, the program
prints info whenever read or flush
occurs */
#endif /* UNIV_DEBUG */
-extern ulint srv_buf_pool_write_requests; /* variable to count write request
+extern ulint srv_buf_pool_write_requests; /*!< variable to count write request
issued */
+#else /* !UNIV_HOTBACKUP */
+extern buf_block_t* back_block1; /*!< first block, for --apply-log */
+extern buf_block_t* back_block2; /*!< second block, for page reorganize */
+#endif /* !UNIV_HOTBACKUP */
+
+/** Magic value to use instead of checksums when they are disabled */
+#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
+
+/** @brief States of a control block
+@see buf_page_struct
-/* States of a control block (@see buf_page_struct).
The enumeration values must be 0..7. */
enum buf_page_state {
- BUF_BLOCK_ZIP_FREE = 0, /* contains a free compressed page */
- BUF_BLOCK_ZIP_PAGE, /* contains a clean compressed page */
- BUF_BLOCK_ZIP_DIRTY, /* contains a compressed page that is
- in the buf_pool->flush_list */
-
- /* The constants for compressed-only pages must precede
- BUF_BLOCK_NOT_USED; @see buf_block_state_valid() */
-
- BUF_BLOCK_NOT_USED, /* is in the free list */
- BUF_BLOCK_READY_FOR_USE, /* when buf_LRU_get_free_block returns
- a block, it is in this state */
- BUF_BLOCK_FILE_PAGE, /* contains a buffered file page */
- BUF_BLOCK_MEMORY, /* contains some main memory object */
- BUF_BLOCK_REMOVE_HASH /* hash index should be removed
+ BUF_BLOCK_ZIP_FREE = 0, /*!< contains a free
+ compressed page */
+ BUF_BLOCK_ZIP_PAGE, /*!< contains a clean
+ compressed page */
+ BUF_BLOCK_ZIP_DIRTY, /*!< contains a compressed
+ page that is in the
+ buf_pool->flush_list */
+
+ BUF_BLOCK_NOT_USED, /*!< is in the free list;
+ must be after the BUF_BLOCK_ZIP_
+ constants for compressed-only pages
+ @see buf_block_state_valid() */
+ BUF_BLOCK_READY_FOR_USE, /*!< when buf_LRU_get_free_block
+ returns a block, it is in this state */
+ BUF_BLOCK_FILE_PAGE, /*!< contains a buffered file page */
+ BUF_BLOCK_MEMORY, /*!< contains some main memory
+ object */
+ BUF_BLOCK_REMOVE_HASH /*!< hash index should be removed
before putting to the free list */
};
-/************************************************************************
-Creates the buffer pool. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Creates the buffer pool.
+@return own: buf_pool object, NULL if not enough memory or error */
UNIV_INTERN
buf_pool_t*
buf_pool_init(void);
/*===============*/
- /* out, own: buf_pool object, NULL if not
- enough memory or error */
-/************************************************************************
+/********************************************************************//**
Frees the buffer pool at shutdown. This must not be invoked before
freeing all mutexes. */
UNIV_INTERN
@@ -94,7 +116,7 @@ void
buf_pool_free(void);
/*===============*/
-/************************************************************************
+/********************************************************************//**
Drops the adaptive hash index. To prevent a livelock, this function
is only to be called while holding btr_search_latch and while
btr_search_enabled == FALSE. */
@@ -103,7 +125,7 @@ void
buf_pool_drop_hash_index(void);
/*==========================*/
-/************************************************************************
+/********************************************************************//**
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list.
The caller must take care of relocating bpage->list. */
@@ -111,67 +133,67 @@ UNIV_INTERN
void
buf_relocate(
/*=========*/
- buf_page_t* bpage, /* in/out: control block being relocated;
+ buf_page_t* bpage, /*!< in/out: control block being relocated;
buf_page_get_state(bpage) must be
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
- buf_page_t* dpage) /* in/out: destination control block */
+ buf_page_t* dpage) /*!< in/out: destination control block */
__attribute__((nonnull));
-/************************************************************************
+/********************************************************************//**
Resizes the buffer pool. */
UNIV_INTERN
void
buf_pool_resize(void);
/*=================*/
-/*************************************************************************
-Gets the current size of buffer buf_pool in bytes. */
+/*********************************************************************//**
+Gets the current size of buffer buf_pool in bytes.
+@return size in bytes */
UNIV_INLINE
ulint
buf_pool_get_curr_size(void);
/*========================*/
- /* out: size in bytes */
-/************************************************************************
+/********************************************************************//**
Gets the smallest oldest_modification lsn for any page in the pool. Returns
-zero if all modified pages have been flushed to disk. */
+zero if all modified pages have been flushed to disk.
+@return oldest modification in pool, zero if none */
UNIV_INLINE
ib_uint64_t
buf_pool_get_oldest_modification(void);
/*==================================*/
- /* out: oldest modification in pool,
- zero if none */
-/************************************************************************
-Allocates a buffer block. */
+/********************************************************************//**
+Allocates a buffer block.
+@return own: the allocated block, in state BUF_BLOCK_MEMORY */
UNIV_INLINE
buf_block_t*
buf_block_alloc(
/*============*/
- /* out, own: the allocated block,
- in state BUF_BLOCK_MEMORY */
- ulint zip_size); /* in: compressed page size in bytes,
+ ulint zip_size); /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
-/************************************************************************
+/********************************************************************//**
Frees a buffer block which does not contain a file page. */
UNIV_INLINE
void
buf_block_free(
/*===========*/
- buf_block_t* block); /* in, own: block to be freed */
-/*************************************************************************
-Copies contents of a buffer frame to a given buffer. */
+ buf_block_t* block); /*!< in, own: block to be freed */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Copies contents of a buffer frame to a given buffer.
+@return buf */
UNIV_INLINE
byte*
buf_frame_copy(
/*===========*/
- /* out: buf */
- byte* buf, /* in: buffer to copy to */
- const buf_frame_t* frame); /* in: buffer frame */
-/******************************************************************
+ byte* buf, /*!< in: buffer to copy to */
+ const buf_frame_t* frame); /*!< in: buffer frame */
+#ifndef UNIV_HOTBACKUP
+/**************************************************************//**
NOTE! The following macros should be used instead of buf_page_get_gen,
to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed
in LA! */
#define buf_page_get(SP, ZS, OF, LA, MTR) buf_page_get_gen(\
SP, ZS, OF, LA, NULL,\
BUF_GET, __FILE__, __LINE__, MTR)
-/******************************************************************
+/**************************************************************//**
Use these macros to bufferfix a page with no latching. Remember not to
read the contents of the page unless you know it is safe. Do not modify
the contents of the page! We have separated this case, because it is
@@ -180,252 +202,256 @@ with care. */
#define buf_page_get_with_no_latch(SP, ZS, OF, MTR) buf_page_get_gen(\
SP, ZS, OF, RW_NO_LATCH, NULL,\
BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used instead of
buf_page_optimistic_get_func, to improve debugging. Only values RW_S_LATCH and
RW_X_LATCH are allowed as LA! */
#define buf_page_optimistic_get(LA, BL, MC, MTR) \
buf_page_optimistic_get_func(LA, BL, MC, __FILE__, __LINE__, MTR)
-/************************************************************************
+/********************************************************************//**
This is the general function used to get optimistic access to a database
-page. */
+page.
+@return TRUE if success */
UNIV_INTERN
ibool
buf_page_optimistic_get_func(
/*=========================*/
- /* out: TRUE if success */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
- buf_block_t* block, /* in: guessed block */
- ib_uint64_t modify_clock,/* in: modify clock value if mode is
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
+ buf_block_t* block, /*!< in: guessed block */
+ ib_uint64_t modify_clock,/*!< in: modify clock value if mode is
..._GUESS_ON_CLOCK */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr); /* in: mini-transaction */
-/************************************************************************
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr); /*!< in: mini-transaction */
+/********************************************************************//**
This is used to get access to a known database page, when no waiting can be
-done. */
+done.
+@return TRUE if success */
UNIV_INTERN
ibool
buf_page_get_known_nowait(
/*======================*/
- /* out: TRUE if success */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
- buf_block_t* block, /* in: the known page */
- ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr); /* in: mini-transaction */
-
-/***********************************************************************
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
+ buf_block_t* block, /*!< in: the known page */
+ ulint mode, /*!< in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr); /*!< in: mini-transaction */
+
+/*******************************************************************//**
Given a tablespace id and page number tries to get that page. If the
page is not in the buffer pool it is not loaded and NULL is returned.
Suitable for using when holding the kernel mutex. */
-
+UNIV_INTERN
const buf_block_t*
buf_page_try_get_func(
/*==================*/
- ulint space_id,/* in: tablespace id */
- ulint page_no,/* in: page number */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr); /* in: mini-transaction */
-
+ ulint space_id,/*!< in: tablespace id */
+ ulint page_no,/*!< in: page number */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr); /*!< in: mini-transaction */
+
+/** Tries to get a page. If the page is not in the buffer pool it is
+not loaded. Suitable for using when holding the kernel mutex.
+@param space_id in: tablespace id
+@param page_no in: page number
+@param mtr in: mini-transaction
+@return the page if in buffer pool, NULL if not */
#define buf_page_try_get(space_id, page_no, mtr) \
buf_page_try_get_func(space_id, page_no, __FILE__, __LINE__, mtr);
-/************************************************************************
+/********************************************************************//**
Get read access to a compressed page (usually of type
FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2).
The page must be released with buf_page_release_zip().
NOTE: the page is not protected by any latch. Mutual exclusion has to
be implemented at a higher level. In other words, all possible
accesses to a given page through this function must be protected by
-the same set of mutexes or latches. */
+the same set of mutexes or latches.
+@return pointer to the block, or NULL if not compressed */
UNIV_INTERN
buf_page_t*
buf_page_get_zip(
/*=============*/
- /* out: pointer to the block,
- or NULL if not compressed */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size */
- ulint offset);/* in: page number */
-/************************************************************************
-This is the general function used to get access to a database page. */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
+This is the general function used to get access to a database page.
+@return pointer to the block or NULL */
UNIV_INTERN
buf_block_t*
buf_page_get_gen(
/*=============*/
- /* out: pointer to the block or NULL */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint offset, /* in: page number */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
- buf_block_t* guess, /* in: guessed block or NULL */
- ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL,
+ ulint offset, /*!< in: page number */
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
+ buf_block_t* guess, /*!< in: guessed block or NULL */
+ ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
BUF_GET_NO_LATCH */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr); /* in: mini-transaction */
-/************************************************************************
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr); /*!< in: mini-transaction */
+/********************************************************************//**
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 =>
-FILE_PAGE (the other is buf_page_get_gen). */
+FILE_PAGE (the other is buf_page_get_gen).
+@return pointer to the block, page bufferfixed */
UNIV_INTERN
buf_block_t*
buf_page_create(
/*============*/
- /* out: pointer to the block, page bufferfixed */
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space in units of
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space in units of
a page */
- ulint zip_size,/* in: compressed page size, or 0 */
- mtr_t* mtr); /* in: mini-transaction handle */
-#ifdef UNIV_HOTBACKUP
-/************************************************************************
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+#else /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
UNIV_INTERN
void
buf_page_init_for_backup_restore(
/*=============================*/
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space
in units of a page */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- buf_block_t* block); /* in: block to init */
-#endif /* UNIV_HOTBACKUP */
-/************************************************************************
+ buf_block_t* block); /*!< in: block to init */
+#endif /* !UNIV_HOTBACKUP */
+
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Releases a compressed-only page acquired with buf_page_get_zip(). */
UNIV_INLINE
void
buf_page_release_zip(
/*=================*/
- buf_page_t* bpage); /* in: buffer block */
-/************************************************************************
+ buf_page_t* bpage); /*!< in: buffer block */
+/********************************************************************//**
Decrements the bufferfix count of a buffer control block and releases
a latch, if specified. */
UNIV_INLINE
void
buf_page_release(
/*=============*/
- buf_block_t* block, /* in: buffer block */
- ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH,
+ buf_block_t* block, /*!< in: buffer block */
+ ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH,
RW_NO_LATCH */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
-function can be used to prevent an important page from from slipping out of
+function can be used to prevent an important page from slipping out of
the buffer pool. */
UNIV_INTERN
void
buf_page_make_young(
/*================*/
- buf_page_t* bpage); /* in: buffer block of a file page */
-/************************************************************************
-Returns TRUE if the page can be found in the buffer pool hash table. NOTE
-that it is possible that the page is not yet read from disk, though. */
+ buf_page_t* bpage); /*!< in: buffer block of a file page */
+/********************************************************************//**
+Returns TRUE if the page can be found in the buffer pool hash table.
+
+NOTE that it is possible that the page is not yet read from disk,
+though.
+
+@return TRUE if found in the page hash table */
UNIV_INLINE
ibool
buf_page_peek(
/*==========*/
- /* out: TRUE if found from page hash table,
- NOTE that the page is not necessarily yet read
- from disk! */
- ulint space, /* in: space id */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Resets the check_index_page_at_flush field of a page if found in the buffer
pool. */
UNIV_INTERN
void
buf_reset_check_index_page_at_flush(
/*================================*/
- ulint space, /* in: space id */
- ulint offset);/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: page number */
#ifdef UNIV_DEBUG_FILE_ACCESSES
-/************************************************************************
+/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
-reallocated. */
+reallocated.
+@return control block if found in page hash table, otherwise NULL */
UNIV_INTERN
buf_page_t*
buf_page_set_file_page_was_freed(
/*=============================*/
- /* out: control block if found in page hash table,
- otherwise NULL */
- ulint space, /* in: space id */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
-reallocated. */
+reallocated.
+@return control block if found in page hash table, otherwise NULL */
UNIV_INTERN
buf_page_t*
buf_page_reset_file_page_was_freed(
/*===============================*/
- /* out: control block if found in page hash table,
- otherwise NULL */
- ulint space, /* in: space id */
- ulint offset); /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset); /*!< in: page number */
#endif /* UNIV_DEBUG_FILE_ACCESSES */
-/************************************************************************
-Reads the freed_page_clock of a buffer block. */
+/********************************************************************//**
+Reads the freed_page_clock of a buffer block.
+@return freed_page_clock */
UNIV_INLINE
ulint
buf_page_get_freed_page_clock(
/*==========================*/
- /* out: freed_page_clock */
- const buf_page_t* bpage) /* in: block */
+ const buf_page_t* bpage) /*!< in: block */
__attribute__((pure));
-/************************************************************************
-Reads the freed_page_clock of a buffer block. */
+/********************************************************************//**
+Reads the freed_page_clock of a buffer block.
+@return freed_page_clock */
UNIV_INLINE
ulint
buf_block_get_freed_page_clock(
/*===========================*/
- /* out: freed_page_clock */
- const buf_block_t* block) /* in: block */
+ const buf_block_t* block) /*!< in: block */
__attribute__((pure));
-/************************************************************************
+/********************************************************************//**
Recommends a move of a block to the start of the LRU list if there is danger
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
-mutex. */
+mutex.
+@return TRUE if should be made younger */
UNIV_INLINE
ibool
buf_page_peek_if_too_old(
/*=====================*/
- /* out: TRUE if should be made
- younger */
- const buf_page_t* bpage); /* in: block to make younger */
-/************************************************************************
+ const buf_page_t* bpage); /*!< in: block to make younger */
+/********************************************************************//**
Returns the current state of is_hashed of a page. FALSE if the page is
not in the pool. NOTE that this operation does not fix the page in the
-pool if it is found there. */
+pool if it is found there.
+@return TRUE if page hash index is built in search system */
UNIV_INTERN
ibool
buf_page_peek_if_search_hashed(
/*===========================*/
- /* out: TRUE if page hash index is built in search
- system */
- ulint space, /* in: space id */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Gets the youngest modification log sequence number for a frame.
-Returns zero if not file page or no modification occurred yet. */
+Returns zero if not file page or no modification occurred yet.
+@return newest modification to page */
UNIV_INLINE
ib_uint64_t
buf_page_get_newest_modification(
/*=============================*/
- /* out: newest modification to page */
- const buf_page_t* bpage); /* in: block containing the
+ const buf_page_t* bpage); /*!< in: block containing the
page frame */
-/************************************************************************
+/********************************************************************//**
Increments the modify clock of a frame by 1. The caller must (1) own the
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
on the block. */
@@ -433,155 +459,174 @@ UNIV_INLINE
void
buf_block_modify_clock_inc(
/*=======================*/
- buf_block_t* block); /* in: block */
-/************************************************************************
+ buf_block_t* block); /*!< in: block */
+/********************************************************************//**
Returns the value of the modify clock. The caller must have an s-lock
-or x-lock on the block. */
+or x-lock on the block.
+@return value */
UNIV_INLINE
ib_uint64_t
buf_block_get_modify_clock(
/*=======================*/
- /* out: value */
- buf_block_t* block); /* in: block */
-/************************************************************************
+ buf_block_t* block); /*!< in: block */
+#else /* !UNIV_HOTBACKUP */
+# define buf_block_modify_clock_inc(block) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value
-on 32-bit and 64-bit architectures. */
+on 32-bit and 64-bit architectures.
+@return checksum */
UNIV_INTERN
ulint
buf_calc_page_new_checksum(
/*=======================*/
- /* out: checksum */
- const byte* page); /* in: buffer page */
-/************************************************************************
+ const byte* page); /*!< in: buffer page */
+/********************************************************************//**
In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
looked at the first few bytes of the page. This calculates that old
checksum.
NOTE: we must first store the new formula checksum to
FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
-because this takes that field as an input! */
+because this takes that field as an input!
+@return checksum */
UNIV_INTERN
ulint
buf_calc_page_old_checksum(
/*=======================*/
- /* out: checksum */
- const byte* page); /* in: buffer page */
-/************************************************************************
-Checks if a page is corrupt. */
+ const byte* page); /*!< in: buffer page */
+/********************************************************************//**
+Checks if a page is corrupt.
+@return TRUE if corrupted */
UNIV_INTERN
ibool
buf_page_is_corrupted(
/*==================*/
- /* out: TRUE if corrupted */
- const byte* read_buf, /* in: a database page */
- ulint zip_size); /* in: size of compressed page;
+ const byte* read_buf, /*!< in: a database page */
+ ulint zip_size); /*!< in: size of compressed page;
0 for uncompressed pages */
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Gets the space id, page offset, and byte offset within page of a
pointer pointing to a buffer frame containing a file page. */
UNIV_INLINE
void
buf_ptr_get_fsp_addr(
/*=================*/
- const void* ptr, /* in: pointer to a buffer frame */
- ulint* space, /* out: space id */
- fil_addr_t* addr); /* out: page offset and byte offset */
-/**************************************************************************
+ const void* ptr, /*!< in: pointer to a buffer frame */
+ ulint* space, /*!< out: space id */
+ fil_addr_t* addr); /*!< out: page offset and byte offset */
+/**********************************************************************//**
Gets the hash value of a block. This can be used in searches in the
-lock hash table. */
+lock hash table.
+@return lock hash value */
UNIV_INLINE
ulint
buf_block_get_lock_hash_val(
/*========================*/
- /* out: lock hash value */
- const buf_block_t* block) /* in: block */
+ const buf_block_t* block) /*!< in: block */
__attribute__((pure));
#ifdef UNIV_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Finds a block in the buffer pool that points to a
-given compressed page. */
+given compressed page.
+@return buffer block pointing to the compressed page, or NULL */
UNIV_INTERN
buf_block_t*
buf_pool_contains_zip(
/*==================*/
- /* out: buffer block pointing to
- the compressed page, or NULL */
- const void* data); /* in: pointer to compressed page */
+ const void* data); /*!< in: pointer to compressed page */
#endif /* UNIV_DEBUG */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/*************************************************************************
-Validates the buffer pool data structure. */
+/*********************************************************************//**
+Validates the buffer pool data structure.
+@return TRUE */
UNIV_INTERN
ibool
buf_validate(void);
/*==============*/
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Prints info of the buffer pool data structure. */
UNIV_INTERN
void
buf_print(void);
/*============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
-/************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Prints a page to stderr. */
UNIV_INTERN
void
buf_page_print(
/*===========*/
- const byte* read_buf, /* in: a database page */
- ulint zip_size); /* in: compressed page size, or
+ const byte* read_buf, /*!< in: a database page */
+ ulint zip_size); /*!< in: compressed page size, or
0 for uncompressed pages */
+/********************************************************************//**
+Decompress a block.
+@return TRUE if successful */
+UNIV_INTERN
+ibool
+buf_zip_decompress(
+/*===============*/
+ buf_block_t* block, /*!< in/out: block */
+ ibool check); /*!< in: TRUE=verify the page checksum */
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
-/*************************************************************************
-Returns the number of latched pages in the buffer pool. */
+/*********************************************************************//**
+Returns the number of latched pages in the buffer pool.
+@return number of latched pages */
UNIV_INTERN
ulint
buf_get_latched_pages_number(void);
/*==============================*/
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Returns the number of pending buf pool ios. */
+/*********************************************************************//**
+Returns the number of pending buf pool ios.
+@return number of pending I/O operations */
UNIV_INTERN
ulint
buf_get_n_pending_ios(void);
/*=======================*/
-/*************************************************************************
+/*********************************************************************//**
Prints info of the buffer i/o. */
UNIV_INTERN
void
buf_print_io(
/*=========*/
- FILE* file); /* in: file where to print */
-/*************************************************************************
+ FILE* file); /*!< in: file where to print */
+/*********************************************************************//**
Returns the ratio in percents of modified pages in the buffer pool /
-database pages in the buffer pool. */
+database pages in the buffer pool.
+@return modified page percentage ratio */
UNIV_INTERN
ulint
buf_get_modified_ratio_pct(void);
/*============================*/
-/**************************************************************************
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
buf_refresh_io_stats(void);
/*======================*/
-/*************************************************************************
-Checks that all file pages in the buffer are in a replaceable state. */
+/*********************************************************************//**
+Asserts that all file pages in the buffer are in a replaceable state.
+@return TRUE */
UNIV_INTERN
ibool
buf_all_freed(void);
/*===============*/
-/*************************************************************************
+/*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer
-pool. */
+pool.
+@return TRUE if there is no pending i/o */
UNIV_INTERN
ibool
buf_pool_check_no_pending_io(void);
/*==============================*/
- /* out: TRUE if there is no pending i/o */
-/*************************************************************************
+/*********************************************************************//**
Invalidates the file pages in the buffer pool when an archive recovery is
completed. All the file pages buffered must be in a replaceable state when
this function is called: not latched and not modified. */
@@ -589,13 +634,14 @@ UNIV_INTERN
void
buf_pool_invalidate(void);
/*=====================*/
+#endif /* !UNIV_HOTBACKUP */
/*========================================================================
--------------------------- LOWER LEVEL ROUTINES -------------------------
=========================================================================*/
#ifdef UNIV_SYNC_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Adds latch level info for the rw-lock protecting the buffer frame. This
should be called in the debug version after a successful latching of a
page if we know the latching order level of the acquired latch. */
@@ -603,301 +649,315 @@ UNIV_INLINE
void
buf_block_dbg_add_level(
/*====================*/
- buf_block_t* block, /* in: buffer page
+ buf_block_t* block, /*!< in: buffer page
where we have acquired latch */
- ulint level); /* in: latching order level */
+ ulint level); /*!< in: latching order level */
#else /* UNIV_SYNC_DEBUG */
# define buf_block_dbg_add_level(block, level) /* nothing */
#endif /* UNIV_SYNC_DEBUG */
-/*************************************************************************
-Gets the state of a block. */
+/*********************************************************************//**
+Gets the state of a block.
+@return state */
UNIV_INLINE
enum buf_page_state
buf_page_get_state(
/*===============*/
- /* out: state */
- const buf_page_t* bpage); /* in: pointer to the control block */
-/*************************************************************************
-Gets the state of a block. */
+ const buf_page_t* bpage); /*!< in: pointer to the control block */
+/*********************************************************************//**
+Gets the state of a block.
+@return state */
UNIV_INLINE
enum buf_page_state
buf_block_get_state(
/*================*/
- /* out: state */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
void
buf_page_set_state(
/*===============*/
- buf_page_t* bpage, /* in/out: pointer to control block */
- enum buf_page_state state); /* in: state */
-/*************************************************************************
+ buf_page_t* bpage, /*!< in/out: pointer to control block */
+ enum buf_page_state state); /*!< in: state */
+/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
void
buf_block_set_state(
/*================*/
- buf_block_t* block, /* in/out: pointer to control block */
- enum buf_page_state state); /* in: state */
-/*************************************************************************
-Determines if a block is mapped to a tablespace. */
+ buf_block_t* block, /*!< in/out: pointer to control block */
+ enum buf_page_state state); /*!< in: state */
+/*********************************************************************//**
+Determines if a block is mapped to a tablespace.
+@return TRUE if mapped */
UNIV_INLINE
ibool
buf_page_in_file(
/*=============*/
- /* out: TRUE if mapped */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
-/*************************************************************************
-Determines if a block should be on unzip_LRU list. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Determines if a block should be on unzip_LRU list.
+@return TRUE if block belongs to unzip_LRU */
UNIV_INLINE
ibool
buf_page_belongs_to_unzip_LRU(
/*==========================*/
- /* out: TRUE if block belongs
- to unzip_LRU */
- const buf_page_t* bpage) /* in: pointer to control block */
- __attribute__((pure));
-/*************************************************************************
-Determine the approximate LRU list position of a block. */
-UNIV_INLINE
-ulint
-buf_page_get_LRU_position(
-/*======================*/
- /* out: LRU list position */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
-/*************************************************************************
-Gets the mutex of a block. */
+/*********************************************************************//**
+Gets the mutex of a block.
+@return pointer to mutex protecting bpage */
UNIV_INLINE
mutex_t*
buf_page_get_mutex(
/*===============*/
- /* out: pointer to mutex
- protecting bpage */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
/*************************************************************************
-Get the flush type of a page. */
+Gets the mutex of a block and enter the mutex with consistency. */
+UNIV_INLINE
+mutex_t*
+buf_page_get_mutex_enter(
+/*=========================*/
+ const buf_page_t* bpage) /*!< in: pointer to control block */
+ __attribute__((pure));
+
+/*********************************************************************//**
+Get the flush type of a page.
+@return flush type */
UNIV_INLINE
enum buf_flush
buf_page_get_flush_type(
/*====================*/
- /* out: flush type */
- const buf_page_t* bpage) /* in: buffer page */
+ const buf_page_t* bpage) /*!< in: buffer page */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Set the flush type of a page. */
UNIV_INLINE
void
buf_page_set_flush_type(
/*====================*/
- buf_page_t* bpage, /* in: buffer page */
- enum buf_flush flush_type); /* in: flush type */
-/*************************************************************************
+ buf_page_t* bpage, /*!< in: buffer page */
+ enum buf_flush flush_type); /*!< in: flush type */
+/*********************************************************************//**
Map a block to a file page. */
UNIV_INLINE
void
buf_block_set_file_page(
/*====================*/
- buf_block_t* block, /* in/out: pointer to control block */
- ulint space, /* in: tablespace id */
- ulint page_no);/* in: page number */
-/*************************************************************************
-Gets the io_fix state of a block. */
+ buf_block_t* block, /*!< in/out: pointer to control block */
+ ulint space, /*!< in: tablespace id */
+ ulint page_no);/*!< in: page number */
+/*********************************************************************//**
+Gets the io_fix state of a block.
+@return io_fix state */
UNIV_INLINE
enum buf_io_fix
buf_page_get_io_fix(
/*================*/
- /* out: io_fix state */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the io_fix state of a block. */
+/*********************************************************************//**
+Gets the io_fix state of a block.
+@return io_fix state */
UNIV_INLINE
enum buf_io_fix
buf_block_get_io_fix(
/*================*/
- /* out: io_fix state */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_page_set_io_fix(
/*================*/
- buf_page_t* bpage, /* in/out: control block */
- enum buf_io_fix io_fix);/* in: io_fix state */
-/*************************************************************************
+ buf_page_t* bpage, /*!< in/out: control block */
+ enum buf_io_fix io_fix);/*!< in: io_fix state */
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_block_set_io_fix(
/*=================*/
- buf_block_t* block, /* in/out: control block */
- enum buf_io_fix io_fix);/* in: io_fix state */
+ buf_block_t* block, /*!< in/out: control block */
+ enum buf_io_fix io_fix);/*!< in: io_fix state */
-/************************************************************************
+/********************************************************************//**
Determine if a buffer block can be relocated in memory. The block
can be dirty, but it must not be I/O-fixed or bufferfixed. */
UNIV_INLINE
ibool
buf_page_can_relocate(
/*==================*/
- const buf_page_t* bpage) /* control block being relocated */
+ const buf_page_t* bpage) /*!< control block being relocated */
__attribute__((pure));
-/*************************************************************************
-Determine if a block has been flagged old. */
+/*********************************************************************//**
+Determine if a block has been flagged old.
+@return TRUE if old */
UNIV_INLINE
ibool
buf_page_is_old(
/*============*/
- /* out: TRUE if old */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Flag a block old. */
UNIV_INLINE
void
buf_page_set_old(
/*=============*/
- buf_page_t* bpage, /* in/out: control block */
- ibool old); /* in: old */
-/*************************************************************************
-Determine if a block has been accessed in the buffer pool. */
+ buf_page_t* bpage, /*!< in/out: control block */
+ ibool old); /*!< in: old */
+/*********************************************************************//**
+Determine the time of first access of a block in the buffer pool.
+@return ut_time_ms() at the time of first access, 0 if not accessed */
UNIV_INLINE
-ibool
+unsigned
buf_page_is_accessed(
/*=================*/
- /* out: TRUE if accessed */
- const buf_page_t* bpage) /* in: control block */
- __attribute__((pure));
-/*************************************************************************
+ const buf_page_t* bpage) /*!< in: control block */
+ __attribute__((nonnull, pure));
+/*********************************************************************//**
Flag a block accessed. */
UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
- buf_page_t* bpage, /* in/out: control block */
- ibool accessed); /* in: accessed */
-/*************************************************************************
+ buf_page_t* bpage, /*!< in/out: control block */
+ ulint time_ms) /*!< in: ut_time_ms() */
+ __attribute__((nonnull));
+/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
-page frame exists, or NULL. */
+page frame exists, or NULL.
+@return control block, or NULL */
UNIV_INLINE
buf_block_t*
buf_page_get_block(
/*===============*/
- /* out: control block, or NULL */
- buf_page_t* bpage) /* in: control block, or NULL */
+ buf_page_t* bpage) /*!< in: control block, or NULL */
__attribute__((pure));
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets a pointer to the memory frame of a block. */
+/*********************************************************************//**
+Gets a pointer to the memory frame of a block.
+@return pointer to the frame */
UNIV_INLINE
buf_frame_t*
buf_block_get_frame(
/*================*/
- /* out: pointer to the frame */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
#else /* UNIV_DEBUG */
# define buf_block_get_frame(block) (block)->frame
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Gets the space id of a block. */
+/*********************************************************************//**
+Gets the space id of a block.
+@return space id */
UNIV_INLINE
ulint
buf_page_get_space(
/*===============*/
- /* out: space id */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the space id of a block. */
+/*********************************************************************//**
+Gets the space id of a block.
+@return space id */
UNIV_INLINE
ulint
buf_block_get_space(
/*================*/
- /* out: space id */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the page number of a block. */
+/*********************************************************************//**
+Gets the page number of a block.
+@return page number */
UNIV_INLINE
ulint
buf_page_get_page_no(
/*=================*/
- /* out: page number */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the page number of a block. */
+/*********************************************************************//**
+Gets the page number of a block.
+@return page number */
UNIV_INLINE
ulint
buf_block_get_page_no(
/*==================*/
- /* out: page number */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the compressed page size of a block. */
+/*********************************************************************//**
+Gets the compressed page size of a block.
+@return compressed page size, or 0 */
UNIV_INLINE
ulint
buf_page_get_zip_size(
/*==================*/
- /* out: compressed page size, or 0 */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the compressed page size of a block. */
+/*********************************************************************//**
+Gets the compressed page size of a block.
+@return compressed page size, or 0 */
UNIV_INLINE
ulint
buf_block_get_zip_size(
/*===================*/
- /* out: compressed page size, or 0 */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Gets the compressed page descriptor corresponding to an uncompressed page
if applicable. */
#define buf_block_get_page_zip(block) \
(UNIV_LIKELY_NULL((block)->page.zip.data) ? &(block)->page.zip : NULL)
-/***********************************************************************
-Gets the block to whose frame the pointer is pointing to. */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Gets the block to whose frame the pointer is pointing to.
+@return pointer to block, never NULL */
UNIV_INTERN
buf_block_t*
buf_block_align(
/*============*/
- /* out: pointer to block, never NULL */
- const byte* ptr); /* in: pointer to a frame */
+ const byte* ptr); /*!< in: pointer to a frame */
+/********************************************************************//**
+Find out if a pointer belongs to a buf_block_t. It can be a pointer to
+the buf_block_t itself or a member of it
+@return TRUE if ptr belongs to a buf_block_t struct */
+UNIV_INTERN
+ibool
+buf_pointer_is_block_field(
+/*=======================*/
+ const void* ptr); /*!< in: pointer not
+ dereferenced */
+/** Find out if a pointer corresponds to a buf_block_t::mutex.
+@param m in: mutex candidate
+@return TRUE if m is a buf_block_t::mutex */
+#define buf_pool_is_block_mutex(m) \
+ buf_pointer_is_block_field((const void*)(m))
+/** Find out if a pointer corresponds to a buf_block_t::lock.
+@param l in: rw-lock candidate
+@return TRUE if l is a buf_block_t::lock */
+#define buf_pool_is_block_lock(l) \
+ buf_pointer_is_block_field((const void*)(l))
+
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Gets the compressed page descriptor corresponding to an uncompressed page
-if applicable. */
+if applicable.
+@return compressed page descriptor, or NULL */
UNIV_INLINE
const page_zip_des_t*
buf_frame_get_page_zip(
/*===================*/
- /* out: compressed page descriptor, or NULL */
- const byte* ptr); /* in: pointer to the page */
+ const byte* ptr); /*!< in: pointer to the page */
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
-/************************************************************************
-This function is used to get info if there is an io operation
-going on on a buffer page. */
-UNIV_INLINE
-ibool
-buf_page_io_query(
-/*==============*/
- /* out: TRUE if io going on */
- buf_page_t* bpage); /* in: pool block, must be bufferfixed */
-/************************************************************************
+/********************************************************************//**
Function which inits a page for read to the buffer buf_pool. If the page is
(1) already in buf_pool, or
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
@@ -905,240 +965,253 @@ Function which inits a page for read to the buffer buf_pool. If the page is
then this function does nothing.
Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
on the buffer frame. The io-handler must take care that the flag is cleared
-and the lock released later. */
+and the lock released later.
+@return pointer to the block or NULL */
UNIV_INTERN
buf_page_t*
buf_page_init_for_read(
/*===================*/
- /* out: pointer to the block or NULL */
- ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED */
- ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ... */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size, or 0 */
- ibool unzip, /* in: TRUE=request uncompressed page */
- ib_int64_t tablespace_version,/* in: prevents reading from a wrong
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED */
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ... */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
+ ib_int64_t tablespace_version,/*!< in: prevents reading from a wrong
version of the tablespace in case we have done
DISCARD + IMPORT */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
the buffer pool. */
UNIV_INTERN
void
buf_page_io_complete(
/*=================*/
- buf_page_t* bpage); /* in: pointer to the block in question */
-/************************************************************************
+ buf_page_t* bpage); /*!< in: pointer to the block in question */
+/********************************************************************//**
Calculates a folded value of a file page address to use in the page hash
-table. */
+table.
+@return the folded value */
UNIV_INLINE
ulint
buf_page_address_fold(
/*==================*/
- /* out: the folded value */
- ulint space, /* in: space id */
- ulint offset) /* in: offset of the page within space */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: offset of the page within space */
__attribute__((const));
-/**********************************************************************
-Returns the control block of a file page, NULL if not found. */
+/******************************************************************//**
+Returns the control block of a file page, NULL if not found.
+@return block, NULL if not found */
UNIV_INLINE
buf_page_t*
buf_page_hash_get(
/*==============*/
- /* out: block, NULL if not found */
- ulint space, /* in: space id */
- ulint offset);/* in: offset of the page within space */
-/**********************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: offset of the page within space */
+/******************************************************************//**
Returns the control block of a file page, NULL if not found
-or an uncompressed page frame does not exist. */
+or an uncompressed page frame does not exist.
+@return block, NULL if not found */
UNIV_INLINE
buf_block_t*
buf_block_hash_get(
/*===============*/
- /* out: block, NULL if not found */
- ulint space, /* in: space id */
- ulint offset);/* in: offset of the page within space */
-/***********************************************************************
-Increments the pool clock by one and returns its new value. Remember that
-in the 32 bit version the clock wraps around at 4 billion! */
-UNIV_INLINE
-ulint
-buf_pool_clock_tic(void);
-/*====================*/
- /* out: new clock value */
-/*************************************************************************
-Gets the current length of the free list of buffer blocks. */
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: offset of the page within space */
+/*********************************************************************//**
+Gets the current length of the free list of buffer blocks.
+@return length of the free list */
UNIV_INTERN
ulint
buf_get_free_list_len(void);
/*=======================*/
+#endif /* !UNIV_HOTBACKUP */
-
-/* The common buffer control block structure
+/** The common buffer control block structure
for compressed and uncompressed frames */
struct buf_page_struct{
- /* None of the following bit-fields must be modified without
- holding buf_page_get_mutex() [block->mutex or buf_pool_zip_mutex],
- since they can be stored in the same machine word. Some of them are
- additionally protected by buf_pool_mutex. */
-
- unsigned space:32; /* tablespace id; also protected
+ /** @name General fields
+ None of these bit-fields must be modified without holding
+ buf_page_get_mutex() [buf_block_struct::mutex or
+ buf_pool_zip_mutex], since they can be stored in the same
+ machine word. Some of these fields are additionally protected
+ by buf_pool_mutex. */
+ /* @{ */
+
+ unsigned space:32; /*!< tablespace id; also protected
by buf_pool_mutex. */
- unsigned offset:32; /* page number; also protected
+ unsigned offset:32; /*!< page number; also protected
by buf_pool_mutex. */
- unsigned state:3; /* state of the control block
- (@see enum buf_page_state); also
+ unsigned state:3; /*!< state of the control block; also
protected by buf_pool_mutex.
State transitions from
BUF_BLOCK_READY_FOR_USE to
BUF_BLOCK_MEMORY need not be
- protected by buf_page_get_mutex(). */
- unsigned flush_type:2; /* if this block is currently being
+ protected by buf_page_get_mutex().
+ @see enum buf_page_state */
+#ifndef UNIV_HOTBACKUP
+ unsigned flush_type:2; /*!< if this block is currently being
flushed to disk, this tells the
- flush_type (@see enum buf_flush) */
- unsigned accessed:1; /* TRUE if the page has been accessed
- while in the buffer pool: read-ahead
- may read in pages which have not been
- accessed yet; a thread is allowed to
- read this for heuristic purposes
- without holding any mutex or latch */
- unsigned io_fix:2; /* type of pending I/O operation
- (@see enum buf_io_fix); also
- protected by buf_pool_mutex */
- unsigned buf_fix_count:24;/* count of how manyfold this block
+ flush_type.
+ @see enum buf_flush */
+ unsigned io_fix:2; /*!< type of pending I/O operation;
+ also protected by buf_pool_mutex
+ @see enum buf_io_fix */
+ unsigned buf_fix_count:25;/*!< count of how manyfold this block
is currently bufferfixed */
-
- page_zip_des_t zip; /* compressed page; zip.data
+ /* @} */
+#endif /* !UNIV_HOTBACKUP */
+ page_zip_des_t zip; /*!< compressed page; zip.data
(but not the data it points to) is
also protected by buf_pool_mutex */
- buf_page_t* hash; /* node used in chaining to
+#ifndef UNIV_HOTBACKUP
+ buf_page_t* hash; /*!< node used in chaining to
buf_pool->page_hash or
buf_pool->zip_hash */
#ifdef UNIV_DEBUG
- ibool in_page_hash; /* TRUE if in buf_pool->page_hash */
- ibool in_zip_hash; /* TRUE if in buf_pool->zip_hash */
+ ibool in_page_hash; /*!< TRUE if in buf_pool->page_hash */
+ ibool in_zip_hash; /*!< TRUE if in buf_pool->zip_hash */
#endif /* UNIV_DEBUG */
- /* 2. Page flushing fields; protected by buf_pool_mutex */
+ /** @name Page flushing fields
+ All these are protected by buf_pool_mutex. */
+ /* @{ */
/* UT_LIST_NODE_T(buf_page_t) list; */
- /* based on state, this is a list
- node in one of the following lists
- in buf_pool:
-
- BUF_BLOCK_NOT_USED: free
- BUF_BLOCK_FILE_PAGE: flush_list
- BUF_BLOCK_ZIP_DIRTY: flush_list
- BUF_BLOCK_ZIP_PAGE: zip_clean
- BUF_BLOCK_ZIP_FREE: zip_free[] */
+ /*!< based on state, this is a
+ list node, protected only by
+ buf_pool_mutex, in one of the
+ following lists in buf_pool:
+
+ - BUF_BLOCK_NOT_USED: free
+ - BUF_BLOCK_FILE_PAGE: flush_list
+ - BUF_BLOCK_ZIP_DIRTY: flush_list
+ - BUF_BLOCK_ZIP_PAGE: zip_clean
+ - BUF_BLOCK_ZIP_FREE: zip_free[]
+
+ The contents of the list node
+ is undefined if !in_flush_list
+ && state == BUF_BLOCK_FILE_PAGE,
+ or if state is one of
+ BUF_BLOCK_MEMORY,
+ BUF_BLOCK_REMOVE_HASH or
+ BUF_BLOCK_READY_IN_USE. */
+
/* resplit for optimistic use */
UT_LIST_NODE_T(buf_page_t) free;
UT_LIST_NODE_T(buf_page_t) flush_list;
UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_clean or zip_free[] */
#ifdef UNIV_DEBUG
- ibool in_flush_list; /* TRUE if in buf_pool->flush_list;
+ ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
when buf_pool_mutex is free, the
following should hold: in_flush_list
== (state == BUF_BLOCK_FILE_PAGE
|| state == BUF_BLOCK_ZIP_DIRTY) */
- ibool in_free_list; /* TRUE if in buf_pool->free; when
+ ibool in_free_list; /*!< TRUE if in buf_pool->free; when
buf_pool_mutex is free, the following
should hold: in_free_list
== (state == BUF_BLOCK_NOT_USED) */
#endif /* UNIV_DEBUG */
ib_uint64_t newest_modification;
- /* log sequence number of the youngest
- modification to this block, zero if
- not modified */
+ /*!< log sequence number of
+ the youngest modification to
+ this block, zero if not
+ modified */
ib_uint64_t oldest_modification;
- /* log sequence number of the START of
- the log entry written of the oldest
- modification to this block which has
- not yet been flushed on disk; zero if
- all modifications are on disk */
-
- /* 3. LRU replacement algorithm fields; protected by
- buf_pool_mutex only (not buf_pool_zip_mutex or block->mutex) */
+ /*!< log sequence number of
+ the START of the log entry
+ written of the oldest
+ modification to this block
+ which has not yet been flushed
+ on disk; zero if all
+ modifications are on disk */
+ /* @} */
+ /** @name LRU replacement algorithm fields
+ These fields are protected by buf_pool_mutex only (not
+ buf_pool_zip_mutex or buf_block_struct::mutex). */
+ /* @{ */
UT_LIST_NODE_T(buf_page_t) LRU;
- /* node of the LRU list */
+ /*!< node of the LRU list */
//#ifdef UNIV_DEBUG
- ibool in_LRU_list; /* TRUE if the page is in the LRU list;
- used in debugging */
+ ibool in_LRU_list; /*!< TRUE if the page is in
+ the LRU list; used in
+ debugging */
//#endif /* UNIV_DEBUG */
- unsigned old:1; /* TRUE if the block is in the old
- blocks in the LRU list */
- unsigned LRU_position:31;/* value which monotonically decreases
- (or may stay constant if old==TRUE)
- toward the end of the LRU list, if
- buf_pool->ulint_clock has not wrapped
- around: NOTE that this value can only
- be used in heuristic algorithms,
- because of the possibility of a
- wrap-around! */
- unsigned freed_page_clock:32;/* the value of
- buf_pool->freed_page_clock when this
- block was the last time put to the
- head of the LRU list; a thread is
- allowed to read this for heuristic
- purposes without holding any mutex or
- latch */
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+ unsigned old:1; /*!< TRUE if the block is in the old
+ blocks in buf_pool->LRU_old */
+ unsigned freed_page_clock:31;/*!< the value of
+ buf_pool->freed_page_clock
+ when this block was the last
+ time put to the head of the
+ LRU list; a thread is allowed
+ to read this for heuristic
+ purposes without holding any
+ mutex or latch */
+ unsigned access_time:32; /*!< time of first access, or
+ 0 if the block was never accessed
+ in the buffer pool */
+ /* @} */
+# ifdef UNIV_DEBUG_FILE_ACCESSES
ibool file_page_was_freed;
- /* this is set to TRUE when fsp
+ /*!< this is set to TRUE when fsp
frees a page in buffer pool */
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+# endif /* UNIV_DEBUG_FILE_ACCESSES */
+#endif /* !UNIV_HOTBACKUP */
};
-/* The buffer control block structure */
+/** The buffer control block structure */
struct buf_block_struct{
- /* 1. General fields */
+ /** @name General fields */
+ /* @{ */
- buf_page_t page; /* page information; this must
+ buf_page_t page; /*!< page information; this must
be the first field, so that
buf_pool->page_hash can point
to buf_page_t or buf_block_t */
+ byte* frame; /*!< pointer to buffer frame which
+ is of size UNIV_PAGE_SIZE, and
+ aligned to an address divisible by
+ UNIV_PAGE_SIZE */
+#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(buf_block_t) unzip_LRU;
- /* node of the decompressed LRU list;
+ /*!< node of the decompressed LRU list;
a block is in the unzip_LRU list
if page.state == BUF_BLOCK_FILE_PAGE
and page.zip.data != NULL */
//#ifdef UNIV_DEBUG
- ibool in_unzip_LRU_list;/* TRUE if the page is in the
+ ibool in_unzip_LRU_list;/*!< TRUE if the page is in the
decompressed LRU list;
used in debugging */
//#endif /* UNIV_DEBUG */
- byte* frame; /* pointer to buffer frame which
- is of size UNIV_PAGE_SIZE, and
- aligned to an address divisible by
- UNIV_PAGE_SIZE */
- mutex_t mutex; /* mutex protecting this block:
+ mutex_t mutex; /*!< mutex protecting this block:
state (also protected by the buffer
pool mutex), io_fix, buf_fix_count,
and accessed; we introduce this new
mutex in InnoDB-5.1 to relieve
contention on the buffer pool mutex */
- rw_lock_t lock; /* read-write lock of the buffer
+ rw_lock_t lock; /*!< read-write lock of the buffer
frame */
- unsigned lock_hash_val:32;/* hashed value of the page address
+ unsigned lock_hash_val:32;/*!< hashed value of the page address
in the record lock hash table */
unsigned check_index_page_at_flush:1;
- /* TRUE if we know that this is
+ /*!< TRUE if we know that this is
an index page, and want the database
to check its consistency before flush;
note that there may be pages in the
buffer pool which are index pages,
but this flag is not set because
we do not keep track of all pages */
+ /* @} */
+ /** @name Optimistic search field */
+ /* @{ */
- /* 2. Optimistic search field */
-
- ib_uint64_t modify_clock; /* this clock is incremented every
+ ib_uint64_t modify_clock; /*!< this clock is incremented every
time a pointer to a record on the
page may become obsolete; this is
used in the optimistic cursor
@@ -1149,175 +1222,218 @@ struct buf_block_struct{
pool mutex and the page is not
bufferfixed, or (2) the thread has an
x-latch on the block */
+ /* @} */
+ /** @name Hash search fields (unprotected)
+ NOTE that these fields are NOT protected by any semaphore! */
+ /* @{ */
- /* 3. Hash search fields: NOTE that the first 4 fields are NOT
- protected by any semaphore! */
-
- ulint n_hash_helps; /* counter which controls building
+ ulint n_hash_helps; /*!< counter which controls building
of a new hash index for the page */
- ulint n_fields; /* recommended prefix length for hash
+ ulint n_fields; /*!< recommended prefix length for hash
search: number of full fields */
- ulint n_bytes; /* recommended prefix: number of bytes
+ ulint n_bytes; /*!< recommended prefix: number of bytes
in an incomplete field */
- ibool left_side; /* TRUE or FALSE, depending on
+ ibool left_side; /*!< TRUE or FALSE, depending on
whether the leftmost record of several
records with the same prefix should be
indexed in the hash index */
+ /* @} */
- /* These 6 fields may only be modified when we have
+ /** @name Hash search fields
+ These 6 fields may only be modified when we have
an x-latch on btr_search_latch AND
- a) we are holding an s-latch or x-latch on block->lock or
- b) we know that block->buf_fix_count == 0.
+ - we are holding an s-latch or x-latch on buf_block_struct::lock or
+ - we know that buf_block_struct::buf_fix_count == 0.
An exception to this is when we init or create a page
in the buffer pool in buf0buf.c. */
+ /* @{ */
+
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- ulint n_pointers; /* used in debugging: the number of
+ ulint n_pointers; /*!< used in debugging: the number of
pointers in the adaptive hash index
pointing to this frame */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- unsigned is_hashed:1; /* TRUE if hash index has already been
- built on this page; note that it does
- not guarantee that the index is
- complete, though: there may have been
- hash collisions, record deletions,
- etc. */
- unsigned curr_n_fields:10;/* prefix length for hash indexing:
+ unsigned is_hashed:1; /*!< TRUE if hash index has
+ already been built on this
+ page; note that it does not
+ guarantee that the index is
+ complete, though: there may
+ have been hash collisions,
+ record deletions, etc. */
+ unsigned curr_n_fields:10;/*!< prefix length for hash indexing:
number of full fields */
- unsigned curr_n_bytes:15;/* number of bytes in hash indexing */
- unsigned curr_left_side:1;/* TRUE or FALSE in hash indexing */
- dict_index_t* index; /* Index for which the adaptive
+ unsigned curr_n_bytes:15;/*!< number of bytes in hash
+ indexing */
+ unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
+ dict_index_t* index; /*!< Index for which the adaptive
hash index has been created. */
- /* 4. Debug fields */
-#ifdef UNIV_SYNC_DEBUG
- rw_lock_t debug_latch; /* in the debug version, each thread
+ /* @} */
+# ifdef UNIV_SYNC_DEBUG
+ /** @name Debug fields */
+ /* @{ */
+ rw_lock_t debug_latch; /*!< in the debug version, each thread
which bufferfixes the block acquires
an s-latch here; so we can use the
debug utilities in sync0rw */
-#endif
+ /* @} */
+# endif
+#endif /* !UNIV_HOTBACKUP */
};
-/* Check if a buf_block_t object is in a valid state. */
+/** Check if a buf_block_t object is in a valid state
+@param block buffer block
+@return TRUE if valid */
#define buf_block_state_valid(block) \
(buf_block_get_state(block) >= BUF_BLOCK_NOT_USED \
&& (buf_block_get_state(block) <= BUF_BLOCK_REMOVE_HASH))
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Compute the hash fold value for blocks in buf_pool->zip_hash. */
+/* @{ */
#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE)
#define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame)
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
+/* @} */
+
+/** @brief The buffer pool statistics structure. */
+struct buf_pool_stat_struct{
+ ulint n_page_gets; /*!< number of page gets performed;
+ also successful searches through
+ the adaptive hash index are
+ counted as page gets; this field
+ is NOT protected by the buffer
+ pool mutex */
+ ulint n_pages_read; /*!< number read operations */
+ ulint n_pages_written;/*!< number write operations */
+ ulint n_pages_created;/*!< number of pages created
+ in the pool with no read */
+ ulint n_ra_pages_read;/*!< number of pages read in
+ as part of read ahead */
+ ulint n_ra_pages_evicted;/*!< number of read ahead
+ pages that are evicted without
+ being accessed */
+ ulint n_pages_made_young; /*!< number of pages made young, in
+ calls to buf_LRU_make_block_young() */
+ ulint n_pages_not_made_young; /*!< number of pages not made
+ young because the first access
+ was not long enough ago, in
+ buf_page_peek_if_too_old() */
+};
-/* The buffer pool structure. NOTE! The definition appears here only for
-other modules of this directory (buf) to see it. Do not use from outside! */
+/** @brief The buffer pool structure.
+
+NOTE! The definition appears here only for other modules of this
+directory (buf) to see it. Do not use from outside! */
struct buf_pool_struct{
- /* 1. General fields */
+ /** @name General fields */
+ /* @{ */
- ulint n_chunks; /* number of buffer pool chunks */
- buf_chunk_t* chunks; /* buffer pool chunks */
- ulint curr_size; /* current pool size in pages */
- hash_table_t* page_hash; /* hash table of buf_page_t or
+ ulint n_chunks; /*!< number of buffer pool chunks */
+ buf_chunk_t* chunks; /*!< buffer pool chunks */
+ ulint curr_size; /*!< current pool size in pages */
+ hash_table_t* page_hash; /*!< hash table of buf_page_t or
buf_block_t file pages,
buf_page_in_file() == TRUE,
indexed by (space_id, offset) */
- hash_table_t* zip_hash; /* hash table of buf_block_t blocks
+ hash_table_t* zip_hash; /*!< hash table of buf_block_t blocks
whose frames are allocated to the
zip buddy system,
indexed by block->frame */
- ulint n_pend_reads; /* number of pending read operations */
- ulint n_pend_unzip; /* number of pending decompressions */
+ ulint n_pend_reads; /*!< number of pending read operations */
+ ulint n_pend_unzip; /*!< number of pending decompressions */
- time_t last_printout_time; /* when buf_print was last time
+ time_t last_printout_time;
+ /*!< when buf_print_io was last time
called */
- ulint n_pages_read; /* number read operations */
- ulint n_pages_written;/* number write operations */
- ulint n_pages_created;/* number of pages created in the pool
- with no read */
- ulint n_page_gets; /* number of page gets performed;
- also successful searches through
- the adaptive hash index are
- counted as page gets; this field
- is NOT protected by the buffer
- pool mutex */
- ulint n_page_gets_old;/* n_page_gets when buf_print was
- last time called: used to calculate
- hit rate */
- ulint n_pages_read_old;/* n_pages_read when buf_print was
- last time called */
- ulint n_pages_written_old;/* number write operations */
- ulint n_pages_created_old;/* number of pages created in
- the pool with no read */
- /* 2. Page flushing algorithm fields */
+ buf_pool_stat_t stat; /*!< current statistics */
+ buf_pool_stat_t old_stat; /*!< old statistics */
+
+ /* @} */
+
+ /** @name Page flushing algorithm fields */
+
+ /* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
- /* base node of the modified block
+ /*!< base node of the modified block
list */
ibool init_flush[BUF_FLUSH_N_TYPES];
- /* this is TRUE when a flush of the
+ /*!< this is TRUE when a flush of the
given type is being initialized */
ulint n_flush[BUF_FLUSH_N_TYPES];
- /* this is the number of pending
+ /*!< this is the number of pending
writes in the given flush type */
os_event_t no_flush[BUF_FLUSH_N_TYPES];
- /* this is in the set state when there
- is no flush batch of the given type
- running */
- ulint ulint_clock; /* a sequence number used to count
- time. NOTE! This counter wraps
- around at 4 billion (if ulint ==
- 32 bits)! */
- ulint freed_page_clock;/* a sequence number used to count the
- number of buffer blocks removed from
- the end of the LRU list; NOTE that
- this counter may wrap around at 4
- billion! A thread is allowed to
- read this for heuristic purposes
- without holding any mutex or latch */
- ulint LRU_flush_ended;/* when an LRU flush ends for a page,
+ /*!< this is in the set state
+ when there is no flush batch
+ of the given type running */
+ ulint freed_page_clock;/*!< a sequence number used
+ to count the number of buffer
+ blocks removed from the end of
+ the LRU list; NOTE that this
+ counter may wrap around at 4
+ billion! A thread is allowed
+ to read this for heuristic
+ purposes without holding any
+ mutex or latch */
+ ulint LRU_flush_ended;/*!< when an LRU flush ends for a page,
this is incremented by one; this is
set to zero when a buffer block is
allocated */
- /* 3. LRU replacement algorithm fields */
+ /* @} */
+ /** @name LRU replacement algorithm fields */
+ /* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) free;
- /* base node of the free block list */
+ /*!< base node of the free
+ block list */
UT_LIST_BASE_NODE_T(buf_page_t) LRU;
- /* base node of the LRU list */
- buf_page_t* LRU_old; /* pointer to the about 3/8 oldest
- blocks in the LRU list; NULL if LRU
- length less than BUF_LRU_OLD_MIN_LEN;
+ /*!< base node of the LRU list */
+ buf_page_t* LRU_old; /*!< pointer to the about
+ buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
+ oldest blocks in the LRU list;
+ NULL if LRU length less than
+ BUF_LRU_OLD_MIN_LEN;
NOTE: when LRU_old != NULL, its length
should always equal LRU_old_len */
- ulint LRU_old_len; /* length of the LRU list from
+ ulint LRU_old_len; /*!< length of the LRU list from
the block to which LRU_old points
onward, including that block;
see buf0lru.c for the restrictions
- on this value; not defined if
- LRU_old == NULL;
+ on this value; 0 if LRU_old == NULL;
NOTE: LRU_old_len must be adjusted
whenever LRU_old shrinks or grows! */
UT_LIST_BASE_NODE_T(buf_block_t) unzip_LRU;
- /* base node of the unzip_LRU list */
-
- /* 4. Fields for the buddy allocator of compressed pages */
+ /*!< base node of the
+ unzip_LRU list */
+
+ /* @} */
+ /** @name Buddy allocator fields
+ The buddy allocator is used for allocating compressed page
+ frames and buf_page_t descriptors of blocks that exist
+ in the buffer pool only in compressed form. */
+ /* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;
- /* unmodified compressed pages */
+ /*!< unmodified compressed pages */
UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
- /* buddy free lists */
+ /*!< buddy free lists */
#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
#endif
#if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE
# error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE"
#endif
+ /* @} */
};
-/* mutex protecting the buffer pool struct and control blocks, except the
+/** mutex protecting the buffer pool struct and control blocks, except the
read-write lock in them */
extern mutex_t buf_pool_mutex;
extern mutex_t LRU_list_mutex;
@@ -1326,16 +1442,17 @@ extern rw_lock_t page_hash_latch;
extern mutex_t free_list_mutex;
extern mutex_t zip_free_mutex;
extern mutex_t zip_hash_mutex;
-/* mutex protecting the control blocks of compressed-only pages
+/** mutex protecting the control blocks of compressed-only pages
(of type buf_page_t, not buf_block_t) */
extern mutex_t buf_pool_zip_mutex;
-/* Accessors for buf_pool_mutex. Use these instead of accessing
-buf_pool_mutex directly. */
+/** @name Accessors for buf_pool_mutex.
+Use these instead of accessing buf_pool_mutex directly. */
+/* @{ */
-/* Test if buf_pool_mutex is owned. */
+/** Test if buf_pool_mutex is owned. */
#define buf_pool_mutex_own() mutex_own(&buf_pool_mutex)
-/* Acquire the buffer pool mutex. */
+/** Acquire the buffer pool mutex. */
#define buf_pool_mutex_enter() do { \
ut_ad(!mutex_own(&buf_pool_zip_mutex)); \
mutex_enter(&buf_pool_mutex); \
@@ -1345,32 +1462,34 @@ buf_pool_mutex directly. */
/** Flag to forbid the release of the buffer pool mutex.
Protected by buf_pool_mutex. */
extern ulint buf_pool_mutex_exit_forbidden;
-/* Forbid the release of the buffer pool mutex. */
+/** Forbid the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_forbid() do { \
ut_ad(buf_pool_mutex_own()); \
buf_pool_mutex_exit_forbidden++; \
} while (0)
-/* Allow the release of the buffer pool mutex. */
+/** Allow the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_allow() do { \
ut_ad(buf_pool_mutex_own()); \
ut_a(buf_pool_mutex_exit_forbidden); \
buf_pool_mutex_exit_forbidden--; \
} while (0)
-/* Release the buffer pool mutex. */
+/** Release the buffer pool mutex. */
# define buf_pool_mutex_exit() do { \
ut_a(!buf_pool_mutex_exit_forbidden); \
mutex_exit(&buf_pool_mutex); \
} while (0)
#else
-/* Forbid the release of the buffer pool mutex. */
+/** Forbid the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_forbid() ((void) 0)
-/* Allow the release of the buffer pool mutex. */
+/** Allow the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_allow() ((void) 0)
-/* Release the buffer pool mutex. */
+/** Release the buffer pool mutex. */
# define buf_pool_mutex_exit() mutex_exit(&buf_pool_mutex)
#endif
+#endif /* !UNIV_HOTBACKUP */
+/* @} */
-/************************************************************************
+/**********************************************************************
Let us list the consistency conditions for different control block states.
NOT_USED: is in free list, not in LRU list, not in flush list, nor
diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic
index d7ac80becce..e48794fc753 100644
--- a/storage/xtradb/include/buf0buf.ic
+++ b/storage/xtradb/include/buf0buf.ic
@@ -23,79 +23,100 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0buf.ic
The database buffer buf_pool
Created 11/5/1995 Heikki Tuuri
*******************************************************/
+#include "mtr0mtr.h"
+#ifndef UNIV_HOTBACKUP
#include "buf0flu.h"
#include "buf0lru.h"
#include "buf0rea.h"
-#include "mtr0mtr.h"
-/************************************************************************
-Reads the freed_page_clock of a buffer block. */
+/********************************************************************//**
+Reads the freed_page_clock of a buffer block.
+@return freed_page_clock */
UNIV_INLINE
ulint
buf_page_get_freed_page_clock(
/*==========================*/
- /* out: freed_page_clock */
- const buf_page_t* bpage) /* in: block */
+ const buf_page_t* bpage) /*!< in: block */
{
/* This is sometimes read without holding buf_pool_mutex. */
return(bpage->freed_page_clock);
}
-/************************************************************************
-Reads the freed_page_clock of a buffer block. */
+/********************************************************************//**
+Reads the freed_page_clock of a buffer block.
+@return freed_page_clock */
UNIV_INLINE
ulint
buf_block_get_freed_page_clock(
/*===========================*/
- /* out: freed_page_clock */
- const buf_block_t* block) /* in: block */
+ const buf_block_t* block) /*!< in: block */
{
return(buf_page_get_freed_page_clock(&block->page));
}
-/************************************************************************
+/********************************************************************//**
Recommends a move of a block to the start of the LRU list if there is danger
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
-mutex. */
+mutex.
+@return TRUE if should be made younger */
UNIV_INLINE
ibool
buf_page_peek_if_too_old(
/*=====================*/
- /* out: TRUE if should be made
- younger */
- const buf_page_t* bpage) /* in: block to make younger */
+ const buf_page_t* bpage) /*!< in: block to make younger */
{
- return(buf_pool->freed_page_clock
- >= buf_page_get_freed_page_clock(bpage)
- + 1 + (buf_pool->curr_size / 4));
+ if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
+ /* If eviction has not started yet, do not update the
+ statistics or move blocks in the LRU list. This is
+ either the warm-up phase or an in-memory workload. */
+ return(FALSE);
+ } else if (buf_LRU_old_threshold_ms && bpage->old) {
+ unsigned access_time = buf_page_is_accessed(bpage);
+
+ if (access_time > 0
+ && (ut_time_ms() - access_time)
+ >= buf_LRU_old_threshold_ms) {
+ return(TRUE);
+ }
+
+ buf_pool->stat.n_pages_not_made_young++;
+ return(FALSE);
+ } else {
+ /* FIXME: bpage->freed_page_clock is 31 bits */
+ return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
+ > ((ulint) bpage->freed_page_clock
+ + (buf_pool->curr_size
+ * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
+ / (BUF_LRU_OLD_RATIO_DIV * 4))));
+ }
}
-/*************************************************************************
-Gets the current size of buffer buf_pool in bytes. */
+/*********************************************************************//**
+Gets the current size of buffer buf_pool in bytes.
+@return size in bytes */
UNIV_INLINE
ulint
buf_pool_get_curr_size(void)
/*========================*/
- /* out: size in bytes */
{
return(buf_pool->curr_size * UNIV_PAGE_SIZE);
}
-/************************************************************************
+/********************************************************************//**
Gets the smallest oldest_modification lsn for any page in the pool. Returns
-zero if all modified pages have been flushed to disk. */
+zero if all modified pages have been flushed to disk.
+@return oldest modification in pool, zero if none */
UNIV_INLINE
ib_uint64_t
buf_pool_get_oldest_modification(void)
/*==================================*/
- /* out: oldest modification in pool,
- zero if none */
{
buf_page_t* bpage;
ib_uint64_t lsn;
@@ -125,32 +146,16 @@ try_again:
return(lsn);
}
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
-Increments the buf_pool clock by one and returns its new value. Remember
-that in the 32 bit version the clock wraps around at 4 billion! */
-UNIV_INLINE
-ulint
-buf_pool_clock_tic(void)
-/*====================*/
- /* out: new clock value */
-{
- //ut_ad(buf_pool_mutex_own());
- ut_ad(mutex_own(&LRU_list_mutex));
-
- buf_pool->ulint_clock++;
-
- return(buf_pool->ulint_clock);
-}
-
-/*************************************************************************
-Gets the state of a block. */
+/*********************************************************************//**
+Gets the state of a block.
+@return state */
UNIV_INLINE
enum buf_page_state
buf_page_get_state(
/*===============*/
- /* out: state */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
enum buf_page_state state = (enum buf_page_state) bpage->state;
@@ -172,25 +177,25 @@ buf_page_get_state(
return(state);
}
-/*************************************************************************
-Gets the state of a block. */
+/*********************************************************************//**
+Gets the state of a block.
+@return state */
UNIV_INLINE
enum buf_page_state
buf_block_get_state(
/*================*/
- /* out: state */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
return(buf_page_get_state(&block->page));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
void
buf_page_set_state(
/*===============*/
- buf_page_t* bpage, /* in/out: pointer to control block */
- enum buf_page_state state) /* in: state */
+ buf_page_t* bpage, /*!< in/out: pointer to control block */
+ enum buf_page_state state) /*!< in: state */
{
#ifdef UNIV_DEBUG
enum buf_page_state old_state = buf_page_get_state(bpage);
@@ -229,26 +234,26 @@ buf_page_set_state(
ut_ad(buf_page_get_state(bpage) == state);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
void
buf_block_set_state(
/*================*/
- buf_block_t* block, /* in/out: pointer to control block */
- enum buf_page_state state) /* in: state */
+ buf_block_t* block, /*!< in/out: pointer to control block */
+ enum buf_page_state state) /*!< in: state */
{
buf_page_set_state(&block->page, state);
}
-/*************************************************************************
-Determines if a block is mapped to a tablespace. */
+/*********************************************************************//**
+Determines if a block is mapped to a tablespace.
+@return TRUE if mapped */
UNIV_INLINE
ibool
buf_page_in_file(
/*=============*/
- /* out: TRUE if mapped */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
{
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_FREE:
@@ -270,15 +275,15 @@ buf_page_in_file(
return(FALSE);
}
-/*************************************************************************
-Determines if a block should be on unzip_LRU list. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Determines if a block should be on unzip_LRU list.
+@return TRUE if block belongs to unzip_LRU */
UNIV_INLINE
ibool
buf_page_belongs_to_unzip_LRU(
/*==========================*/
- /* out: TRUE if block belongs
- to unzip_LRU */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
{
ut_ad(buf_page_in_file(bpage));
@@ -286,30 +291,14 @@ buf_page_belongs_to_unzip_LRU(
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
}
-/*************************************************************************
-Determine the approximate LRU list position of a block. */
-UNIV_INLINE
-ulint
-buf_page_get_LRU_position(
-/*======================*/
- /* out: LRU list position */
- const buf_page_t* bpage) /* in: control block */
-{
- ut_ad(buf_page_in_file(bpage));
- //ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
-
- return(bpage->LRU_position);
-}
-
-/*************************************************************************
-Gets the mutex of a block. */
+/*********************************************************************//**
+Gets the mutex of a block.
+@return pointer to mutex protecting bpage */
UNIV_INLINE
mutex_t*
buf_page_get_mutex(
/*===============*/
- /* out: pointer to mutex
- protecting bpage */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
{
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_FREE:
@@ -324,13 +313,35 @@ buf_page_get_mutex(
}
/*************************************************************************
-Get the flush type of a page. */
+Gets the mutex of a block and enter the mutex with consistency. */
+UNIV_INLINE
+mutex_t*
+buf_page_get_mutex_enter(
+/*=========================*/
+ const buf_page_t* bpage) /*!< in: pointer to control block */
+{
+ mutex_t* block_mutex;
+
+ while(1) {
+ block_mutex = buf_page_get_mutex(bpage);
+ if (!block_mutex)
+ return block_mutex;
+
+ mutex_enter(block_mutex);
+ if (block_mutex == buf_page_get_mutex(bpage))
+ return block_mutex;
+ mutex_exit(block_mutex);
+ }
+}
+
+/*********************************************************************//**
+Get the flush type of a page.
+@return flush type */
UNIV_INLINE
enum buf_flush
buf_page_get_flush_type(
/*====================*/
- /* out: flush type */
- const buf_page_t* bpage) /* in: buffer page */
+ const buf_page_t* bpage) /*!< in: buffer page */
{
enum buf_flush flush_type = (enum buf_flush) bpage->flush_type;
@@ -347,42 +358,42 @@ buf_page_get_flush_type(
#endif /* UNIV_DEBUG */
return(flush_type);
}
-/*************************************************************************
+/*********************************************************************//**
Set the flush type of a page. */
UNIV_INLINE
void
buf_page_set_flush_type(
/*====================*/
- buf_page_t* bpage, /* in: buffer page */
- enum buf_flush flush_type) /* in: flush type */
+ buf_page_t* bpage, /*!< in: buffer page */
+ enum buf_flush flush_type) /*!< in: flush type */
{
bpage->flush_type = flush_type;
ut_ad(buf_page_get_flush_type(bpage) == flush_type);
}
-/*************************************************************************
+/*********************************************************************//**
Map a block to a file page. */
UNIV_INLINE
void
buf_block_set_file_page(
/*====================*/
- buf_block_t* block, /* in/out: pointer to control block */
- ulint space, /* in: tablespace id */
- ulint page_no)/* in: page number */
+ buf_block_t* block, /*!< in/out: pointer to control block */
+ ulint space, /*!< in: tablespace id */
+ ulint page_no)/*!< in: page number */
{
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
block->page.space = space;
block->page.offset = page_no;
}
-/*************************************************************************
-Gets the io_fix state of a block. */
+/*********************************************************************//**
+Gets the io_fix state of a block.
+@return io_fix state */
UNIV_INLINE
enum buf_io_fix
buf_page_get_io_fix(
/*================*/
- /* out: io_fix state */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
#ifdef UNIV_DEBUG
@@ -397,26 +408,26 @@ buf_page_get_io_fix(
return(io_fix);
}
-/*************************************************************************
-Gets the io_fix state of a block. */
+/*********************************************************************//**
+Gets the io_fix state of a block.
+@return io_fix state */
UNIV_INLINE
enum buf_io_fix
buf_block_get_io_fix(
/*================*/
- /* out: io_fix state */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
return(buf_page_get_io_fix(&block->page));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_page_set_io_fix(
/*================*/
- buf_page_t* bpage, /* in/out: control block */
- enum buf_io_fix io_fix) /* in: io_fix state */
+ buf_page_t* bpage, /*!< in/out: control block */
+ enum buf_io_fix io_fix) /*!< in: io_fix state */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -425,26 +436,26 @@ buf_page_set_io_fix(
ut_ad(buf_page_get_io_fix(bpage) == io_fix);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_block_set_io_fix(
/*=================*/
- buf_block_t* block, /* in/out: control block */
- enum buf_io_fix io_fix) /* in: io_fix state */
+ buf_block_t* block, /*!< in/out: control block */
+ enum buf_io_fix io_fix) /*!< in: io_fix state */
{
buf_page_set_io_fix(&block->page, io_fix);
}
-/************************************************************************
+/********************************************************************//**
Determine if a buffer block can be relocated in memory. The block
can be dirty, but it must not be I/O-fixed or bufferfixed. */
UNIV_INLINE
ibool
buf_page_can_relocate(
/*==================*/
- const buf_page_t* bpage) /* control block being relocated */
+ const buf_page_t* bpage) /*!< control block being relocated */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -456,14 +467,14 @@ buf_page_can_relocate(
&& bpage->buf_fix_count == 0);
}
-/*************************************************************************
-Determine if a block has been flagged old. */
+/*********************************************************************//**
+Determine if a block has been flagged old.
+@return TRUE if old */
UNIV_INLINE
ibool
buf_page_is_old(
/*============*/
- /* out: TRUE if old */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
//ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
@@ -471,14 +482,14 @@ buf_page_is_old(
return(bpage->old);
}
-/*************************************************************************
+/*********************************************************************//**
Flag a block old. */
UNIV_INLINE
void
buf_page_set_old(
/*=============*/
- buf_page_t* bpage, /* in/out: control block */
- ibool old) /* in: old */
+ buf_page_t* bpage, /*!< in/out: control block */
+ ibool old) /*!< in: old */
{
ut_a(buf_page_in_file(bpage));
//ut_ad(buf_pool_mutex_own());
@@ -486,54 +497,67 @@ buf_page_set_old(
ut_ad(bpage->in_LRU_list);
#ifdef UNIV_LRU_DEBUG
- if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)
- && UT_LIST_GET_PREV(LRU, bpage)->old
- == UT_LIST_GET_NEXT(LRU, bpage)->old) {
- ut_a(UT_LIST_GET_PREV(LRU, bpage)->old == old);
+ ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL));
+ /* If a block is flagged "old", the LRU_old list must exist. */
+ ut_a(!old || buf_pool->LRU_old);
+
+ if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) {
+ const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
+ const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage);
+ if (prev->old == next->old) {
+ ut_a(prev->old == old);
+ } else {
+ ut_a(!prev->old);
+ ut_a(buf_pool->LRU_old == (old ? bpage : next));
+ }
}
#endif /* UNIV_LRU_DEBUG */
bpage->old = old;
}
-/*************************************************************************
-Determine if a block has been accessed in the buffer pool. */
+/*********************************************************************//**
+Determine the time of first access of a block in the buffer pool.
+@return ut_time_ms() at the time of first access, 0 if not accessed */
UNIV_INLINE
-ibool
+unsigned
buf_page_is_accessed(
/*=================*/
- /* out: TRUE if accessed */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
- return(bpage->accessed);
+ return(bpage->access_time);
}
-/*************************************************************************
+/*********************************************************************//**
Flag a block accessed. */
UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
- buf_page_t* bpage, /* in/out: control block */
- ibool accessed) /* in: accessed */
+ buf_page_t* bpage, /*!< in/out: control block */
+ ulint time_ms) /*!< in: ut_time_ms() */
{
ut_a(buf_page_in_file(bpage));
+ //ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
- bpage->accessed = accessed;
+ if (!bpage->access_time) {
+ /* Make this the time of the first access. */
+ bpage->access_time = time_ms;
+ }
}
-/*************************************************************************
+/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
-page frame exists, or NULL. */
+page frame exists, or NULL.
+@return control block, or NULL */
UNIV_INLINE
buf_block_t*
buf_page_get_block(
/*===============*/
- /* out: control block, or NULL */
- buf_page_t* bpage) /* in: control block, or NULL */
+ buf_page_t* bpage) /*!< in: control block, or NULL */
{
if (UNIV_LIKELY(bpage != NULL)) {
ut_ad(buf_page_in_file(bpage));
@@ -545,16 +569,17 @@ buf_page_get_block(
return(NULL);
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets a pointer to the memory frame of a block. */
+/*********************************************************************//**
+Gets a pointer to the memory frame of a block.
+@return pointer to the frame */
UNIV_INLINE
buf_frame_t*
buf_block_get_frame(
/*================*/
- /* out: pointer to the frame */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
ut_ad(block);
@@ -566,7 +591,9 @@ buf_block_get_frame(
ut_error;
break;
case BUF_BLOCK_FILE_PAGE:
+# ifndef UNIV_HOTBACKUP
ut_a(block->page.buf_fix_count > 0);
+# endif /* !UNIV_HOTBACKUP */
/* fall through */
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_MEMORY:
@@ -579,14 +606,14 @@ ok:
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Gets the space id of a block. */
+/*********************************************************************//**
+Gets the space id of a block.
+@return space id */
UNIV_INLINE
ulint
buf_page_get_space(
/*===============*/
- /* out: space id */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
@@ -594,14 +621,14 @@ buf_page_get_space(
return(bpage->space);
}
-/*************************************************************************
-Gets the space id of a block. */
+/*********************************************************************//**
+Gets the space id of a block.
+@return space id */
UNIV_INLINE
ulint
buf_block_get_space(
/*================*/
- /* out: space id */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
ut_ad(block);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
@@ -609,14 +636,14 @@ buf_block_get_space(
return(block->page.space);
}
-/*************************************************************************
-Gets the page number of a block. */
+/*********************************************************************//**
+Gets the page number of a block.
+@return page number */
UNIV_INLINE
ulint
buf_page_get_page_no(
/*=================*/
- /* out: page number */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
@@ -624,14 +651,14 @@ buf_page_get_page_no(
return(bpage->offset);
}
-/*************************************************************************
-Gets the page number of a block. */
+/*********************************************************************//**
+Gets the page number of a block.
+@return page number */
UNIV_INLINE
ulint
buf_block_get_page_no(
/*==================*/
- /* out: page number */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
ut_ad(block);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
@@ -639,55 +666,57 @@ buf_block_get_page_no(
return(block->page.offset);
}
-/*************************************************************************
-Gets the compressed page size of a block. */
+/*********************************************************************//**
+Gets the compressed page size of a block.
+@return compressed page size, or 0 */
UNIV_INLINE
ulint
buf_page_get_zip_size(
/*==================*/
- /* out: compressed page size, or 0 */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
}
-/*************************************************************************
-Gets the compressed page size of a block. */
+/*********************************************************************//**
+Gets the compressed page size of a block.
+@return compressed page size, or 0 */
UNIV_INLINE
ulint
buf_block_get_zip_size(
/*===================*/
- /* out: compressed page size, or 0 */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
}
+#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Gets the compressed page descriptor corresponding to an uncompressed page
-if applicable. */
+if applicable.
+@return compressed page descriptor, or NULL */
UNIV_INLINE
const page_zip_des_t*
buf_frame_get_page_zip(
/*===================*/
- /* out: compressed page descriptor, or NULL */
- const byte* ptr) /* in: pointer to the page */
+ const byte* ptr) /*!< in: pointer to the page */
{
return(buf_block_get_page_zip(buf_block_align(ptr)));
}
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Gets the space id, page offset, and byte offset within page of a
pointer pointing to a buffer frame containing a file page. */
UNIV_INLINE
void
buf_ptr_get_fsp_addr(
/*=================*/
- const void* ptr, /* in: pointer to a buffer frame */
- ulint* space, /* out: space id */
- fil_addr_t* addr) /* out: page offset and byte offset */
+ const void* ptr, /*!< in: pointer to a buffer frame */
+ ulint* space, /*!< out: space id */
+ fil_addr_t* addr) /*!< out: page offset and byte offset */
{
const page_t* page = (const page_t*) ut_align_down(ptr,
UNIV_PAGE_SIZE);
@@ -697,28 +726,28 @@ buf_ptr_get_fsp_addr(
addr->boffset = ut_align_offset(ptr, UNIV_PAGE_SIZE);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Gets the hash value of the page the pointer is pointing to. This can be used
-in searches in the lock hash table. */
+in searches in the lock hash table.
+@return lock hash value */
UNIV_INLINE
ulint
buf_block_get_lock_hash_val(
/*========================*/
- /* out: lock hash value */
- const buf_block_t* block) /* in: block */
+ const buf_block_t* block) /*!< in: block */
{
return(block->lock_hash_val);
}
-/************************************************************************
-Allocates a buffer block. */
+/********************************************************************//**
+Allocates a buffer block.
+@return own: the allocated block, in state BUF_BLOCK_MEMORY */
UNIV_INLINE
buf_block_t*
buf_block_alloc(
/*============*/
- /* out, own: the allocated block,
- in state BUF_BLOCK_MEMORY */
- ulint zip_size) /* in: compressed page size in bytes,
+ ulint zip_size) /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
{
buf_block_t* block;
@@ -730,13 +759,13 @@ buf_block_alloc(
return(block);
}
-/************************************************************************
+/********************************************************************//**
Frees a buffer block which does not contain a file page. */
UNIV_INLINE
void
buf_block_free(
/*===========*/
- buf_block_t* block) /* in, own: block to be freed */
+ buf_block_t* block) /*!< in, own: block to be freed */
{
//buf_pool_mutex_enter();
@@ -750,16 +779,17 @@ buf_block_free(
//buf_pool_mutex_exit();
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Copies contents of a buffer frame to a given buffer. */
+/*********************************************************************//**
+Copies contents of a buffer frame to a given buffer.
+@return buf */
UNIV_INLINE
byte*
buf_frame_copy(
/*===========*/
- /* out: buf */
- byte* buf, /* in: buffer to copy to */
- const buf_frame_t* frame) /* in: buffer frame */
+ byte* buf, /*!< in: buffer to copy to */
+ const buf_frame_t* frame) /*!< in: buffer frame */
{
ut_ad(buf && frame);
@@ -768,86 +798,49 @@ buf_frame_copy(
return(buf);
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Calculates a folded value of a file page address to use in the page hash
-table. */
+table.
+@return the folded value */
UNIV_INLINE
ulint
buf_page_address_fold(
/*==================*/
- /* out: the folded value */
- ulint space, /* in: space id */
- ulint offset) /* in: offset of the page within space */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: offset of the page within space */
{
return((space << 20) + space + offset);
}
-/************************************************************************
-This function is used to get info if there is an io operation
-going on on a buffer page. */
-UNIV_INLINE
-ibool
-buf_page_io_query(
-/*==============*/
- /* out: TRUE if io going on */
- buf_page_t* bpage) /* in: buf_pool block, must be bufferfixed */
-{
- ibool io_fixed;
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
-
- //buf_pool_mutex_enter();
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
-
- ut_ad(buf_page_in_file(bpage));
- ut_ad(bpage->buf_fix_count > 0);
-
- io_fixed = buf_page_get_io_fix(bpage) != BUF_IO_NONE;
- //buf_pool_mutex_exit();
- mutex_exit(block_mutex);
-
- return(io_fixed);
-}
-
-/************************************************************************
+/********************************************************************//**
Gets the youngest modification log sequence number for a frame.
-Returns zero if not file page or no modification occurred yet. */
+Returns zero if not file page or no modification occurred yet.
+@return newest modification to page */
UNIV_INLINE
ib_uint64_t
buf_page_get_newest_modification(
/*=============================*/
- /* out: newest modification to page */
- const buf_page_t* bpage) /* in: block containing the
+ const buf_page_t* bpage) /*!< in: block containing the
page frame */
{
ib_uint64_t lsn;
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
-
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
- if (buf_page_in_file(bpage)) {
+ if (block_mutex && buf_page_in_file(bpage)) {
lsn = bpage->newest_modification;
} else {
lsn = 0;
}
- mutex_exit(block_mutex);
+ if (block_mutex) {
+ mutex_exit(block_mutex);
+ }
return(lsn);
}
-/************************************************************************
+/********************************************************************//**
Increments the modify clock of a frame by 1. The caller must (1) own the
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
on the block. */
@@ -855,7 +848,7 @@ UNIV_INLINE
void
buf_block_modify_clock_inc(
/*=======================*/
- buf_block_t* block) /* in: block */
+ buf_block_t* block) /*!< in: block */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad((mutex_own(&LRU_list_mutex)
@@ -866,15 +859,15 @@ buf_block_modify_clock_inc(
block->modify_clock++;
}
-/************************************************************************
+/********************************************************************//**
Returns the value of the modify clock. The caller must have an s-lock
-or x-lock on the block. */
+or x-lock on the block.
+@return value */
UNIV_INLINE
ib_uint64_t
buf_block_get_modify_clock(
/*=======================*/
- /* out: value */
- buf_block_t* block) /* in: block */
+ buf_block_t* block) /*!< in: block */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
@@ -884,17 +877,17 @@ buf_block_get_modify_clock(
return(block->modify_clock);
}
-/***********************************************************************
+/*******************************************************************//**
Increments the bufferfix count. */
UNIV_INLINE
void
buf_block_buf_fix_inc_func(
/*=======================*/
#ifdef UNIV_SYNC_DEBUG
- const char* file, /* in: file name */
- ulint line, /* in: line */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line */
#endif /* UNIV_SYNC_DEBUG */
- buf_block_t* block) /* in: block to bufferfix */
+ buf_block_t* block) /*!< in/out: block to bufferfix */
{
#ifdef UNIV_SYNC_DEBUG
ibool ret;
@@ -907,18 +900,26 @@ buf_block_buf_fix_inc_func(
block->page.buf_fix_count++;
}
#ifdef UNIV_SYNC_DEBUG
+/** Increments the bufferfix count.
+@param b in/out: block to bufferfix
+@param f in: file name where requested
+@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
#else /* UNIV_SYNC_DEBUG */
+/** Increments the bufferfix count.
+@param b in/out: block to bufferfix
+@param f in: file name where requested
+@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
#endif /* UNIV_SYNC_DEBUG */
-/***********************************************************************
+/*******************************************************************//**
Decrements the bufferfix count. */
UNIV_INLINE
void
buf_block_buf_fix_dec(
/*==================*/
- buf_block_t* block) /* in: block to bufferunfix */
+ buf_block_t* block) /*!< in/out: block to bufferunfix */
{
ut_ad(mutex_own(&block->mutex));
@@ -928,15 +929,15 @@ buf_block_buf_fix_dec(
#endif
}
-/**********************************************************************
-Returns the control block of a file page, NULL if not found. */
+/******************************************************************//**
+Returns the control block of a file page, NULL if not found.
+@return block, NULL if not found */
UNIV_INLINE
buf_page_t*
buf_page_hash_get(
/*==============*/
- /* out: block, NULL if not found */
- ulint space, /* in: space id */
- ulint offset) /* in: offset of the page within space */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: offset of the page within space */
{
buf_page_t* bpage;
ulint fold;
@@ -966,32 +967,33 @@ buf_page_hash_get(
return(bpage);
}
-/**********************************************************************
+/******************************************************************//**
Returns the control block of a file page, NULL if not found
-or an uncompressed page frame does not exist. */
+or an uncompressed page frame does not exist.
+@return block, NULL if not found */
UNIV_INLINE
buf_block_t*
buf_block_hash_get(
/*===============*/
- /* out: block, NULL if not found */
- ulint space, /* in: space id */
- ulint offset) /* in: offset of the page within space */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: offset of the page within space */
{
return(buf_page_get_block(buf_page_hash_get(space, offset)));
}
-/************************************************************************
-Returns TRUE if the page can be found in the buffer pool hash table. NOTE
-that it is possible that the page is not yet read from disk, though. */
+/********************************************************************//**
+Returns TRUE if the page can be found in the buffer pool hash table.
+
+NOTE that it is possible that the page is not yet read from disk,
+though.
+
+@return TRUE if found in the page hash table */
UNIV_INLINE
ibool
buf_page_peek(
/*==========*/
- /* out: TRUE if found from page hash table,
- NOTE that the page is not necessarily yet read
- from disk! */
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
const buf_page_t* bpage;
@@ -1006,13 +1008,13 @@ buf_page_peek(
return(bpage != NULL);
}
-/************************************************************************
+/********************************************************************//**
Releases a compressed-only page acquired with buf_page_get_zip(). */
UNIV_INLINE
void
buf_page_release_zip(
/*=================*/
- buf_page_t* bpage) /* in: buffer block */
+ buf_page_t* bpage) /*!< in: buffer block */
{
buf_block_t* block;
@@ -1046,17 +1048,17 @@ buf_page_release_zip(
ut_error;
}
-/************************************************************************
+/********************************************************************//**
Decrements the bufferfix count of a buffer control block and releases
a latch, if specified. */
UNIV_INLINE
void
buf_page_release(
/*=============*/
- buf_block_t* block, /* in: buffer block */
- ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH,
+ buf_block_t* block, /*!< in: buffer block */
+ ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH,
RW_NO_LATCH */
- mtr_t* mtr __attribute__((unused))) /* in: mtr */
+ mtr_t* mtr __attribute__((unused))) /*!< in: mtr */
{
ut_ad(block);
@@ -1079,10 +1081,6 @@ buf_page_release(
#endif
block->page.buf_fix_count--;
- /* Dirty blocks should be in the flush list. */
- ut_ad(!block->page.oldest_modification
- || block->page.in_flush_list);
-
mutex_exit(&block->mutex);
if (rw_latch == RW_S_LATCH) {
@@ -1093,7 +1091,7 @@ buf_page_release(
}
#ifdef UNIV_SYNC_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Adds latch level info for the rw-lock protecting the buffer frame. This
should be called in the debug version after a successful latching of a
page if we know the latching order level of the acquired latch. */
@@ -1101,10 +1099,11 @@ UNIV_INLINE
void
buf_block_dbg_add_level(
/*====================*/
- buf_block_t* block, /* in: buffer page
+ buf_block_t* block, /*!< in: buffer page
where we have acquired latch */
- ulint level) /* in: latching order level */
+ ulint level) /*!< in: latching order level */
{
sync_thread_add_level(&block->lock, level);
}
#endif /* UNIV_SYNC_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/buf0flu.h b/storage/xtradb/include/buf0flu.h
index 11a37351479..cac4bf9fe4b 100644
--- a/storage/xtradb/include/buf0flu.h
+++ b/storage/xtradb/include/buf0flu.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0flu.h
The database buffer pool flush algorithm
Created 11/5/1995 Heikki Tuuri
@@ -26,25 +27,26 @@ Created 11/5/1995 Heikki Tuuri
#define buf0flu_h
#include "univ.i"
-#include "buf0types.h"
#include "ut0byte.h"
+#ifndef UNIV_HOTBACKUP
#include "mtr0types.h"
+#include "buf0types.h"
-/************************************************************************
+/********************************************************************//**
Remove a block from the flush list of modified blocks. */
UNIV_INTERN
void
buf_flush_remove(
/*=============*/
- buf_page_t* bpage); /* in: pointer to the block in question */
-/************************************************************************
+ buf_page_t* bpage); /*!< in: pointer to the block in question */
+/********************************************************************//**
Updates the flush system data structures when a write is completed. */
UNIV_INTERN
void
buf_flush_write_complete(
/*=====================*/
- buf_page_t* bpage); /* in: pointer to the block in question */
-/*************************************************************************
+ buf_page_t* bpage); /*!< in: pointer to the block in question */
+/*********************************************************************//**
Flushes pages from the end of the LRU list if there is too small
a margin of replaceable pages there. */
UNIV_INTERN
@@ -52,50 +54,50 @@ void
buf_flush_free_margin(
/*=======================*/
ibool wait);
-/************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Initializes a page for writing to the tablespace. */
UNIV_INTERN
void
buf_flush_init_for_writing(
/*=======================*/
- byte* page, /* in/out: page */
- void* page_zip_, /* in/out: compressed page, or NULL */
- ib_uint64_t newest_lsn); /* in: newest modification lsn
+ byte* page, /*!< in/out: page */
+ void* page_zip_, /*!< in/out: compressed page, or NULL */
+ ib_uint64_t newest_lsn); /*!< in: newest modification lsn
to the page */
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
This utility flushes dirty blocks from the end of the LRU list or flush_list.
NOTE 1: in the case of an LRU flush the calling thread may own latches to
pages: to avoid deadlocks, this function must be written so that it cannot
end up waiting for these latches! NOTE 2: in the case of a flush list flush,
-the calling thread is not allowed to own any latches on pages! */
+the calling thread is not allowed to own any latches on pages!
+@return number of blocks for which the write request was queued;
+ULINT_UNDEFINED if there was a flush of the same type already running */
UNIV_INTERN
ulint
buf_flush_batch(
/*============*/
- /* out: number of blocks for which the
- write request was queued;
- ULINT_UNDEFINED if there was a flush
- of the same type already running */
- enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
+ enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST; if BUF_FLUSH_LIST,
then the caller must not own any
latches on pages */
- ulint min_n, /* in: wished minimum mumber of blocks
+ ulint min_n, /*!< in: wished minimum mumber of blocks
flushed (it is not guaranteed that the
actual number is that big, though) */
- ib_uint64_t lsn_limit); /* in the case BUF_FLUSH_LIST all
+ ib_uint64_t lsn_limit); /*!< in the case BUF_FLUSH_LIST all
blocks whose oldest_modification is
smaller than this should be flushed
(if their number does not exceed
min_n), otherwise ignored */
-/**********************************************************************
+/******************************************************************//**
Waits until a flush batch of the given type ends */
UNIV_INTERN
void
buf_flush_wait_batch_end(
/*=====================*/
- enum buf_flush type); /* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
-/************************************************************************
+ enum buf_flush type); /*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
+/********************************************************************//**
This function should be called at a mini-transaction commit, if a page was
modified in it. Puts the block to the list of modified blocks, if it not
already in it. */
@@ -103,46 +105,85 @@ UNIV_INLINE
void
buf_flush_note_modification(
/*========================*/
- buf_block_t* block, /* in: block which is modified */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
+ buf_block_t* block, /*!< in: block which is modified */
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
This function should be called when recovery has modified a buffer page. */
UNIV_INLINE
void
buf_flush_recv_note_modification(
/*=============================*/
- buf_block_t* block, /* in: block which is modified */
- ib_uint64_t start_lsn, /* in: start lsn of the first mtr in a
+ buf_block_t* block, /*!< in: block which is modified */
+ ib_uint64_t start_lsn, /*!< in: start lsn of the first mtr in a
set of mtr's */
- ib_uint64_t end_lsn); /* in: end lsn of the last mtr in the
+ ib_uint64_t end_lsn); /*!< in: end lsn of the last mtr in the
set of mtr's */
-/************************************************************************
+/********************************************************************//**
Returns TRUE if the file page block is immediately suitable for replacement,
-i.e., transition FILE_PAGE => NOT_USED allowed. */
+i.e., transition FILE_PAGE => NOT_USED allowed.
+@return TRUE if can replace immediately */
UNIV_INTERN
ibool
buf_flush_ready_for_replace(
/*========================*/
- /* out: TRUE if can replace immediately */
- buf_page_t* bpage); /* in: buffer control block, must be
+ buf_page_t* bpage); /*!< in: buffer control block, must be
buf_page_in_file(bpage) and in the LRU list */
+
+/** @brief Statistics for selecting flush rate based on redo log
+generation speed.
+
+These statistics are generated for heuristics used in estimating the
+rate at which we should flush the dirty blocks to avoid bursty IO
+activity. Note that the rate of flushing not only depends on how many
+dirty pages we have in the buffer pool but it is also a fucntion of
+how much redo the workload is generating and at what rate. */
+
+struct buf_flush_stat_struct
+{
+ ib_uint64_t redo; /**< amount of redo generated. */
+ ulint n_flushed; /**< number of pages flushed. */
+};
+
+/** Statistics for selecting flush rate of dirty pages. */
+typedef struct buf_flush_stat_struct buf_flush_stat_t;
+/*********************************************************************
+Update the historical stats that we are collecting for flush rate
+heuristics at the end of each interval. */
+UNIV_INTERN
+void
+buf_flush_stat_update(void);
+/*=======================*/
+/*********************************************************************
+Determines the fraction of dirty pages that need to be flushed based
+on the speed at which we generate redo log. Note that if redo log
+is generated at significant rate without a corresponding increase
+in the number of dirty pages (for example, an in-memory workload)
+it can cause IO bursts of flushing. This function implements heuristics
+to avoid this burstiness.
+@return number of dirty pages to be flushed / second */
+UNIV_INTERN
+ulint
+buf_flush_get_desired_flush_rate(void);
+/*==================================*/
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**********************************************************************
-Validates the flush list. */
+/******************************************************************//**
+Validates the flush list.
+@return TRUE if ok */
UNIV_INTERN
ibool
buf_flush_validate(void);
/*====================*/
- /* out: TRUE if ok */
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-/* When buf_flush_free_margin is called, it tries to make this many blocks
+/** When buf_flush_free_margin is called, it tries to make this many blocks
available to replacement in the free list and at the end of the LRU list (to
make sure that a read-ahead batch can be read efficiently in a single
sweep). */
-
#define BUF_FLUSH_FREE_BLOCK_MARGIN (5 + BUF_READ_AHEAD_AREA)
+/** Extra margin to apply above BUF_FLUSH_FREE_BLOCK_MARGIN */
#define BUF_FLUSH_EXTRA_MARGIN (BUF_FLUSH_FREE_BLOCK_MARGIN / 4 + 100)
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "buf0flu.ic"
diff --git a/storage/xtradb/include/buf0flu.ic b/storage/xtradb/include/buf0flu.ic
index c466caae347..4ad0814f344 100644
--- a/storage/xtradb/include/buf0flu.ic
+++ b/storage/xtradb/include/buf0flu.ic
@@ -16,23 +16,25 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0flu.ic
The database buffer pool flush algorithm
Created 11/5/1995 Heikki Tuuri
*******************************************************/
+#ifndef UNIV_HOTBACKUP
#include "buf0buf.h"
#include "mtr0mtr.h"
-/************************************************************************
+/********************************************************************//**
Inserts a modified block into the flush list. */
UNIV_INTERN
void
buf_flush_insert_into_flush_list(
/*=============================*/
- buf_block_t* block); /* in/out: block which is modified */
-/************************************************************************
+ buf_block_t* block); /*!< in/out: block which is modified */
+/********************************************************************//**
Inserts a modified block into the flush list in the right sorted position.
This function is used by recovery, because there the modifications do not
necessarily come in the order of lsn's. */
@@ -40,9 +42,9 @@ UNIV_INTERN
void
buf_flush_insert_sorted_into_flush_list(
/*====================================*/
- buf_block_t* block); /* in/out: block which is modified */
+ buf_block_t* block); /*!< in/out: block which is modified */
-/************************************************************************
+/********************************************************************//**
This function should be called at a mini-transaction commit, if a page was
modified in it. Puts the block to the list of modified blocks, if it is not
already in it. */
@@ -50,8 +52,8 @@ UNIV_INLINE
void
buf_flush_note_modification(
/*========================*/
- buf_block_t* block, /* in: block which is modified */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: block which is modified */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool use_LRU_mutex = FALSE;
@@ -97,16 +99,16 @@ buf_flush_note_modification(
mutex_exit(&LRU_list_mutex);
}
-/************************************************************************
+/********************************************************************//**
This function should be called when recovery has modified a buffer page. */
UNIV_INLINE
void
buf_flush_recv_note_modification(
/*=============================*/
- buf_block_t* block, /* in: block which is modified */
- ib_uint64_t start_lsn, /* in: start lsn of the first mtr in a
+ buf_block_t* block, /*!< in: block which is modified */
+ ib_uint64_t start_lsn, /*!< in: start lsn of the first mtr in a
set of mtr's */
- ib_uint64_t end_lsn) /* in: end lsn of the last mtr in the
+ ib_uint64_t end_lsn) /*!< in: end lsn of the last mtr in the
set of mtr's */
{
ibool use_LRU_mutex = FALSE;
@@ -150,3 +152,4 @@ buf_flush_recv_note_modification(
mutex_exit(&LRU_list_mutex);
mutex_exit(&(block->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h
index 3fd534a215d..0a7d01c95cf 100644
--- a/storage/xtradb/include/buf0lru.h
+++ b/storage/xtradb/include/buf0lru.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0lru.h
The database buffer pool LRU replacement algorithm
Created 11/5/1995 Heikki Tuuri
@@ -41,7 +42,7 @@ enum buf_lru_free_block_status {
BUF_LRU_NOT_FREED
};
-/**********************************************************************
+/******************************************************************//**
Tries to remove LRU flushed blocks from the end of the LRU list and put them
to the free list. This is beneficial for the efficiency of the insert buffer
operation, as flushed pages from non-unique non-clustered indexes are here
@@ -53,28 +54,27 @@ UNIV_INTERN
void
buf_LRU_try_free_flushed_blocks(void);
/*==================================*/
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if less than 25 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer
-pool for their locks. */
+pool for their locks.
+@return TRUE if less than 25 % of buffer pool left */
UNIV_INTERN
ibool
buf_LRU_buf_pool_running_out(void);
/*==============================*/
- /* out: TRUE if less than 25 % of buffer pool
- left */
/*#######################################################################
These are low-level functions
#########################################################################*/
-/* Minimum LRU list length for which the LRU_old pointer is defined */
-
-#define BUF_LRU_OLD_MIN_LEN 80
+/** Minimum LRU list length for which the LRU_old pointer is defined */
+#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
+/** Maximum LRU list search length in buf_flush_LRU_recommendation() */
#define BUF_LRU_FREE_SEARCH_LEN (5 + 2 * BUF_READ_AHEAD_AREA)
-/**********************************************************************
+/******************************************************************//**
Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. A PROBLEM: if readahead is being started,
what guarantees that it will not try to read in pages after this operation has
@@ -83,25 +83,16 @@ UNIV_INTERN
void
buf_LRU_invalidate_tablespace(
/*==========================*/
- ulint id); /* in: space id */
-/**********************************************************************
-Gets the minimum LRU_position field for the blocks in an initial segment
-(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around. */
-UNIV_INTERN
-ulint
-buf_LRU_get_recent_limit(void);
-/*==========================*/
- /* out: the limit; zero if could not determine it */
-/************************************************************************
+ ulint id); /*!< in: space id */
+/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
void
buf_LRU_insert_zip_clean(
/*=====================*/
- buf_page_t* bpage); /* in: pointer to the block in question */
+ buf_page_t* bpage); /*!< in: pointer to the block in question */
-/**********************************************************************
+/******************************************************************//**
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
@@ -111,30 +102,29 @@ accessible via bpage.
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
-buf_page_get_mutex() may be held when calling this function. */
+buf_page_get_mutex() may be held when calling this function.
+@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
+BUF_LRU_NOT_FREED otherwise. */
UNIV_INTERN
enum buf_lru_free_block_status
buf_LRU_free_block(
/*===============*/
- /* out: BUF_LRU_FREED if freed,
- BUF_LRU_CANNOT_RELOCATE or
- BUF_LRU_NOT_FREED otherwise. */
- buf_page_t* bpage, /* in: block to be freed */
- ibool zip, /* in: TRUE if should remove also the
+ buf_page_t* bpage, /*!< in: block to be freed */
+ ibool zip, /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
ibool* buf_pool_mutex_released,
- /* in: pointer to a variable that will
+ /*!< in: pointer to a variable that will
be assigned TRUE if buf_pool_mutex
was temporarily released, or NULL */
ibool have_LRU_mutex);
-/**********************************************************************
-Try to free a replaceable block. */
+/******************************************************************//**
+Try to free a replaceable block.
+@return TRUE if found and freed */
UNIV_INTERN
ibool
buf_LRU_search_and_free_block(
/*==========================*/
- /* out: TRUE if found and freed */
- ulint n_iterations); /* in: how many times this has been called
+ ulint n_iterations); /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@@ -142,88 +132,111 @@ buf_LRU_search_and_free_block(
pages from the end of the LRU list; if
n_iterations < 5, then we will also search
n_iterations / 5 of the unzip_LRU list. */
-/**********************************************************************
+/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
-free list. If it is empty, returns NULL. */
+free list. If it is empty, returns NULL.
+@return a free control block, or NULL if the buf_block->free list is empty */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_only(void);
/*=======================*/
- /* out: a free control block, or NULL
- if the buf_block->free list is empty */
-/**********************************************************************
+/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, blocks are moved from the end of the
-LRU list to the free list. */
+LRU list to the free list.
+@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_block(
/*===================*/
- /* out: the free control block,
- in state BUF_BLOCK_READY_FOR_USE */
- ulint zip_size); /* in: compressed page size in bytes,
+ ulint zip_size); /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
-/**********************************************************************
+/******************************************************************//**
Puts a block back to the free list. */
UNIV_INTERN
void
buf_LRU_block_free_non_file_page(
/*=============================*/
- buf_block_t* block, /* in: block, must not contain a file page */
+ buf_block_t* block, /*!< in: block, must not contain a file page */
ibool have_page_hash_mutex);
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INTERN
void
buf_LRU_add_block(
/*==============*/
- buf_page_t* bpage, /* in: control block */
- ibool old); /* in: TRUE if should be put to the old
+ buf_page_t* bpage, /*!< in: control block */
+ ibool old); /*!< in: TRUE if should be put to the old
blocks in the LRU list, else put to the
start; if the LRU list is very short, added to
the start regardless of this parameter */
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list of decompressed zip pages. */
UNIV_INTERN
void
buf_unzip_LRU_add_block(
/*====================*/
- buf_block_t* block, /* in: control block */
- ibool old); /* in: TRUE if should be put to the end
+ buf_block_t* block, /*!< in: control block */
+ ibool old); /*!< in: TRUE if should be put to the end
of the list, else put to the start */
-/**********************************************************************
+/******************************************************************//**
Moves a block to the start of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_young(
/*=====================*/
- buf_page_t* bpage); /* in: control block */
-/**********************************************************************
+ buf_page_t* bpage); /*!< in: control block */
+/******************************************************************//**
Moves a block to the end of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_old(
/*===================*/
- buf_page_t* bpage); /* in: control block */
-/************************************************************************
+ buf_page_t* bpage); /*!< in: control block */
+/**********************************************************************//**
+Updates buf_LRU_old_ratio.
+@return updated old_pct */
+UNIV_INTERN
+uint
+buf_LRU_old_ratio_update(
+/*=====================*/
+ uint old_pct,/*!< in: Reserve this percentage of
+ the buffer pool for "old" blocks. */
+ ibool adjust);/*!< in: TRUE=adjust the LRU list;
+ FALSE=just assign buf_LRU_old_ratio
+ during the initialization of InnoDB */
+/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
UNIV_INTERN
void
buf_LRU_stat_update(void);
/*=====================*/
+/********************************************************************//**
+Dump the LRU page list to the specific file. */
+UNIV_INTERN
+ibool
+buf_LRU_file_dump(void);
+/*===================*/
+/********************************************************************//**
+Read the pages based on the specific file.*/
+UNIV_INTERN
+ibool
+buf_LRU_file_restore(void);
+/*======================*/
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
-Validates the LRU list. */
+/**********************************************************************//**
+Validates the LRU list.
+@return TRUE */
UNIV_INTERN
ibool
buf_LRU_validate(void);
/*==================*/
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Prints the LRU list. */
UNIV_INTERN
void
@@ -231,18 +244,47 @@ buf_LRU_print(void);
/*===============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
-/**********************************************************************
+/** @name Heuristics for detecting index scan @{ */
+/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
+"old" blocks. Protected by buf_pool_mutex. */
+extern uint buf_LRU_old_ratio;
+/** The denominator of buf_LRU_old_ratio. */
+#define BUF_LRU_OLD_RATIO_DIV 1024
+/** Maximum value of buf_LRU_old_ratio.
+@see buf_LRU_old_adjust_len
+@see buf_LRU_old_ratio_update */
+#define BUF_LRU_OLD_RATIO_MAX BUF_LRU_OLD_RATIO_DIV
+/** Minimum value of buf_LRU_old_ratio.
+@see buf_LRU_old_adjust_len
+@see buf_LRU_old_ratio_update
+The minimum must exceed
+(BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */
+#define BUF_LRU_OLD_RATIO_MIN 51
+
+#if BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX
+# error "BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX"
+#endif
+#if BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV
+# error "BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV"
+#endif
+
+/** Move blocks to "new" LRU list only if the first access was at
+least this many milliseconds ago. Not protected by any mutex or latch. */
+extern uint buf_LRU_old_threshold_ms;
+/* @} */
+
+/** @brief Statistics for selecting the LRU list for eviction.
+
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics we decide
if we want to evict from buf_pool->unzip_LRU or buf_pool->LRU. */
-
-/** Statistics for selecting the LRU list for eviction. */
struct buf_LRU_stat_struct
{
ulint io; /**< Counter of buffer pool I/O operations. */
ulint unzip; /**< Counter of page_zip_decompress operations. */
};
+/** Statistics for selecting the LRU list for eviction. */
typedef struct buf_LRU_stat_struct buf_LRU_stat_t;
/** Current operation counters. Not protected by any mutex.
@@ -253,10 +295,10 @@ extern buf_LRU_stat_t buf_LRU_stat_cur;
Updated by buf_LRU_stat_update(). Protected by buf_pool_mutex. */
extern buf_LRU_stat_t buf_LRU_stat_sum;
-/************************************************************************
+/********************************************************************//**
Increments the I/O counter in buf_LRU_stat_cur. */
#define buf_LRU_stat_inc_io() buf_LRU_stat_cur.io++
-/************************************************************************
+/********************************************************************//**
Increments the page_zip_decompress() counter in buf_LRU_stat_cur. */
#define buf_LRU_stat_inc_unzip() buf_LRU_stat_cur.unzip++
diff --git a/storage/xtradb/include/buf0lru.ic b/storage/xtradb/include/buf0lru.ic
index f4c40e0b606..556f45d987f 100644
--- a/storage/xtradb/include/buf0lru.ic
+++ b/storage/xtradb/include/buf0lru.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0lru.ic
The database buffer replacement algorithm
Created 11/5/1995 Heikki Tuuri
diff --git a/storage/xtradb/include/buf0rea.h b/storage/xtradb/include/buf0rea.h
index 6d138a3a02b..71f62ff7b49 100644
--- a/storage/xtradb/include/buf0rea.h
+++ b/storage/xtradb/include/buf0rea.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0rea.h
The database buffer read
Created 11/5/1995 Heikki Tuuri
@@ -26,28 +27,59 @@ Created 11/5/1995 Heikki Tuuri
#define buf0rea_h
#include "univ.i"
+#include "trx0types.h"
#include "buf0types.h"
-/************************************************************************
+/********************************************************************//**
+Low-level function which reads a page asynchronously from a file to the
+buffer buf_pool if it is not already there, in which case does nothing.
+Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
+flag is cleared and the x-lock released by an i/o-handler thread.
+@return 1 if a read request was queued, 0 if the page already resided
+in buf_pool, or if the page is in the doublewrite buffer blocks in
+which case it is never read into the pool, or if the tablespace does
+not exist or is being dropped
+@return 1 if read request is issued. 0 if it is not */
+UNIV_INTERN
+ulint
+buf_read_page_low(
+/*==============*/
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
+ trying to read from a non-existent tablespace, or a
+ tablespace which is just now being dropped */
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
+ ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
+ at read-ahead functions) */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
+ ib_int64_t tablespace_version, /*!< in: if the space memory object has
+ this timestamp different from what we are giving here,
+ treat the tablespace as dropped; this is a timestamp we
+ use to stop dangling page reads from a tablespace
+ which we have DISCARDed + IMPORTed back */
+ ulint offset, /*!< in: page number */
+ trx_t* trx);
+/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible. */
+released by the i/o-handler thread.
+@return TRUE if page has been read in, FALSE in case of failure */
UNIV_INTERN
-ulint
+ibool
buf_read_page(
/*==========*/
- /* out: number of page read requests issued: this can
- be > 1 if read-ahead occurred */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset, /*!< in: page number */
+ trx_t* trx);
+/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
-that the the algorithm looks at the 'natural' adjacent successor and
+that the algorithm looks at the 'natural' adjacent successor and
predecessor of the page, which on the leaf level of a B-tree are the next
and previous page in the chain of leaves. To know these, the page specified
in (space, offset) must already be present in the buf_pool. Thus, the
@@ -65,17 +97,18 @@ function must be written such that it cannot end up waiting for these
latches!
NOTE 3: the calling thread must want access to the page given: this rule is
set to prevent unintended read-aheads performed by ibuf routines, a situation
-which could result in a deadlock if the OS does not support asynchronous io. */
+which could result in a deadlock if the OS does not support asynchronous io.
+@return number of page read requests issued */
UNIV_INTERN
ulint
buf_read_ahead_linear(
/*==================*/
- /* out: number of page read requests issued */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset);/* in: page number of a page; NOTE: the current thread
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset, /*!< in: page number of a page; NOTE: the current thread
must want access to this page (see NOTE 3 above) */
-/************************************************************************
+ trx_t* trx);
+/********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like
a read-ahead function. */
@@ -83,54 +116,56 @@ UNIV_INTERN
void
buf_read_ibuf_merge_pages(
/*======================*/
- ibool sync, /* in: TRUE if the caller
+ ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
- const ulint* space_ids, /* in: array of space ids */
- const ib_int64_t* space_versions,/* in: the spaces must have
+ const ulint* space_ids, /*!< in: array of space ids */
+ const ib_int64_t* space_versions,/*!< in: the spaces must have
this version number
(timestamp), otherwise we
discard the read; we use this
to cancel reads if DISCARD +
IMPORT may have changed the
tablespace size */
- const ulint* page_nos, /* in: array of page numbers
+ const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
- ulint n_stored); /* in: number of elements
+ ulint n_stored); /*!< in: number of elements
in the arrays */
-/************************************************************************
+/********************************************************************//**
Issues read requests for pages which recovery wants to read in. */
UNIV_INTERN
void
buf_read_recv_pages(
/*================*/
- ibool sync, /* in: TRUE if the caller
+ ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in
bytes, or 0 */
- const ulint* page_nos, /* in: array of page numbers
+ const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
- ulint n_stored); /* in: number of page numbers
+ ulint n_stored); /*!< in: number of page numbers
in the array */
-/* The size in pages of the area which the read-ahead algorithms read if
+/** The size in pages of the area which the read-ahead algorithms read if
invoked */
-
#define BUF_READ_AHEAD_AREA \
ut_min(64, ut_2_power_up(buf_pool->curr_size / 32))
-/* Modes used in read-ahead */
+/** @name Modes used in read-ahead @{ */
+/** read only pages belonging to the insert buffer tree */
#define BUF_READ_IBUF_PAGES_ONLY 131
+/** read any page */
#define BUF_READ_ANY_PAGE 132
+/* @} */
#endif
diff --git a/storage/xtradb/include/buf0types.h b/storage/xtradb/include/buf0types.h
index f2721da85f9..bfae6477135 100644
--- a/storage/xtradb/include/buf0types.h
+++ b/storage/xtradb/include/buf0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0types.h
The database buffer pool global types for the directory
Created 11/17/1995 Heikki Tuuri
@@ -25,46 +26,57 @@ Created 11/17/1995 Heikki Tuuri
#ifndef buf0types_h
#define buf0types_h
+/** Buffer page (uncompressed or compressed) */
typedef struct buf_page_struct buf_page_t;
+/** Buffer block for which an uncompressed page exists */
typedef struct buf_block_struct buf_block_t;
+/** Buffer pool chunk comprising buf_block_t */
typedef struct buf_chunk_struct buf_chunk_t;
+/** Buffer pool comprising buf_chunk_t */
typedef struct buf_pool_struct buf_pool_t;
+/** Buffer pool statistics struct */
+typedef struct buf_pool_stat_struct buf_pool_stat_t;
-/* The 'type' used of a buffer frame */
+/** A buffer frame. @see page_t */
typedef byte buf_frame_t;
-/* Flags for flush types */
+/** Flags for flush types */
enum buf_flush {
- BUF_FLUSH_LRU = 0,
- BUF_FLUSH_SINGLE_PAGE,
- BUF_FLUSH_LIST,
- BUF_FLUSH_N_TYPES /* index of last element + 1 */
+ BUF_FLUSH_LRU = 0, /*!< flush via the LRU list */
+ BUF_FLUSH_SINGLE_PAGE, /*!< flush a single page */
+ BUF_FLUSH_LIST, /*!< flush via the flush list
+ of dirty blocks */
+ BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
};
-/* Flags for io_fix types */
+/** Flags for io_fix types */
enum buf_io_fix {
BUF_IO_NONE = 0, /**< no pending I/O */
BUF_IO_READ, /**< read pending */
BUF_IO_WRITE /**< write pending */
};
-/* Parameters of binary buddy system for compressed pages (buf0buddy.h) */
+/** Parameters of binary buddy system for compressed pages (buf0buddy.h) */
+/* @{ */
#if UNIV_WORD_SIZE <= 4 /* 32-bit system */
+/** Base-2 logarithm of the smallest buddy block size */
# define BUF_BUDDY_LOW_SHIFT 6
#else /* 64-bit system */
+/** Base-2 logarithm of the smallest buddy block size */
# define BUF_BUDDY_LOW_SHIFT 7
#endif
#define BUF_BUDDY_LOW (1 << BUF_BUDDY_LOW_SHIFT)
- /* minimum block size in the binary
+ /*!< minimum block size in the binary
buddy system; must be at least
sizeof(buf_page_t) */
#define BUF_BUDDY_SIZES (UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT)
- /* number of buddy sizes */
+ /*!< number of buddy sizes */
-/* twice the maximum block size of the buddy system;
+/** twice the maximum block size of the buddy system;
the underlying memory is aligned by this amount:
this must be equal to UNIV_PAGE_SIZE */
#define BUF_BUDDY_HIGH (BUF_BUDDY_LOW << BUF_BUDDY_SIZES)
+/* @} */
#endif
diff --git a/storage/xtradb/include/data0data.h b/storage/xtradb/include/data0data.h
index 1190a7ae45a..f9fce3f3657 100644
--- a/storage/xtradb/include/data0data.h
+++ b/storage/xtradb/include/data0data.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/data0data.h
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@@ -32,376 +33,375 @@ Created 5/30/1994 Heikki Tuuri
#include "mem0mem.h"
#include "dict0types.h"
+/** Storage for overflow data in a big record, that is, a clustered
+index record which needs external storage of data fields */
typedef struct big_rec_struct big_rec_t;
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets pointer to the type struct of SQL data field. */
+/*********************************************************************//**
+Gets pointer to the type struct of SQL data field.
+@return pointer to the type struct */
UNIV_INLINE
dtype_t*
dfield_get_type(
/*============*/
- /* out: pointer to the type struct */
- const dfield_t* field); /* in: SQL data field */
-/*************************************************************************
-Gets pointer to the data in a field. */
+ const dfield_t* field); /*!< in: SQL data field */
+/*********************************************************************//**
+Gets pointer to the data in a field.
+@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
/*============*/
- /* out: pointer to data */
- const dfield_t* field); /* in: field */
+ const dfield_t* field); /*!< in: field */
#else /* UNIV_DEBUG */
# define dfield_get_type(field) (&(field)->type)
# define dfield_get_data(field) ((field)->data)
#endif /* UNIV_DEBUG */
-/*************************************************************************
+/*********************************************************************//**
Sets the type struct of SQL data field. */
UNIV_INLINE
void
dfield_set_type(
/*============*/
- dfield_t* field, /* in: SQL data field */
- dtype_t* type); /* in: pointer to data type struct */
-/*************************************************************************
-Gets length of field data. */
+ dfield_t* field, /*!< in: SQL data field */
+ dtype_t* type); /*!< in: pointer to data type struct */
+/*********************************************************************//**
+Gets length of field data.
+@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
/*===========*/
- /* out: length of data; UNIV_SQL_NULL if
- SQL null data */
- const dfield_t* field); /* in: field */
-/*************************************************************************
+ const dfield_t* field); /*!< in: field */
+/*********************************************************************//**
Sets length in a field. */
UNIV_INLINE
void
dfield_set_len(
/*===========*/
- dfield_t* field, /* in: field */
- ulint len); /* in: length or UNIV_SQL_NULL */
-/*************************************************************************
-Determines if a field is SQL NULL */
+ dfield_t* field, /*!< in: field */
+ ulint len); /*!< in: length or UNIV_SQL_NULL */
+/*********************************************************************//**
+Determines if a field is SQL NULL
+@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
/*===========*/
- /* out: nonzero if SQL null data */
- const dfield_t* field); /* in: field */
-/*************************************************************************
-Determines if a field is externally stored */
+ const dfield_t* field); /*!< in: field */
+/*********************************************************************//**
+Determines if a field is externally stored
+@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
/*==========*/
- /* out: nonzero if externally stored */
- const dfield_t* field); /* in: field */
-/*************************************************************************
+ const dfield_t* field); /*!< in: field */
+/*********************************************************************//**
Sets the "external storage" flag */
UNIV_INLINE
void
dfield_set_ext(
/*===========*/
- dfield_t* field); /* in/out: field */
-/*************************************************************************
+ dfield_t* field); /*!< in/out: field */
+/*********************************************************************//**
Sets pointer to the data and length in a field. */
UNIV_INLINE
void
dfield_set_data(
/*============*/
- dfield_t* field, /* in: field */
- const void* data, /* in: data */
- ulint len); /* in: length or UNIV_SQL_NULL */
-/*************************************************************************
+ dfield_t* field, /*!< in: field */
+ const void* data, /*!< in: data */
+ ulint len); /*!< in: length or UNIV_SQL_NULL */
+/*********************************************************************//**
Sets a data field to SQL NULL. */
UNIV_INLINE
void
dfield_set_null(
/*============*/
- dfield_t* field); /* in/out: field */
-/**************************************************************************
+ dfield_t* field); /*!< in/out: field */
+/**********************************************************************//**
Writes an SQL null field full of zeros. */
UNIV_INLINE
void
data_write_sql_null(
/*================*/
- byte* data, /* in: pointer to a buffer of size len */
- ulint len); /* in: SQL null size in bytes */
-/*************************************************************************
+ byte* data, /*!< in: pointer to a buffer of size len */
+ ulint len); /*!< in: SQL null size in bytes */
+/*********************************************************************//**
Copies the data and len fields. */
UNIV_INLINE
void
dfield_copy_data(
/*=============*/
- dfield_t* field1, /* out: field to copy to */
- const dfield_t* field2);/* in: field to copy from */
-/*************************************************************************
+ dfield_t* field1, /*!< out: field to copy to */
+ const dfield_t* field2);/*!< in: field to copy from */
+/*********************************************************************//**
Copies a data field to another. */
UNIV_INLINE
void
dfield_copy(
/*========*/
- dfield_t* field1, /* out: field to copy to */
- const dfield_t* field2);/* in: field to copy from */
-/*************************************************************************
+ dfield_t* field1, /*!< out: field to copy to */
+ const dfield_t* field2);/*!< in: field to copy from */
+/*********************************************************************//**
Copies the data pointed to by a data field. */
UNIV_INLINE
void
dfield_dup(
/*=======*/
- dfield_t* field, /* in/out: data field */
- mem_heap_t* heap); /* in: memory heap where allocated */
-/*************************************************************************
-Tests if data length and content is equal for two dfields. */
+ dfield_t* field, /*!< in/out: data field */
+ mem_heap_t* heap); /*!< in: memory heap where allocated */
+/*********************************************************************//**
+Tests if data length and content is equal for two dfields.
+@return TRUE if equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
/*==========================*/
- /* out: TRUE if equal */
- const dfield_t* field1, /* in: field */
- const dfield_t* field2);/* in: field */
-/*************************************************************************
-Tests if dfield data length and content is equal to the given. */
+ const dfield_t* field1, /*!< in: field */
+ const dfield_t* field2);/*!< in: field */
+/*********************************************************************//**
+Tests if dfield data length and content is equal to the given.
+@return TRUE if equal */
UNIV_INTERN
ibool
dfield_data_is_binary_equal(
/*========================*/
- /* out: TRUE if equal */
- const dfield_t* field, /* in: field */
- ulint len, /* in: data length or UNIV_SQL_NULL */
- const byte* data); /* in: data */
-/*************************************************************************
-Gets number of fields in a data tuple. */
+ const dfield_t* field, /*!< in: field */
+ ulint len, /*!< in: data length or UNIV_SQL_NULL */
+ const byte* data); /*!< in: data */
+/*********************************************************************//**
+Gets number of fields in a data tuple.
+@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
- /* out: number of fields */
- const dtuple_t* tuple); /* in: tuple */
+ const dtuple_t* tuple); /*!< in: tuple */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets nth field of a tuple. */
+/*********************************************************************//**
+Gets nth field of a tuple.
+@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
/*=================*/
- /* out: nth field */
- const dtuple_t* tuple, /* in: tuple */
- ulint n); /* in: index of field */
+ const dtuple_t* tuple, /*!< in: tuple */
+ ulint n); /*!< in: index of field */
#else /* UNIV_DEBUG */
# define dtuple_get_nth_field(tuple, n) ((tuple)->fields + (n))
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Gets info bits in a data tuple. */
+/*********************************************************************//**
+Gets info bits in a data tuple.
+@return info bits */
UNIV_INLINE
ulint
dtuple_get_info_bits(
/*=================*/
- /* out: info bits */
- const dtuple_t* tuple); /* in: tuple */
-/*************************************************************************
+ const dtuple_t* tuple); /*!< in: tuple */
+/*********************************************************************//**
Sets info bits in a data tuple. */
UNIV_INLINE
void
dtuple_set_info_bits(
/*=================*/
- dtuple_t* tuple, /* in: tuple */
- ulint info_bits); /* in: info bits */
-/*************************************************************************
-Gets number of fields used in record comparisons. */
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint info_bits); /*!< in: info bits */
+/*********************************************************************//**
+Gets number of fields used in record comparisons.
+@return number of fields used in comparisons in rem0cmp.* */
UNIV_INLINE
ulint
dtuple_get_n_fields_cmp(
/*====================*/
- /* out: number of fields used in comparisons
- in rem0cmp.* */
- const dtuple_t* tuple); /* in: tuple */
-/*************************************************************************
+ const dtuple_t* tuple); /*!< in: tuple */
+/*********************************************************************//**
Gets number of fields used in record comparisons. */
UNIV_INLINE
void
dtuple_set_n_fields_cmp(
/*====================*/
- dtuple_t* tuple, /* in: tuple */
- ulint n_fields_cmp); /* in: number of fields used in
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint n_fields_cmp); /*!< in: number of fields used in
comparisons in rem0cmp.* */
-/**************************************************************
+/**********************************************************//**
Creates a data tuple to a memory heap. The default value for number
-of fields used in record comparisons for this tuple is n_fields. */
+of fields used in record comparisons for this tuple is n_fields.
+@return own: created tuple */
UNIV_INLINE
dtuple_t*
dtuple_create(
/*==========*/
- /* out, own: created tuple */
- mem_heap_t* heap, /* in: memory heap where the tuple
+ mem_heap_t* heap, /*!< in: memory heap where the tuple
is created */
- ulint n_fields); /* in: number of fields */
+ ulint n_fields); /*!< in: number of fields */
-/**************************************************************
+/**********************************************************//**
Wrap data fields in a tuple. The default value for number
-of fields used in record comparisons for this tuple is n_fields. */
+of fields used in record comparisons for this tuple is n_fields.
+@return data tuple */
UNIV_INLINE
const dtuple_t*
dtuple_from_fields(
/*===============*/
- /* out: data tuple */
- dtuple_t* tuple, /* in: storage for data tuple */
- const dfield_t* fields, /* in: fields */
- ulint n_fields); /* in: number of fields */
+ dtuple_t* tuple, /*!< in: storage for data tuple */
+ const dfield_t* fields, /*!< in: fields */
+ ulint n_fields); /*!< in: number of fields */
-/*************************************************************************
+/*********************************************************************//**
Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */
UNIV_INTERN
void
dtuple_set_n_fields(
/*================*/
- dtuple_t* tuple, /* in: tuple */
- ulint n_fields); /* in: number of fields */
-/*************************************************************************
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint n_fields); /*!< in: number of fields */
+/*********************************************************************//**
Copies a data tuple to another. This is a shallow copy; if a deep copy
-is desired, dfield_dup() will have to be invoked on each field. */
+is desired, dfield_dup() will have to be invoked on each field.
+@return own: copy of tuple */
UNIV_INLINE
dtuple_t*
dtuple_copy(
/*========*/
- /* out, own: copy of tuple */
- const dtuple_t* tuple, /* in: tuple to copy from */
- mem_heap_t* heap); /* in: memory heap
+ const dtuple_t* tuple, /*!< in: tuple to copy from */
+ mem_heap_t* heap); /*!< in: memory heap
where the tuple is created */
-/**************************************************************
+/**********************************************************//**
The following function returns the sum of data lengths of a tuple. The space
-occupied by the field structs or the tuple struct is not counted. */
+occupied by the field structs or the tuple struct is not counted.
+@return sum of data lens */
UNIV_INLINE
ulint
dtuple_get_data_size(
/*=================*/
- /* out: sum of data lens */
- const dtuple_t* tuple); /* in: typed data tuple */
-/*************************************************************************
-Computes the number of externally stored fields in a data tuple. */
+ const dtuple_t* tuple, /*!< in: typed data tuple */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
+/*********************************************************************//**
+Computes the number of externally stored fields in a data tuple.
+@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_ext(
/*=============*/
- /* out: number of fields */
- const dtuple_t* tuple); /* in: tuple */
-/****************************************************************
-Compare two data tuples, respecting the collation of character fields. */
+ const dtuple_t* tuple); /*!< in: tuple */
+/************************************************************//**
+Compare two data tuples, respecting the collation of character fields.
+@return 1, 0 , -1 if tuple1 is greater, equal, less, respectively,
+than tuple2 */
UNIV_INTERN
int
dtuple_coll_cmp(
/*============*/
- /* out: 1, 0 , -1 if tuple1 is greater, equal,
- less, respectively, than tuple2 */
- const dtuple_t* tuple1, /* in: tuple 1 */
- const dtuple_t* tuple2);/* in: tuple 2 */
-/****************************************************************
-Folds a prefix given as the number of fields of a tuple. */
+ const dtuple_t* tuple1, /*!< in: tuple 1 */
+ const dtuple_t* tuple2);/*!< in: tuple 2 */
+/************************************************************//**
+Folds a prefix given as the number of fields of a tuple.
+@return the folded value */
UNIV_INLINE
ulint
dtuple_fold(
/*========*/
- /* out: the folded value */
- const dtuple_t* tuple, /* in: the tuple */
- ulint n_fields,/* in: number of complete fields to fold */
- ulint n_bytes,/* in: number of bytes to fold in an
+ const dtuple_t* tuple, /*!< in: the tuple */
+ ulint n_fields,/*!< in: number of complete fields to fold */
+ ulint n_bytes,/*!< in: number of bytes to fold in an
incomplete last field */
- dulint tree_id)/* in: index tree id */
+ dulint tree_id)/*!< in: index tree id */
__attribute__((pure));
-/***********************************************************************
+/*******************************************************************//**
Sets types of fields binary in a tuple. */
UNIV_INLINE
void
dtuple_set_types_binary(
/*====================*/
- dtuple_t* tuple, /* in: data tuple */
- ulint n); /* in: number of fields to set */
-/**************************************************************************
-Checks if a dtuple contains an SQL null value. */
+ dtuple_t* tuple, /*!< in: data tuple */
+ ulint n); /*!< in: number of fields to set */
+/**********************************************************************//**
+Checks if a dtuple contains an SQL null value.
+@return TRUE if some field is SQL null */
UNIV_INLINE
ibool
dtuple_contains_null(
/*=================*/
- /* out: TRUE if some field is SQL null */
- const dtuple_t* tuple); /* in: dtuple */
-/**************************************************************
-Checks that a data field is typed. Asserts an error if not. */
+ const dtuple_t* tuple); /*!< in: dtuple */
+/**********************************************************//**
+Checks that a data field is typed. Asserts an error if not.
+@return TRUE if ok */
UNIV_INTERN
ibool
dfield_check_typed(
/*===============*/
- /* out: TRUE if ok */
- const dfield_t* field); /* in: data field */
-/**************************************************************
-Checks that a data tuple is typed. Asserts an error if not. */
+ const dfield_t* field); /*!< in: data field */
+/**********************************************************//**
+Checks that a data tuple is typed. Asserts an error if not.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed(
/*===============*/
- /* out: TRUE if ok */
- const dtuple_t* tuple); /* in: tuple */
-/**************************************************************
-Checks that a data tuple is typed. */
+ const dtuple_t* tuple); /*!< in: tuple */
+/**********************************************************//**
+Checks that a data tuple is typed.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed_no_assert(
/*=========================*/
- /* out: TRUE if ok */
- const dtuple_t* tuple); /* in: tuple */
+ const dtuple_t* tuple); /*!< in: tuple */
#ifdef UNIV_DEBUG
-/**************************************************************
+/**********************************************************//**
Validates the consistency of a tuple which must be complete, i.e,
-all fields must have been set. */
+all fields must have been set.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_validate(
/*============*/
- /* out: TRUE if ok */
- const dtuple_t* tuple); /* in: tuple */
+ const dtuple_t* tuple); /*!< in: tuple */
#endif /* UNIV_DEBUG */
-/*****************************************************************
+/*************************************************************//**
Pretty prints a dfield value according to its data type. */
UNIV_INTERN
void
dfield_print(
/*=========*/
- const dfield_t* dfield);/* in: dfield */
-/*****************************************************************
+ const dfield_t* dfield);/*!< in: dfield */
+/*************************************************************//**
Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */
UNIV_INTERN
void
dfield_print_also_hex(
/*==================*/
- const dfield_t* dfield); /* in: dfield */
-/**************************************************************
+ const dfield_t* dfield); /*!< in: dfield */
+/**********************************************************//**
The following function prints the contents of a tuple. */
UNIV_INTERN
void
dtuple_print(
/*=========*/
- FILE* f, /* in: output stream */
- const dtuple_t* tuple); /* in: tuple */
-/******************************************************************
+ FILE* f, /*!< in: output stream */
+ const dtuple_t* tuple); /*!< in: tuple */
+/**************************************************************//**
Moves parts of long fields in entry to the big record vector so that
the size of tuple drops below the maximum record size allowed in the
database. Moves data only from those fields which are not necessary
-to determine uniquely the insertion place of the tuple in the index. */
+to determine uniquely the insertion place of the tuple in the index.
+@return own: created big record vector, NULL if we are not able to
+shorten the entry enough, i.e., if there are too many fixed-length or
+short fields in entry or the index is clustered */
UNIV_INTERN
big_rec_t*
dtuple_convert_big_rec(
/*===================*/
- /* out, own: created big record vector,
- NULL if we are not able to shorten
- the entry enough, i.e., if there are
- too many fixed-length or short fields
- in entry or the index is clustered */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in/out: index entry */
- ulint* n_ext); /* in/out: number of
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in/out: index entry */
+ ulint* n_ext); /*!< in/out: number of
externally stored columns */
-/******************************************************************
+/**************************************************************//**
Puts back to entry the data stored in vector. Note that to ensure the
fields in entry can accommodate the data, vector must have been created
from entry with dtuple_convert_big_rec. */
@@ -409,68 +409,71 @@ UNIV_INTERN
void
dtuple_convert_back_big_rec(
/*========================*/
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: entry whose data was put to vector */
- big_rec_t* vector);/* in, own: big rec vector; it is
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: entry whose data was put to vector */
+ big_rec_t* vector);/*!< in, own: big rec vector; it is
freed in this function */
-/******************************************************************
+/**************************************************************//**
Frees the memory in a big rec vector. */
UNIV_INLINE
void
dtuple_big_rec_free(
/*================*/
- big_rec_t* vector); /* in, own: big rec vector; it is
+ big_rec_t* vector); /*!< in, own: big rec vector; it is
freed in this function */
/*######################################################################*/
-/* Structure for an SQL data field */
+/** Structure for an SQL data field */
struct dfield_struct{
- void* data; /* pointer to data */
- unsigned ext:1; /* TRUE=externally stored, FALSE=local */
- unsigned len:32; /* data length; UNIV_SQL_NULL if SQL null */
- dtype_t type; /* type of data */
+ void* data; /*!< pointer to data */
+ unsigned ext:1; /*!< TRUE=externally stored, FALSE=local */
+ unsigned len:32; /*!< data length; UNIV_SQL_NULL if SQL null */
+ dtype_t type; /*!< type of data */
};
+/** Structure for an SQL data tuple of fields (logical record) */
struct dtuple_struct {
- ulint info_bits; /* info bits of an index record:
+ ulint info_bits; /*!< info bits of an index record:
the default is 0; this field is used
if an index record is built from
a data tuple */
- ulint n_fields; /* number of fields in dtuple */
- ulint n_fields_cmp; /* number of fields which should
+ ulint n_fields; /*!< number of fields in dtuple */
+ ulint n_fields_cmp; /*!< number of fields which should
be used in comparison services
of rem0cmp.*; the index search
is performed by comparing only these
fields, others are ignored; the
default value in dtuple creation is
the same value as n_fields */
- dfield_t* fields; /* fields */
+ dfield_t* fields; /*!< fields */
UT_LIST_NODE_T(dtuple_t) tuple_list;
- /* data tuples can be linked into a
+ /*!< data tuples can be linked into a
list using this field */
#ifdef UNIV_DEBUG
- ulint magic_n;
+ ulint magic_n; /*!< magic number, used in
+ debug assertions */
+/** Value of dtuple_struct::magic_n */
# define DATA_TUPLE_MAGIC_N 65478679
#endif /* UNIV_DEBUG */
};
-/* A slot for a field in a big rec vector */
-
+/** A slot for a field in a big rec vector */
typedef struct big_rec_field_struct big_rec_field_t;
+/** A slot for a field in a big rec vector */
struct big_rec_field_struct {
- ulint field_no; /* field number in record */
- ulint len; /* stored data len */
- const void* data; /* stored data */
+ ulint field_no; /*!< field number in record */
+ ulint len; /*!< stored data length, in bytes */
+ const void* data; /*!< stored data */
};
-/* Storage format for overflow data in a big record, that is, a record
-which needs external storage of data fields */
-
+/** Storage format for overflow data in a big record, that is, a
+clustered index record which needs external storage of data fields */
struct big_rec_struct {
- mem_heap_t* heap; /* memory heap from which allocated */
- ulint n_fields; /* number of stored fields */
- big_rec_field_t* fields; /* stored fields */
+ mem_heap_t* heap; /*!< memory heap from which
+ allocated */
+ ulint n_fields; /*!< number of stored fields */
+ big_rec_field_t*fields; /*!< stored fields */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/data0data.ic b/storage/xtradb/include/data0data.ic
index f11dbd9fce6..da79aa33702 100644
--- a/storage/xtradb/include/data0data.ic
+++ b/storage/xtradb/include/data0data.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/data0data.ic
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@@ -26,16 +27,19 @@ Created 5/30/1994 Heikki Tuuri
#include "ut0rnd.h"
#ifdef UNIV_DEBUG
+/** Dummy variable to catch access to uninitialized fields. In the
+debug version, dtuple_create() will make all fields of dtuple_t point
+to data_error. */
extern byte data_error;
-/*************************************************************************
-Gets pointer to the type struct of SQL data field. */
+/*********************************************************************//**
+Gets pointer to the type struct of SQL data field.
+@return pointer to the type struct */
UNIV_INLINE
dtype_t*
dfield_get_type(
/*============*/
- /* out: pointer to the type struct */
- const dfield_t* field) /* in: SQL data field */
+ const dfield_t* field) /*!< in: SQL data field */
{
ut_ad(field);
@@ -43,14 +47,14 @@ dfield_get_type(
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
+/*********************************************************************//**
Sets the type struct of SQL data field. */
UNIV_INLINE
void
dfield_set_type(
/*============*/
- dfield_t* field, /* in: SQL data field */
- dtype_t* type) /* in: pointer to data type struct */
+ dfield_t* field, /*!< in: SQL data field */
+ dtype_t* type) /*!< in: pointer to data type struct */
{
ut_ad(field && type);
@@ -58,14 +62,14 @@ dfield_set_type(
}
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets pointer to the data in a field. */
+/*********************************************************************//**
+Gets pointer to the data in a field.
+@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
/*============*/
- /* out: pointer to data */
- const dfield_t* field) /* in: field */
+ const dfield_t* field) /*!< in: field */
{
ut_ad(field);
ut_ad((field->len == UNIV_SQL_NULL)
@@ -75,15 +79,14 @@ dfield_get_data(
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Gets length of field data. */
+/*********************************************************************//**
+Gets length of field data.
+@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
/*===========*/
- /* out: length of data; UNIV_SQL_NULL if
- SQL null data */
- const dfield_t* field) /* in: field */
+ const dfield_t* field) /*!< in: field */
{
ut_ad(field);
ut_ad((field->len == UNIV_SQL_NULL)
@@ -92,14 +95,14 @@ dfield_get_len(
return(field->len);
}
-/*************************************************************************
+/*********************************************************************//**
Sets length in a field. */
UNIV_INLINE
void
dfield_set_len(
/*===========*/
- dfield_t* field, /* in: field */
- ulint len) /* in: length or UNIV_SQL_NULL */
+ dfield_t* field, /*!< in: field */
+ ulint len) /*!< in: length or UNIV_SQL_NULL */
{
ut_ad(field);
#ifdef UNIV_VALGRIND_DEBUG
@@ -110,56 +113,56 @@ dfield_set_len(
field->len = len;
}
-/*************************************************************************
-Determines if a field is SQL NULL */
+/*********************************************************************//**
+Determines if a field is SQL NULL
+@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
/*===========*/
- /* out: nonzero if SQL null data */
- const dfield_t* field) /* in: field */
+ const dfield_t* field) /*!< in: field */
{
ut_ad(field);
return(field->len == UNIV_SQL_NULL);
}
-/*************************************************************************
-Determines if a field is externally stored */
+/*********************************************************************//**
+Determines if a field is externally stored
+@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
/*==========*/
- /* out: nonzero if externally stored */
- const dfield_t* field) /* in: field */
+ const dfield_t* field) /*!< in: field */
{
ut_ad(field);
return(UNIV_UNLIKELY(field->ext));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the "external storage" flag */
UNIV_INLINE
void
dfield_set_ext(
/*===========*/
- dfield_t* field) /* in/out: field */
+ dfield_t* field) /*!< in/out: field */
{
ut_ad(field);
field->ext = 1;
}
-/*************************************************************************
+/*********************************************************************//**
Sets pointer to the data and length in a field. */
UNIV_INLINE
void
dfield_set_data(
/*============*/
- dfield_t* field, /* in: field */
- const void* data, /* in: data */
- ulint len) /* in: length or UNIV_SQL_NULL */
+ dfield_t* field, /*!< in: field */
+ const void* data, /*!< in: data */
+ ulint len) /*!< in: length or UNIV_SQL_NULL */
{
ut_ad(field);
@@ -171,25 +174,25 @@ dfield_set_data(
field->len = len;
}
-/*************************************************************************
+/*********************************************************************//**
Sets a data field to SQL NULL. */
UNIV_INLINE
void
dfield_set_null(
/*============*/
- dfield_t* field) /* in/out: field */
+ dfield_t* field) /*!< in/out: field */
{
dfield_set_data(field, NULL, UNIV_SQL_NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Copies the data and len fields. */
UNIV_INLINE
void
dfield_copy_data(
/*=============*/
- dfield_t* field1, /* out: field to copy to */
- const dfield_t* field2) /* in: field to copy from */
+ dfield_t* field1, /*!< out: field to copy to */
+ const dfield_t* field2) /*!< in: field to copy from */
{
ut_ad(field1 && field2);
@@ -198,26 +201,26 @@ dfield_copy_data(
field1->ext = field2->ext;
}
-/*************************************************************************
+/*********************************************************************//**
Copies a data field to another. */
UNIV_INLINE
void
dfield_copy(
/*========*/
- dfield_t* field1, /* out: field to copy to */
- const dfield_t* field2) /* in: field to copy from */
+ dfield_t* field1, /*!< out: field to copy to */
+ const dfield_t* field2) /*!< in: field to copy from */
{
*field1 = *field2;
}
-/*************************************************************************
+/*********************************************************************//**
Copies the data pointed to by a data field. */
UNIV_INLINE
void
dfield_dup(
/*=======*/
- dfield_t* field, /* in/out: data field */
- mem_heap_t* heap) /* in: memory heap where allocated */
+ dfield_t* field, /*!< in/out: data field */
+ mem_heap_t* heap) /*!< in: memory heap where allocated */
{
if (!dfield_is_null(field)) {
UNIV_MEM_ASSERT_RW(field->data, field->len);
@@ -225,15 +228,15 @@ dfield_dup(
}
}
-/*************************************************************************
-Tests if data length and content is equal for two dfields. */
+/*********************************************************************//**
+Tests if data length and content is equal for two dfields.
+@return TRUE if equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
/*==========================*/
- /* out: TRUE if equal */
- const dfield_t* field1, /* in: field */
- const dfield_t* field2) /* in: field */
+ const dfield_t* field1, /*!< in: field */
+ const dfield_t* field2) /*!< in: field */
{
ulint len;
@@ -244,57 +247,56 @@ dfield_datas_are_binary_equal(
|| !memcmp(field1->data, field2->data, len)));
}
-/*************************************************************************
-Gets info bits in a data tuple. */
+/*********************************************************************//**
+Gets info bits in a data tuple.
+@return info bits */
UNIV_INLINE
ulint
dtuple_get_info_bits(
/*=================*/
- /* out: info bits */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
return(tuple->info_bits);
}
-/*************************************************************************
+/*********************************************************************//**
Sets info bits in a data tuple. */
UNIV_INLINE
void
dtuple_set_info_bits(
/*=================*/
- dtuple_t* tuple, /* in: tuple */
- ulint info_bits) /* in: info bits */
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint info_bits) /*!< in: info bits */
{
ut_ad(tuple);
tuple->info_bits = info_bits;
}
-/*************************************************************************
-Gets number of fields used in record comparisons. */
+/*********************************************************************//**
+Gets number of fields used in record comparisons.
+@return number of fields used in comparisons in rem0cmp.* */
UNIV_INLINE
ulint
dtuple_get_n_fields_cmp(
/*====================*/
- /* out: number of fields used in comparisons
- in rem0cmp.* */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
return(tuple->n_fields_cmp);
}
-/*************************************************************************
+/*********************************************************************//**
Sets number of fields used in record comparisons. */
UNIV_INLINE
void
dtuple_set_n_fields_cmp(
/*====================*/
- dtuple_t* tuple, /* in: tuple */
- ulint n_fields_cmp) /* in: number of fields used in
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint n_fields_cmp) /*!< in: number of fields used in
comparisons in rem0cmp.* */
{
ut_ad(tuple);
@@ -303,14 +305,14 @@ dtuple_set_n_fields_cmp(
tuple->n_fields_cmp = n_fields_cmp;
}
-/*************************************************************************
-Gets number of fields in a data tuple. */
+/*********************************************************************//**
+Gets number of fields in a data tuple.
+@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
- /* out: number of fields */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
@@ -318,15 +320,15 @@ dtuple_get_n_fields(
}
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets nth field of a tuple. */
+/*********************************************************************//**
+Gets nth field of a tuple.
+@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
/*=================*/
- /* out: nth field */
- const dtuple_t* tuple, /* in: tuple */
- ulint n) /* in: index of field */
+ const dtuple_t* tuple, /*!< in: tuple */
+ ulint n) /*!< in: index of field */
{
ut_ad(tuple);
ut_ad(n < tuple->n_fields);
@@ -335,17 +337,17 @@ dtuple_get_nth_field(
}
#endif /* UNIV_DEBUG */
-/**************************************************************
+/**********************************************************//**
Creates a data tuple to a memory heap. The default value for number
-of fields used in record comparisons for this tuple is n_fields. */
+of fields used in record comparisons for this tuple is n_fields.
+@return own: created tuple */
UNIV_INLINE
dtuple_t*
dtuple_create(
/*==========*/
- /* out, own: created tuple */
- mem_heap_t* heap, /* in: memory heap where the tuple
+ mem_heap_t* heap, /*!< in: memory heap where the tuple
is created */
- ulint n_fields) /* in: number of fields */
+ ulint n_fields) /*!< in: number of fields */
{
dtuple_t* tuple;
@@ -380,17 +382,17 @@ dtuple_create(
return(tuple);
}
-/**************************************************************
+/**********************************************************//**
Wrap data fields in a tuple. The default value for number
-of fields used in record comparisons for this tuple is n_fields. */
+of fields used in record comparisons for this tuple is n_fields.
+@return data tuple */
UNIV_INLINE
const dtuple_t*
dtuple_from_fields(
/*===============*/
- /* out: data tuple */
- dtuple_t* tuple, /* in: storage for data tuple */
- const dfield_t* fields, /* in: fields */
- ulint n_fields) /* in: number of fields */
+ dtuple_t* tuple, /*!< in: storage for data tuple */
+ const dfield_t* fields, /*!< in: fields */
+ ulint n_fields) /*!< in: number of fields */
{
tuple->info_bits = 0;
tuple->n_fields = tuple->n_fields_cmp = n_fields;
@@ -400,16 +402,16 @@ dtuple_from_fields(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Copies a data tuple to another. This is a shallow copy; if a deep copy
-is desired, dfield_dup() will have to be invoked on each field. */
+is desired, dfield_dup() will have to be invoked on each field.
+@return own: copy of tuple */
UNIV_INLINE
dtuple_t*
dtuple_copy(
/*========*/
- /* out, own: copy of tuple */
- const dtuple_t* tuple, /* in: tuple to copy from */
- mem_heap_t* heap) /* in: memory heap
+ const dtuple_t* tuple, /*!< in: tuple to copy from */
+ mem_heap_t* heap) /*!< in: memory heap
where the tuple is created */
{
ulint n_fields = dtuple_get_n_fields(tuple);
@@ -424,16 +426,17 @@ dtuple_copy(
return(new_tuple);
}
-/**************************************************************
+/**********************************************************//**
The following function returns the sum of data lengths of a tuple. The space
occupied by the field structs or the tuple struct is not counted. Neither
-is possible space in externally stored parts of the field. */
+is possible space in externally stored parts of the field.
+@return sum of data lengths */
UNIV_INLINE
ulint
dtuple_get_data_size(
/*=================*/
- /* out: sum of data lengths */
- const dtuple_t* tuple) /* in: typed data tuple */
+ const dtuple_t* tuple, /*!< in: typed data tuple */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
const dfield_t* field;
ulint n_fields;
@@ -452,7 +455,8 @@ dtuple_get_data_size(
len = dfield_get_len(field);
if (len == UNIV_SQL_NULL) {
- len = dtype_get_sql_null_size(dfield_get_type(field));
+ len = dtype_get_sql_null_size(dfield_get_type(field),
+ comp);
}
sum += len;
@@ -461,14 +465,14 @@ dtuple_get_data_size(
return(sum);
}
-/*************************************************************************
-Computes the number of externally stored fields in a data tuple. */
+/*********************************************************************//**
+Computes the number of externally stored fields in a data tuple.
+@return number of externally stored fields */
UNIV_INLINE
ulint
dtuple_get_n_ext(
/*=============*/
- /* out: number of externally stored fields */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ulint n_ext = 0;
ulint n_fields = tuple->n_fields;
@@ -485,14 +489,14 @@ dtuple_get_n_ext(
return(n_ext);
}
-/***********************************************************************
+/*******************************************************************//**
Sets types of fields binary in a tuple. */
UNIV_INLINE
void
dtuple_set_types_binary(
/*====================*/
- dtuple_t* tuple, /* in: data tuple */
- ulint n) /* in: number of fields to set */
+ dtuple_t* tuple, /*!< in: data tuple */
+ ulint n) /*!< in: number of fields to set */
{
dtype_t* dfield_type;
ulint i;
@@ -503,18 +507,18 @@ dtuple_set_types_binary(
}
}
-/****************************************************************
-Folds a prefix given as the number of fields of a tuple. */
+/************************************************************//**
+Folds a prefix given as the number of fields of a tuple.
+@return the folded value */
UNIV_INLINE
ulint
dtuple_fold(
/*========*/
- /* out: the folded value */
- const dtuple_t* tuple, /* in: the tuple */
- ulint n_fields,/* in: number of complete fields to fold */
- ulint n_bytes,/* in: number of bytes to fold in an
+ const dtuple_t* tuple, /*!< in: the tuple */
+ ulint n_fields,/*!< in: number of complete fields to fold */
+ ulint n_bytes,/*!< in: number of bytes to fold in an
incomplete last field */
- dulint tree_id)/* in: index tree id */
+ dulint tree_id)/*!< in: index tree id */
{
const dfield_t* field;
ulint i;
@@ -559,26 +563,26 @@ dtuple_fold(
return(fold);
}
-/**************************************************************************
+/**********************************************************************//**
Writes an SQL null field full of zeros. */
UNIV_INLINE
void
data_write_sql_null(
/*================*/
- byte* data, /* in: pointer to a buffer of size len */
- ulint len) /* in: SQL null size in bytes */
+ byte* data, /*!< in: pointer to a buffer of size len */
+ ulint len) /*!< in: SQL null size in bytes */
{
memset(data, 0, len);
}
-/**************************************************************************
-Checks if a dtuple contains an SQL null value. */
+/**********************************************************************//**
+Checks if a dtuple contains an SQL null value.
+@return TRUE if some field is SQL null */
UNIV_INLINE
ibool
dtuple_contains_null(
/*=================*/
- /* out: TRUE if some field is SQL null */
- const dtuple_t* tuple) /* in: dtuple */
+ const dtuple_t* tuple) /*!< in: dtuple */
{
ulint n;
ulint i;
@@ -595,13 +599,13 @@ dtuple_contains_null(
return(FALSE);
}
-/******************************************************************
+/**************************************************************//**
Frees the memory in a big rec vector. */
UNIV_INLINE
void
dtuple_big_rec_free(
/*================*/
- big_rec_t* vector) /* in, own: big rec vector; it is
+ big_rec_t* vector) /*!< in, own: big rec vector; it is
freed in this function */
{
mem_heap_free(vector->heap);
diff --git a/storage/xtradb/include/data0type.h b/storage/xtradb/include/data0type.h
index 1f10878984b..a73bed3a9f5 100644
--- a/storage/xtradb/include/data0type.h
+++ b/storage/xtradb/include/data0type.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/data0type.h
Data types
Created 1/16/1996 Heikki Tuuri
@@ -167,228 +168,240 @@ SQL null*/
store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
-/*************************************************************************
-Gets the MySQL type code from a dtype. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Gets the MySQL type code from a dtype.
+@return MySQL type code; this is NOT an InnoDB type code! */
UNIV_INLINE
ulint
dtype_get_mysql_type(
/*=================*/
- /* out: MySQL type code; this is NOT an InnoDB
- type code! */
- const dtype_t* type); /* in: type struct */
-/*************************************************************************
+ const dtype_t* type); /*!< in: type struct */
+/*********************************************************************//**
Determine how many bytes the first n characters of the given string occupy.
If the string is shorter than n characters, returns the number of bytes
-the characters in the string occupy. */
+the characters in the string occupy.
+@return length of the prefix, in bytes */
UNIV_INTERN
ulint
dtype_get_at_most_n_mbchars(
/*========================*/
- /* out: length of the prefix,
- in bytes */
- ulint prtype, /* in: precise type */
- ulint mbminlen, /* in: minimum length of a
+ ulint prtype, /*!< in: precise type */
+ ulint mbminlen, /*!< in: minimum length of a
multi-byte character */
- ulint mbmaxlen, /* in: maximum length of a
+ ulint mbmaxlen, /*!< in: maximum length of a
multi-byte character */
- ulint prefix_len, /* in: length of the requested
+ ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
- ulint data_len, /* in: length of str (in bytes) */
- const char* str); /* in: the string whose prefix
+ ulint data_len, /*!< in: length of str (in bytes) */
+ const char* str); /*!< in: the string whose prefix
length is being determined */
-/*************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
Checks if a data main type is a string type. Also a BLOB is considered a
-string type. */
+string type.
+@return TRUE if string type */
UNIV_INTERN
ibool
dtype_is_string_type(
/*=================*/
- /* out: TRUE if string type */
- ulint mtype); /* in: InnoDB main data type code: DATA_CHAR, ... */
-/*************************************************************************
+ ulint mtype); /*!< in: InnoDB main data type code: DATA_CHAR, ... */
+/*********************************************************************//**
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
-those DATA_BLOB columns this function currently returns FALSE. */
+those DATA_BLOB columns this function currently returns FALSE.
+@return TRUE if binary string type */
UNIV_INTERN
ibool
dtype_is_binary_string_type(
/*========================*/
- /* out: TRUE if binary string type */
- ulint mtype, /* in: main data type */
- ulint prtype);/* in: precise type */
-/*************************************************************************
+ ulint mtype, /*!< in: main data type */
+ ulint prtype);/*!< in: precise type */
+/*********************************************************************//**
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
-For those DATA_BLOB columns this function currently returns TRUE. */
+For those DATA_BLOB columns this function currently returns TRUE.
+@return TRUE if non-binary string type */
UNIV_INTERN
ibool
dtype_is_non_binary_string_type(
/*============================*/
- /* out: TRUE if non-binary string type */
- ulint mtype, /* in: main data type */
- ulint prtype);/* in: precise type */
-/*************************************************************************
+ ulint mtype, /*!< in: main data type */
+ ulint prtype);/*!< in: precise type */
+/*********************************************************************//**
Sets a data type structure. */
UNIV_INLINE
void
dtype_set(
/*======*/
- dtype_t* type, /* in: type struct to init */
- ulint mtype, /* in: main data type */
- ulint prtype, /* in: precise type */
- ulint len); /* in: precision of type */
-/*************************************************************************
+ dtype_t* type, /*!< in: type struct to init */
+ ulint mtype, /*!< in: main data type */
+ ulint prtype, /*!< in: precise type */
+ ulint len); /*!< in: precision of type */
+/*********************************************************************//**
Copies a data type structure. */
UNIV_INLINE
void
dtype_copy(
/*=======*/
- dtype_t* type1, /* in: type struct to copy to */
- const dtype_t* type2); /* in: type struct to copy from */
-/*************************************************************************
-Gets the SQL main data type. */
+ dtype_t* type1, /*!< in: type struct to copy to */
+ const dtype_t* type2); /*!< in: type struct to copy from */
+/*********************************************************************//**
+Gets the SQL main data type.
+@return SQL main data type */
UNIV_INLINE
ulint
dtype_get_mtype(
/*============*/
- const dtype_t* type);
-/*************************************************************************
-Gets the precise data type. */
+ const dtype_t* type); /*!< in: data type */
+/*********************************************************************//**
+Gets the precise data type.
+@return precise data type */
UNIV_INLINE
ulint
dtype_get_prtype(
/*=============*/
- const dtype_t* type);
-/*************************************************************************
+ const dtype_t* type); /*!< in: data type */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_get_mblen(
/*============*/
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type (and collation) */
- ulint* mbminlen, /* out: minimum length of a
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type (and collation) */
+ ulint* mbminlen, /*!< out: minimum length of a
multi-byte character */
- ulint* mbmaxlen); /* out: maximum length of a
+ ulint* mbmaxlen); /*!< out: maximum length of a
multi-byte character */
-/*************************************************************************
-Gets the MySQL charset-collation code for MySQL string types. */
+/*********************************************************************//**
+Gets the MySQL charset-collation code for MySQL string types.
+@return MySQL charset-collation code */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
- ulint prtype);/* in: precise data type */
-/*************************************************************************
+ ulint prtype);/*!< in: precise data type */
+/*********************************************************************//**
Forms a precise type from the < 4.1.2 format precise type plus the
-charset-collation code. */
+charset-collation code.
+@return precise type, including the charset-collation code */
UNIV_INTERN
ulint
dtype_form_prtype(
/*==============*/
- ulint old_prtype, /* in: the MySQL type code and the flags
+ ulint old_prtype, /*!< in: the MySQL type code and the flags
DATA_BINARY_TYPE etc. */
- ulint charset_coll); /* in: MySQL charset-collation code */
-/*************************************************************************
+ ulint charset_coll); /*!< in: MySQL charset-collation code */
+/*********************************************************************//**
Determines if a MySQL string type is a subset of UTF-8. This function
may return false negatives, in case further character-set collation
-codes are introduced in MySQL later. */
+codes are introduced in MySQL later.
+@return TRUE if a subset of UTF-8 */
UNIV_INLINE
ibool
dtype_is_utf8(
/*==========*/
- /* out: TRUE if a subset of UTF-8 */
- ulint prtype);/* in: precise data type */
-/*************************************************************************
-Gets the type length. */
+ ulint prtype);/*!< in: precise data type */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Gets the type length.
+@return fixed length of the type, in bytes, or 0 if variable-length */
UNIV_INLINE
ulint
dtype_get_len(
/*==========*/
- const dtype_t* type);
-/*************************************************************************
-Gets the minimum length of a character, in bytes. */
+ const dtype_t* type); /*!< in: data type */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Gets the minimum length of a character, in bytes.
+@return minimum length of a char, in bytes, or 0 if this is not a
+character type */
UNIV_INLINE
ulint
dtype_get_mbminlen(
/*===============*/
- /* out: minimum length of a char, in bytes,
- or 0 if this is not a character type */
- const dtype_t* type); /* in: type */
-/*************************************************************************
-Gets the maximum length of a character, in bytes. */
+ const dtype_t* type); /*!< in: type */
+/*********************************************************************//**
+Gets the maximum length of a character, in bytes.
+@return maximum length of a char, in bytes, or 0 if this is not a
+character type */
UNIV_INLINE
ulint
dtype_get_mbmaxlen(
/*===============*/
- /* out: maximum length of a char, in bytes,
- or 0 if this is not a character type */
- const dtype_t* type); /* in: type */
-/*************************************************************************
-Gets the padding character code for the type. */
+ const dtype_t* type); /*!< in: type */
+/*********************************************************************//**
+Gets the padding character code for the type.
+@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
ulint
dtype_get_pad_char(
/*===============*/
- /* out: padding character code, or
- ULINT_UNDEFINED if no padding specified */
- ulint mtype, /* in: main type */
- ulint prtype); /* in: precise type */
-/***************************************************************************
-Returns the size of a fixed size data type, 0 if not a fixed size type. */
+ ulint mtype, /*!< in: main type */
+ ulint prtype); /*!< in: precise type */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************************//**
+Returns the size of a fixed size data type, 0 if not a fixed size type.
+@return fixed size, or 0 */
UNIV_INLINE
ulint
dtype_get_fixed_size_low(
/*=====================*/
- /* out: fixed size, or 0 */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint mbminlen, /* in: minimum length of a multibyte char */
- ulint mbmaxlen); /* in: maximum length of a multibyte char */
-/***************************************************************************
-Returns the minimum size of a data type. */
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint len, /*!< in: length */
+ ulint mbminlen, /*!< in: minimum length of a multibyte char */
+ ulint mbmaxlen, /*!< in: maximum length of a multibyte char */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Returns the minimum size of a data type.
+@return minimum size */
UNIV_INLINE
ulint
dtype_get_min_size_low(
/*===================*/
- /* out: minimum size */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint mbminlen, /* in: minimum length of a multibyte char */
- ulint mbmaxlen); /* in: maximum length of a multibyte char */
-/***************************************************************************
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint len, /*!< in: length */
+ ulint mbminlen, /*!< in: minimum length of a multibyte char */
+ ulint mbmaxlen); /*!< in: maximum length of a multibyte char */
+/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
-incomplete and return incorrect information. */
+incomplete and return incorrect information.
+@return maximum size */
UNIV_INLINE
ulint
dtype_get_max_size_low(
/*===================*/
- /* out: maximum size */
- ulint mtype, /* in: main type */
- ulint len); /* in: length */
-/***************************************************************************
+ ulint mtype, /*!< in: main type */
+ ulint len); /*!< in: length */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
-For fixed length types it is the fixed length of the type, otherwise 0. */
+For fixed length types it is the fixed length of the type, otherwise 0.
+@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dtype_get_sql_null_size(
/*====================*/
- /* out: SQL null storage size
- in ROW_FORMAT=REDUNDANT */
- const dtype_t* type); /* in: type */
-/**************************************************************************
+ const dtype_t* type, /*!< in: type */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. */
UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
- dtype_t* type, /* in: type struct */
- const byte* buf); /* in: buffer for the stored order info */
-/**************************************************************************
+ dtype_t* type, /*!< in: type struct */
+ const byte* buf); /*!< in: buffer for the stored order info */
+/**********************************************************************//**
Stores for a type the information which determines its alphabetical ordering
and the storage size of an SQL NULL value. This is the >= 4.1.x storage
format. */
@@ -396,13 +409,13 @@ UNIV_INLINE
void
dtype_new_store_for_order_and_null_size(
/*====================================*/
- byte* buf, /* in: buffer for
+ byte* buf, /*!< in: buffer for
DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
bytes where we store the info */
- const dtype_t* type, /* in: type struct */
- ulint prefix_len);/* in: prefix length to
+ const dtype_t* type, /*!< in: type struct */
+ ulint prefix_len);/*!< in: prefix length to
replace type->len, or 0 */
-/**************************************************************************
+/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the 4.1.x storage
format. */
@@ -410,24 +423,25 @@ UNIV_INLINE
void
dtype_new_read_for_order_and_null_size(
/*===================================*/
- dtype_t* type, /* in: type struct */
- const byte* buf); /* in: buffer for stored type order info */
+ dtype_t* type, /*!< in: type struct */
+ const byte* buf); /*!< in: buffer for stored type order info */
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Validates a data type structure. */
+/*********************************************************************//**
+Validates a data type structure.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtype_validate(
/*===========*/
- /* out: TRUE if ok */
- const dtype_t* type); /* in: type struct to validate */
-/*************************************************************************
+ const dtype_t* type); /*!< in: type struct to validate */
+/*********************************************************************//**
Prints a data type structure. */
UNIV_INTERN
void
dtype_print(
/*========*/
- const dtype_t* type); /* in: type */
+ const dtype_t* type); /*!< in: type */
/* Structure for an SQL data type.
If you add fields to this structure, be sure to initialize them everywhere.
@@ -438,8 +452,8 @@ dtype_new_read_for_order_and_null_size()
sym_tab_add_null_lit() */
struct dtype_struct{
- unsigned mtype:8; /* main data type */
- unsigned prtype:24; /* precise type; MySQL data
+ unsigned mtype:8; /*!< main data type */
+ unsigned prtype:24; /*!< precise type; MySQL data
type, charset code, flags to
indicate nullability,
signedness, whether this is a
@@ -449,7 +463,7 @@ struct dtype_struct{
/* the remaining fields do not affect alphabetical ordering: */
- unsigned len:16; /* length; for MySQL data this
+ unsigned len:16; /*!< length; for MySQL data this
is field->pack_length(),
except that for a >= 5.0.3
type true VARCHAR this is the
@@ -457,11 +471,12 @@ struct dtype_struct{
string data (in addition to
the string, MySQL uses 1 or 2
bytes to store the string length) */
-
- unsigned mbminlen:2; /* minimum length of a
+#ifndef UNIV_HOTBACKUP
+ unsigned mbminlen:2; /*!< minimum length of a
character, in bytes */
- unsigned mbmaxlen:3; /* maximum length of a
+ unsigned mbmaxlen:3; /*!< maximum length of a
character, in bytes */
+#endif /* !UNIV_HOTBACKUP */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic
index d4c1080bebe..240b4288f39 100644
--- a/storage/xtradb/include/data0type.ic
+++ b/storage/xtradb/include/data0type.ic
@@ -16,36 +16,39 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/data0type.ic
Data types
Created 1/16/1996 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
-#include "ha_prototypes.h"
+#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h"
-/*************************************************************************
-Gets the MySQL charset-collation code for MySQL string types. */
+/*********************************************************************//**
+Gets the MySQL charset-collation code for MySQL string types.
+@return MySQL charset-collation code */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
- ulint prtype) /* in: precise data type */
+ ulint prtype) /*!< in: precise data type */
{
return((prtype >> 16) & 0xFFUL);
}
-/*************************************************************************
+/*********************************************************************//**
Determines if a MySQL string type is a subset of UTF-8. This function
may return false negatives, in case further character-set collation
-codes are introduced in MySQL later. */
+codes are introduced in MySQL later.
+@return TRUE if a subset of UTF-8 */
UNIV_INLINE
ibool
dtype_is_utf8(
/*==========*/
- /* out: TRUE if a subset of UTF-8 */
- ulint prtype) /* in: precise data type */
+ ulint prtype) /*!< in: precise data type */
{
/* These codes have been copied from strings/ctype-extra.c
and strings/ctype-utf8.c. */
@@ -61,55 +64,49 @@ dtype_is_utf8(
return(FALSE);
}
-/*************************************************************************
-Gets the MySQL type code from a dtype. */
+/*********************************************************************//**
+Gets the MySQL type code from a dtype.
+@return MySQL type code; this is NOT an InnoDB type code! */
UNIV_INLINE
ulint
dtype_get_mysql_type(
/*=================*/
- /* out: MySQL type code; this is NOT an InnoDB
- type code! */
- const dtype_t* type) /* in: type struct */
+ const dtype_t* type) /*!< in: type struct */
{
return(type->prtype & 0xFFUL);
}
-/*************************************************************************
+/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_get_mblen(
/*============*/
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type (and collation) */
- ulint* mbminlen, /* out: minimum length of a
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type (and collation) */
+ ulint* mbminlen, /*!< out: minimum length of a
multi-byte character */
- ulint* mbmaxlen) /* out: maximum length of a
+ ulint* mbmaxlen) /*!< out: maximum length of a
multi-byte character */
{
if (dtype_is_string_type(mtype)) {
-#ifndef UNIV_HOTBACKUP
innobase_get_cset_width(dtype_get_charset_coll(prtype),
mbminlen, mbmaxlen);
ut_ad(*mbminlen <= *mbmaxlen);
ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */
ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */
-#else /* !UNIV_HOTBACKUP */
- ut_a(mtype <= DATA_BINARY);
- *mbminlen = *mbmaxlen = 1;
-#endif /* !UNIV_HOTBACKUP */
} else {
*mbminlen = *mbmaxlen = 0;
}
}
-/*************************************************************************
+/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_set_mblen(
/*============*/
- dtype_t* type) /* in/out: type */
+ dtype_t* type) /*!< in/out: type */
{
ulint mbminlen;
ulint mbmaxlen;
@@ -120,17 +117,20 @@ dtype_set_mblen(
ut_ad(dtype_validate(type));
}
+#else /* !UNIV_HOTBACKUP */
+# define dtype_set_mblen(type) (void) 0
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Sets a data type structure. */
UNIV_INLINE
void
dtype_set(
/*======*/
- dtype_t* type, /* in: type struct to init */
- ulint mtype, /* in: main data type */
- ulint prtype, /* in: precise type */
- ulint len) /* in: precision of type */
+ dtype_t* type, /*!< in: type struct to init */
+ ulint mtype, /*!< in: main data type */
+ ulint prtype, /*!< in: precise type */
+ ulint len) /*!< in: precision of type */
{
ut_ad(type);
ut_ad(mtype <= DATA_MTYPE_MAX);
@@ -142,96 +142,99 @@ dtype_set(
dtype_set_mblen(type);
}
-/*************************************************************************
+/*********************************************************************//**
Copies a data type structure. */
UNIV_INLINE
void
dtype_copy(
/*=======*/
- dtype_t* type1, /* in: type struct to copy to */
- const dtype_t* type2) /* in: type struct to copy from */
+ dtype_t* type1, /*!< in: type struct to copy to */
+ const dtype_t* type2) /*!< in: type struct to copy from */
{
*type1 = *type2;
ut_ad(dtype_validate(type1));
}
-/*************************************************************************
-Gets the SQL main data type. */
+/*********************************************************************//**
+Gets the SQL main data type.
+@return SQL main data type */
UNIV_INLINE
ulint
dtype_get_mtype(
/*============*/
- const dtype_t* type)
+ const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->mtype);
}
-/*************************************************************************
-Gets the precise data type. */
+/*********************************************************************//**
+Gets the precise data type.
+@return precise data type */
UNIV_INLINE
ulint
dtype_get_prtype(
/*=============*/
- const dtype_t* type)
+ const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->prtype);
}
-/*************************************************************************
-Gets the type length. */
+/*********************************************************************//**
+Gets the type length.
+@return fixed length of the type, in bytes, or 0 if variable-length */
UNIV_INLINE
ulint
dtype_get_len(
/*==========*/
- const dtype_t* type)
+ const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->len);
}
-/*************************************************************************
-Gets the minimum length of a character, in bytes. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Gets the minimum length of a character, in bytes.
+@return minimum length of a char, in bytes, or 0 if this is not a
+character type */
UNIV_INLINE
ulint
dtype_get_mbminlen(
/*===============*/
- /* out: minimum length of a char, in bytes,
- or 0 if this is not a character type */
- const dtype_t* type) /* in: type */
+ const dtype_t* type) /*!< in: type */
{
ut_ad(type);
return(type->mbminlen);
}
-/*************************************************************************
-Gets the maximum length of a character, in bytes. */
+/*********************************************************************//**
+Gets the maximum length of a character, in bytes.
+@return maximum length of a char, in bytes, or 0 if this is not a
+character type */
UNIV_INLINE
ulint
dtype_get_mbmaxlen(
/*===============*/
- /* out: maximum length of a char, in bytes,
- or 0 if this is not a character type */
- const dtype_t* type) /* in: type */
+ const dtype_t* type) /*!< in: type */
{
ut_ad(type);
return(type->mbmaxlen);
}
-/*************************************************************************
-Gets the padding character code for a type. */
+/*********************************************************************//**
+Gets the padding character code for a type.
+@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
ulint
dtype_get_pad_char(
/*===============*/
- /* out: padding character code, or
- ULINT_UNDEFINED if no padding specified */
- ulint mtype, /* in: main type */
- ulint prtype) /* in: precise type */
+ ulint mtype, /*!< in: main type */
+ ulint prtype) /*!< in: precise type */
{
switch (mtype) {
case DATA_FIXBINARY:
@@ -262,7 +265,7 @@ dtype_get_pad_char(
}
}
-/**************************************************************************
+/**********************************************************************//**
Stores for a type the information which determines its alphabetical ordering
and the storage size of an SQL NULL value. This is the >= 4.1.x storage
format. */
@@ -270,11 +273,11 @@ UNIV_INLINE
void
dtype_new_store_for_order_and_null_size(
/*====================================*/
- byte* buf, /* in: buffer for
+ byte* buf, /*!< in: buffer for
DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
bytes where we store the info */
- const dtype_t* type, /* in: type struct */
- ulint prefix_len)/* in: prefix length to
+ const dtype_t* type, /*!< in: type struct */
+ ulint prefix_len)/*!< in: prefix length to
replace type->len, or 0 */
{
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
@@ -307,7 +310,7 @@ dtype_new_store_for_order_and_null_size(
}
}
-/**************************************************************************
+/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the < 4.1.x
storage format. */
@@ -315,8 +318,8 @@ UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
- dtype_t* type, /* in: type struct */
- const byte* buf) /* in: buffer for stored type order info */
+ dtype_t* type, /*!< in: type struct */
+ const byte* buf) /*!< in: buffer for stored type order info */
{
#if 4 != DATA_ORDER_NULL_TYPE_BUF_SIZE
# error "4 != DATA_ORDER_NULL_TYPE_BUF_SIZE"
@@ -336,7 +339,7 @@ dtype_read_for_order_and_null_size(
dtype_set_mblen(type);
}
-/**************************************************************************
+/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the >= 4.1.x
storage format. */
@@ -344,8 +347,8 @@ UNIV_INLINE
void
dtype_new_read_for_order_and_null_size(
/*===================================*/
- dtype_t* type, /* in: type struct */
- const byte* buf) /* in: buffer for stored type order info */
+ dtype_t* type, /*!< in: type struct */
+ const byte* buf) /*!< in: buffer for stored type order info */
{
ulint charset_coll;
@@ -385,19 +388,21 @@ dtype_new_read_for_order_and_null_size(
}
dtype_set_mblen(type);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
-Returns the size of a fixed size data type, 0 if not a fixed size type. */
+/***********************************************************************//**
+Returns the size of a fixed size data type, 0 if not a fixed size type.
+@return fixed size, or 0 */
UNIV_INLINE
ulint
dtype_get_fixed_size_low(
/*=====================*/
- /* out: fixed size, or 0 */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint mbminlen, /* in: minimum length of a multibyte char */
- ulint mbmaxlen) /* in: maximum length of a multibyte char */
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint len, /*!< in: length */
+ ulint mbminlen, /*!< in: minimum length of a multibyte char */
+ ulint mbmaxlen, /*!< in: maximum length of a multibyte char */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
switch (mtype) {
case DATA_SYS:
@@ -424,14 +429,12 @@ dtype_get_fixed_size_low(
case DATA_DOUBLE:
return(len);
case DATA_MYSQL:
+#ifndef UNIV_HOTBACKUP
if (prtype & DATA_BINARY_TYPE) {
return(len);
+ } else if (!comp) {
+ return(len);
} else {
-#ifdef UNIV_HOTBACKUP
- if (mbminlen == mbmaxlen) {
- return(len);
- }
-#else /* UNIV_HOTBACKUP */
/* We play it safe here and ask MySQL for
mbminlen and mbmaxlen. Although
mbminlen and mbmaxlen are
@@ -463,8 +466,10 @@ dtype_get_fixed_size_low(
if (mbminlen == mbmaxlen) {
return(len);
}
-#endif /* !UNIV_HOTBACKUP */
}
+#else /* !UNIV_HOTBACKUP */
+ return(len);
+#endif /* !UNIV_HOTBACKUP */
/* fall through for variable-length charsets */
case DATA_VARCHAR:
case DATA_BINARY:
@@ -479,18 +484,19 @@ dtype_get_fixed_size_low(
return(0);
}
-/***************************************************************************
-Returns the minimum size of a data type. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Returns the minimum size of a data type.
+@return minimum size */
UNIV_INLINE
ulint
dtype_get_min_size_low(
/*===================*/
- /* out: minimum size */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint mbminlen, /* in: minimum length of a multibyte char */
- ulint mbmaxlen) /* in: maximum length of a multibyte char */
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint len, /*!< in: length */
+ ulint mbminlen, /*!< in: minimum length of a multibyte char */
+ ulint mbmaxlen) /*!< in: maximum length of a multibyte char */
{
switch (mtype) {
case DATA_SYS:
@@ -538,16 +544,16 @@ dtype_get_min_size_low(
return(0);
}
-/***************************************************************************
+/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
-incomplete and return incorrect information. */
+incomplete and return incorrect information.
+@return maximum size */
UNIV_INLINE
ulint
dtype_get_max_size_low(
/*===================*/
- /* out: maximum size */
- ulint mtype, /* in: main type */
- ulint len) /* in: length */
+ ulint mtype, /*!< in: main type */
+ ulint len) /*!< in: length */
{
switch (mtype) {
case DATA_SYS:
@@ -570,18 +576,24 @@ dtype_get_max_size_low(
return(ULINT_MAX);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
+/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
-For fixed length types it is the fixed length of the type, otherwise 0. */
+For fixed length types it is the fixed length of the type, otherwise 0.
+@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dtype_get_sql_null_size(
/*====================*/
- /* out: SQL null storage size
- in ROW_FORMAT=REDUNDANT */
- const dtype_t* type) /* in: type */
+ const dtype_t* type, /*!< in: type */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
+#ifndef UNIV_HOTBACKUP
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- type->mbminlen, type->mbmaxlen));
+ type->mbminlen, type->mbmaxlen, comp));
+#else /* !UNIV_HOTBACKUP */
+ return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
+ 0, 0, 0));
+#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/xtradb/include/data0types.h b/storage/xtradb/include/data0types.h
index 9e536478d68..04e835bc401 100644
--- a/storage/xtradb/include/data0types.h
+++ b/storage/xtradb/include/data0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/data0types.h
Some type definitions
Created 9/21/2000 Heikki Tuuri
diff --git a/storage/xtradb/include/db0err.h b/storage/xtradb/include/db0err.h
index d6d2a9785a5..747e9b5364e 100644
--- a/storage/xtradb/include/db0err.h
+++ b/storage/xtradb/include/db0err.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/db0err.h
Global error codes for the database
Created 5/24/1996 Heikki Tuuri
@@ -31,6 +32,7 @@ enum db_err {
/* The following are error codes */
DB_ERROR,
+ DB_INTERRUPTED,
DB_OUT_OF_MEMORY,
DB_OUT_OF_FILE_SPACE,
DB_LOCK_WAIT,
diff --git a/storage/xtradb/include/dict0boot.h b/storage/xtradb/include/dict0boot.h
index e1556bdb16e..51d37ee98d1 100644
--- a/storage/xtradb/include/dict0boot.h
+++ b/storage/xtradb/include/dict0boot.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0boot.h
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
@@ -36,54 +37,53 @@ Created 4/18/1996 Heikki Tuuri
typedef byte dict_hdr_t;
-/**************************************************************************
-Gets a pointer to the dictionary header and x-latches its page. */
+/**********************************************************************//**
+Gets a pointer to the dictionary header and x-latches its page.
+@return pointer to the dictionary header, page x-latched */
UNIV_INTERN
dict_hdr_t*
dict_hdr_get(
/*=========*/
- /* out: pointer to the dictionary header,
- page x-latched */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
-Returns a new row, table, index, or tree id. */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
+Returns a new row, table, index, or tree id.
+@return the new id */
UNIV_INTERN
dulint
dict_hdr_get_new_id(
/*================*/
- /* out: the new id */
- ulint type); /* in: DICT_HDR_ROW_ID, ... */
-/**************************************************************************
-Returns a new row id. */
+ ulint type); /*!< in: DICT_HDR_ROW_ID, ... */
+/**********************************************************************//**
+Returns a new row id.
+@return the new id */
UNIV_INLINE
dulint
dict_sys_get_new_row_id(void);
/*=========================*/
- /* out: the new id */
-/**************************************************************************
-Reads a row id from a record or other 6-byte stored form. */
+/**********************************************************************//**
+Reads a row id from a record or other 6-byte stored form.
+@return row id */
UNIV_INLINE
dulint
dict_sys_read_row_id(
/*=================*/
- /* out: row id */
- byte* field); /* in: record field */
-/**************************************************************************
+ byte* field); /*!< in: record field */
+/**********************************************************************//**
Writes a row id to a record or other 6-byte stored form. */
UNIV_INLINE
void
dict_sys_write_row_id(
/*==================*/
- byte* field, /* in: record field */
- dulint row_id);/* in: row id */
-/*********************************************************************
+ byte* field, /*!< in: record field */
+ dulint row_id);/*!< in: row id */
+/*****************************************************************//**
Initializes the data dictionary memory structures when the database is
started. This function is also called when the data dictionary is created. */
UNIV_INTERN
void
dict_boot(void);
/*===========*/
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the data dictionary at the database creation. */
UNIV_INTERN
void
diff --git a/storage/xtradb/include/dict0boot.ic b/storage/xtradb/include/dict0boot.ic
index 9b45f9e84be..d5f372e38c4 100644
--- a/storage/xtradb/include/dict0boot.ic
+++ b/storage/xtradb/include/dict0boot.ic
@@ -16,13 +16,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0boot.ic
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
*******************************************************/
-/**************************************************************************
+/**********************************************************************//**
Writes the current value of the row id counter to the dictionary header file
page. */
UNIV_INTERN
@@ -31,13 +32,13 @@ dict_hdr_flush_row_id(void);
/*=======================*/
-/**************************************************************************
-Returns a new row id. */
+/**********************************************************************//**
+Returns a new row id.
+@return the new id */
UNIV_INLINE
dulint
dict_sys_get_new_row_id(void)
/*=========================*/
- /* out: the new id */
{
dulint id;
@@ -57,14 +58,14 @@ dict_sys_get_new_row_id(void)
return(id);
}
-/**************************************************************************
-Reads a row id from a record or other 6-byte stored form. */
+/**********************************************************************//**
+Reads a row id from a record or other 6-byte stored form.
+@return row id */
UNIV_INLINE
dulint
dict_sys_read_row_id(
/*=================*/
- /* out: row id */
- byte* field) /* in: record field */
+ byte* field) /*!< in: record field */
{
#if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
@@ -73,14 +74,14 @@ dict_sys_read_row_id(
return(mach_read_from_6(field));
}
-/**************************************************************************
+/**********************************************************************//**
Writes a row id to a record or other 6-byte stored form. */
UNIV_INLINE
void
dict_sys_write_row_id(
/*==================*/
- byte* field, /* in: record field */
- dulint row_id) /* in: row id */
+ byte* field, /*!< in: record field */
+ dulint row_id) /*!< in: row id */
{
#if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
diff --git a/storage/xtradb/include/dict0crea.h b/storage/xtradb/include/dict0crea.h
index 9ac3e408f1f..cce1246b789 100644
--- a/storage/xtradb/include/dict0crea.h
+++ b/storage/xtradb/include/dict0crea.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0crea.h
Database object creation
Created 1/8/1996 Heikki Tuuri
@@ -32,94 +33,92 @@ Created 1/8/1996 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
-/*************************************************************************
-Creates a table create graph. */
+/*********************************************************************//**
+Creates a table create graph.
+@return own: table create node */
UNIV_INTERN
tab_node_t*
tab_create_graph_create(
/*====================*/
- /* out, own: table create node */
- dict_table_t* table, /* in: table to create, built as a memory data
+ dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
- mem_heap_t* heap); /* in: heap where created */
-/*************************************************************************
-Creates an index create graph. */
+ mem_heap_t* heap); /*!< in: heap where created */
+/*********************************************************************//**
+Creates an index create graph.
+@return own: index create node */
UNIV_INTERN
ind_node_t*
ind_create_graph_create(
/*====================*/
- /* out, own: index create node */
- dict_index_t* index, /* in: index to create, built as a memory data
+ dict_index_t* index, /*!< in: index to create, built as a memory data
structure */
- mem_heap_t* heap); /* in: heap where created */
-/***************************************************************
-Creates a table. This is a high-level function used in SQL execution graphs. */
+ mem_heap_t* heap); /*!< in: heap where created */
+/***********************************************************//**
+Creates a table. This is a high-level function used in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_table_step(
/*===================*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/***************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************//**
Creates an index. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_index_step(
/*===================*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/***********************************************************************
-Truncates the index tree associated with a row in SYS_INDEXES table. */
+ que_thr_t* thr); /*!< in: query thread */
+/*******************************************************************//**
+Truncates the index tree associated with a row in SYS_INDEXES table.
+@return new root page number, or FIL_NULL on failure */
UNIV_INTERN
ulint
dict_truncate_index_tree(
/*=====================*/
- /* out: new root page number, or
- FIL_NULL on failure */
- dict_table_t* table, /* in: the table the index belongs to */
- ulint space, /* in: 0=truncate,
+ dict_table_t* table, /*!< in: the table the index belongs to */
+ ulint space, /*!< in: 0=truncate,
nonzero=create the index tree in the
given tablespace */
- btr_pcur_t* pcur, /* in/out: persistent cursor pointing to
+ btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing to
record in the clustered index of
SYS_INDEXES table. The cursor may be
repositioned in this call. */
- mtr_t* mtr); /* in: mtr having the latch
+ mtr_t* mtr); /*!< in: mtr having the latch
on the record page. The mtr may be
committed and restarted in this call. */
-/***********************************************************************
+/*******************************************************************//**
Drops the index tree associated with a row in SYS_INDEXES table. */
UNIV_INTERN
void
dict_drop_index_tree(
/*=================*/
- rec_t* rec, /* in/out: record in the clustered index
+ rec_t* rec, /*!< in/out: record in the clustered index
of SYS_INDEXES table */
- mtr_t* mtr); /* in: mtr having the latch on the record page */
-#ifndef UNIV_HOTBACKUP
-/********************************************************************
+ mtr_t* mtr); /*!< in: mtr having the latch on the record page */
+/****************************************************************//**
Creates the foreign key constraints system tables inside InnoDB
at database creation or database start if they are not found or are
-not of the right form. */
+not of the right form.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_foreign_constraint_tables(void);
/*================================================*/
- /* out: DB_SUCCESS or error code */
-/************************************************************************
+/********************************************************************//**
Adds foreign key definitions to data dictionary tables in the database. We
look at table->foreign_list, and also generate names to constraints that were
not named by the user. A generated constraint has a name of the format
-databasename/tablename_ibfk_<number>, where the numbers start from 1, and are
+databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and are
given locally for this table, that is, the number is not global, as in the
-old format constraints < 4.0.18 it used to be. */
+old format constraints < 4.0.18 it used to be.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_add_foreigns_to_dictionary(
/*===================================*/
- /* out: error code or DB_SUCCESS */
- ulint start_id,/* in: if we are actually doing ALTER TABLE
+ ulint start_id,/*!< in: if we are actually doing ALTER TABLE
ADD CONSTRAINT, we want to generate constraint
numbers which are bigger than in the table so
far; we number the constraints from
@@ -127,15 +126,14 @@ dict_create_add_foreigns_to_dictionary(
we are creating a new table, or if the table
so far has no constraints for which the name
was generated here */
- dict_table_t* table, /* in: table */
- trx_t* trx); /* in: transaction */
-#endif /* !UNIV_HOTBACKUP */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx); /*!< in: transaction */
/* Table create node structure */
struct tab_node_struct{
- que_common_t common; /* node type: QUE_NODE_TABLE_CREATE */
- dict_table_t* table; /* table to create, built as a memory data
+ que_common_t common; /*!< node type: QUE_NODE_TABLE_CREATE */
+ dict_table_t* table; /*!< table to create, built as a memory data
structure with dict_mem_... functions */
ins_node_t* tab_def; /* child node which does the insert of
the table definition; the row to be inserted
@@ -148,9 +146,9 @@ struct tab_node_struct{
a successful table creation */
/*----------------------*/
/* Local storage for this graph node */
- ulint state; /* node execution state */
- ulint col_no; /* next column definition to insert */
- mem_heap_t* heap; /* memory heap used as auxiliary storage */
+ ulint state; /*!< node execution state */
+ ulint col_no; /*!< next column definition to insert */
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
/* Table create node states */
@@ -163,8 +161,8 @@ struct tab_node_struct{
/* Index create node struct */
struct ind_node_struct{
- que_common_t common; /* node type: QUE_NODE_INDEX_CREATE */
- dict_index_t* index; /* index to create, built as a memory data
+ que_common_t common; /*!< node type: QUE_NODE_INDEX_CREATE */
+ dict_index_t* index; /*!< index to create, built as a memory data
structure with dict_mem_... functions */
ins_node_t* ind_def; /* child node which does the insert of
the index definition; the row to be inserted
@@ -177,12 +175,12 @@ struct ind_node_struct{
a successful index creation */
/*----------------------*/
/* Local storage for this graph node */
- ulint state; /* node execution state */
+ ulint state; /*!< node execution state */
ulint page_no;/* root page number of the index */
- dict_table_t* table; /* table which owns the index */
+ dict_table_t* table; /*!< table which owns the index */
dtuple_t* ind_row;/* index definition row built */
ulint field_no;/* next field definition to insert */
- mem_heap_t* heap; /* memory heap used as auxiliary storage */
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
/* Index create node states */
diff --git a/storage/xtradb/include/dict0crea.ic b/storage/xtradb/include/dict0crea.ic
index b05385fa121..c5365ce7489 100644
--- a/storage/xtradb/include/dict0crea.ic
+++ b/storage/xtradb/include/dict0crea.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0crea.ic
Database object creation
Created 1/8/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index 7c7b37b7681..3d49b6a98a4 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0dict.h
Data dictionary system
Created 1/8/1996 Heikki Tuuri
@@ -30,8 +31,6 @@ Created 1/8/1996 Heikki Tuuri
#include "dict0mem.h"
#include "data0type.h"
#include "data0data.h"
-#include "sync0sync.h"
-#include "sync0rw.h"
#include "mem0mem.h"
#include "rem0types.h"
#include "ut0mem.h"
@@ -42,56 +41,57 @@ Created 1/8/1996 Heikki Tuuri
#include "trx0types.h"
#ifndef UNIV_HOTBACKUP
-/**********************************************************************
+# include "sync0sync.h"
+# include "sync0rw.h"
+/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
void
dict_casedn_str(
/*============*/
- char* a); /* in/out: string to put in lower case */
-#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Get the database name length in a table name. */
+ char* a); /*!< in/out: string to put in lower case */
+/********************************************************************//**
+Get the database name length in a table name.
+@return database name length */
UNIV_INTERN
ulint
dict_get_db_name_len(
/*=================*/
- /* out: database name length */
- const char* name); /* in: table name in the form
+ const char* name); /*!< in: table name in the form
dbname '/' tablename */
-/************************************************************************
-Return the end of table name where we have removed dbname and '/'. */
+/********************************************************************//**
+Return the end of table name where we have removed dbname and '/'.
+@return table name */
const char*
dict_remove_db_name(
/*================*/
- /* out: table name */
- const char* name); /* in: table name in the form
+ const char* name); /*!< in: table name in the form
dbname '/' tablename */
-/**************************************************************************
-Returns a table object based on table id. */
+/**********************************************************************//**
+Returns a table object based on table id.
+@return table, NULL if does not exist */
UNIV_INTERN
dict_table_t*
dict_table_get_on_id(
/*=================*/
- /* out: table, NULL if does not exist */
- dulint table_id, /* in: table id */
- trx_t* trx); /* in: transaction handle */
-/************************************************************************
+ dulint table_id, /*!< in: table id */
+ trx_t* trx); /*!< in: transaction handle */
+/********************************************************************//**
Decrements the count of open MySQL handles to a table. */
UNIV_INTERN
void
dict_table_decrement_handle_count(
/*==============================*/
- dict_table_t* table, /* in/out: table */
- ibool dict_locked); /* in: TRUE=data dictionary locked */
-/**************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ ibool dict_locked); /*!< in: TRUE=data dictionary locked */
+/**********************************************************************//**
Inits the data dictionary module. */
UNIV_INTERN
void
dict_init(void);
/*===========*/
-/************************************************************************
+/********************************************************************//**
Gets the space id of every table of the data dictionary and makes a linear
list and a hash table of them to the data dictionary cache. This function
can be called at database startup if we did not need to do a crash recovery.
@@ -101,109 +101,113 @@ UNIV_INTERN
void
dict_load_space_id_list(void);
/*=========================*/
-/*************************************************************************
+/*********************************************************************//**
Gets the column data type. */
UNIV_INLINE
void
dict_col_copy_type(
/*===============*/
- const dict_col_t* col, /* in: column */
- dtype_t* type); /* out: data type */
+ const dict_col_t* col, /*!< in: column */
+ dtype_t* type); /*!< out: data type */
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Assert that a column and a data type match. */
+/*********************************************************************//**
+Assert that a column and a data type match.
+@return TRUE */
UNIV_INLINE
ibool
dict_col_type_assert_equal(
/*=======================*/
- /* out: TRUE */
- const dict_col_t* col, /* in: column */
- const dtype_t* type); /* in: data type */
+ const dict_col_t* col, /*!< in: column */
+ const dtype_t* type); /*!< in: data type */
#endif /* UNIV_DEBUG */
-/***************************************************************************
-Returns the minimum size of the column. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Returns the minimum size of the column.
+@return minimum size */
UNIV_INLINE
ulint
dict_col_get_min_size(
/*==================*/
- /* out: minimum size */
- const dict_col_t* col); /* in: column */
-/***************************************************************************
-Returns the maximum size of the column. */
+ const dict_col_t* col); /*!< in: column */
+/***********************************************************************//**
+Returns the maximum size of the column.
+@return maximum size */
UNIV_INLINE
ulint
dict_col_get_max_size(
/*==================*/
- /* out: maximum size */
- const dict_col_t* col); /* in: column */
-/***************************************************************************
-Returns the size of a fixed size column, 0 if not a fixed size column. */
+ const dict_col_t* col); /*!< in: column */
+/***********************************************************************//**
+Returns the size of a fixed size column, 0 if not a fixed size column.
+@return fixed size, or 0 */
UNIV_INLINE
ulint
dict_col_get_fixed_size(
/*====================*/
- /* out: fixed size, or 0 */
- const dict_col_t* col); /* in: column */
-/***************************************************************************
+ const dict_col_t* col, /*!< in: column */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
+/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
-For fixed length types it is the fixed length of the type, otherwise 0. */
+For fixed length types it is the fixed length of the type, otherwise 0.
+@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dict_col_get_sql_null_size(
/*=======================*/
- /* out: SQL null storage size
- in ROW_FORMAT=REDUNDANT */
- const dict_col_t* col); /* in: column */
+ const dict_col_t* col, /*!< in: column */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
-/*************************************************************************
-Gets the column number. */
+/*********************************************************************//**
+Gets the column number.
+@return col->ind, table column position (starting from 0) */
UNIV_INLINE
ulint
dict_col_get_no(
/*============*/
- const dict_col_t* col);
-/*************************************************************************
+ const dict_col_t* col); /*!< in: column */
+/*********************************************************************//**
Gets the column position in the clustered index. */
UNIV_INLINE
ulint
dict_col_get_clust_pos(
/*===================*/
- const dict_col_t* col, /* in: table column */
- const dict_index_t* clust_index); /* in: clustered index */
-/********************************************************************
+ const dict_col_t* col, /*!< in: table column */
+ const dict_index_t* clust_index); /*!< in: clustered index */
+/****************************************************************//**
If the given column name is reserved for InnoDB system columns, return
-TRUE. */
+TRUE.
+@return TRUE if name is reserved */
UNIV_INTERN
ibool
dict_col_name_is_reserved(
/*======================*/
- /* out: TRUE if name is reserved */
- const char* name); /* in: column name */
-/************************************************************************
-Acquire the autoinc lock.*/
+ const char* name); /*!< in: column name */
+/********************************************************************//**
+Acquire the autoinc lock. */
UNIV_INTERN
void
dict_table_autoinc_lock(
/*====================*/
- dict_table_t* table); /* in/out: table */
-/************************************************************************
+ dict_table_t* table); /*!< in/out: table */
+/********************************************************************//**
Unconditionally set the autoinc counter. */
UNIV_INTERN
void
dict_table_autoinc_initialize(
/*==========================*/
- dict_table_t* table, /* in/out: table */
- ib_uint64_t value); /* in: next value to assign to a row */
-/************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ ib_uint64_t value); /*!< in: next value to assign to a row */
+/********************************************************************//**
Reads the next autoinc value (== autoinc counter value), 0 if not yet
-initialized. */
+initialized.
+@return value for a new row, or 0 */
UNIV_INTERN
ib_uint64_t
dict_table_autoinc_read(
/*====================*/
- /* out: value for a new row, or 0 */
- const dict_table_t* table); /* in: table */
-/************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
Updates the autoinc counter if the value supplied is greater than the
current value. */
UNIV_INTERN
@@ -211,135 +215,136 @@ void
dict_table_autoinc_update_if_greater(
/*=================================*/
- dict_table_t* table, /* in/out: table */
- ib_uint64_t value); /* in: value which was assigned to a row */
-/************************************************************************
-Release the autoinc lock.*/
+ dict_table_t* table, /*!< in/out: table */
+ ib_uint64_t value); /*!< in: value which was assigned to a row */
+/********************************************************************//**
+Release the autoinc lock. */
UNIV_INTERN
void
dict_table_autoinc_unlock(
/*======================*/
- dict_table_t* table); /* in/out: table */
-/**************************************************************************
+ dict_table_t* table); /*!< in/out: table */
+#endif /* !UNIV_HOTBACKUP */
+/**********************************************************************//**
Adds system columns to a table object. */
UNIV_INTERN
void
dict_table_add_system_columns(
/*==========================*/
- dict_table_t* table, /* in/out: table */
- mem_heap_t* heap); /* in: temporary heap */
-/**************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ mem_heap_t* heap); /*!< in: temporary heap */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Adds a table object to the dictionary cache. */
UNIV_INTERN
void
dict_table_add_to_cache(
/*====================*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap); /* in: temporary heap */
-/**************************************************************************
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap); /*!< in: temporary heap */
+/**********************************************************************//**
Removes a table object from the dictionary cache. */
UNIV_INTERN
void
dict_table_remove_from_cache(
/*=========================*/
- dict_table_t* table); /* in, own: table */
-/**************************************************************************
-Renames a table object. */
+ dict_table_t* table); /*!< in, own: table */
+/**********************************************************************//**
+Renames a table object.
+@return TRUE if success */
UNIV_INTERN
ibool
dict_table_rename_in_cache(
/*=======================*/
- /* out: TRUE if success */
- dict_table_t* table, /* in/out: table */
- const char* new_name, /* in: new name */
- ibool rename_also_foreigns);/* in: in ALTER TABLE we want
+ dict_table_t* table, /*!< in/out: table */
+ const char* new_name, /*!< in: new name */
+ ibool rename_also_foreigns);/*!< in: in ALTER TABLE we want
to preserve the original table name
in constraints which reference it */
-/**************************************************************************
+/**********************************************************************//**
Removes an index from the dictionary cache. */
UNIV_INTERN
void
dict_index_remove_from_cache(
/*=========================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index); /* in, own: index */
-/**************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index); /*!< in, own: index */
+/**********************************************************************//**
Change the id of a table object in the dictionary cache. This is used in
DISCARD TABLESPACE. */
UNIV_INTERN
void
dict_table_change_id_in_cache(
/*==========================*/
- dict_table_t* table, /* in/out: table object already in cache */
- dulint new_id);/* in: new id to set */
-/**************************************************************************
+ dict_table_t* table, /*!< in/out: table object already in cache */
+ dulint new_id);/*!< in: new id to set */
+/**********************************************************************//**
Adds a foreign key constraint object to the dictionary cache. May free
the object if there already is an object with the same identifier in.
At least one of foreign table or referenced table must already be in
-the dictionary cache! */
+the dictionary cache!
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_foreign_add_to_cache(
/*======================*/
- /* out: DB_SUCCESS or error code */
- dict_foreign_t* foreign, /* in, own: foreign key constraint */
- ibool check_charsets);/* in: TRUE=check charset
+ dict_foreign_t* foreign, /*!< in, own: foreign key constraint */
+ ibool check_charsets);/*!< in: TRUE=check charset
compatibility */
-/*************************************************************************
+/*********************************************************************//**
Check if the index is referenced by a foreign key, if TRUE return the
-matching instance NULL otherwise. */
+matching instance NULL otherwise.
+@return pointer to foreign key struct if index is defined for foreign
+key, otherwise NULL */
UNIV_INTERN
dict_foreign_t*
dict_table_get_referenced_constraint(
/*=================================*/
- /* out: pointer to foreign key struct if index
- is defined for foreign key, otherwise NULL */
- dict_table_t* table, /* in: InnoDB table */
- dict_index_t* index); /* in: InnoDB index */
-/*************************************************************************
-Checks if a table is referenced by foreign keys. */
+ dict_table_t* table, /*!< in: InnoDB table */
+ dict_index_t* index); /*!< in: InnoDB index */
+/*********************************************************************//**
+Checks if a table is referenced by foreign keys.
+@return TRUE if table is referenced by a foreign key */
UNIV_INTERN
ibool
dict_table_is_referenced_by_foreign_key(
/*====================================*/
- /* out: TRUE if table is referenced
- by a foreign key */
- const dict_table_t* table); /* in: InnoDB table */
-/**************************************************************************
+ const dict_table_t* table); /*!< in: InnoDB table */
+/**********************************************************************//**
Replace the index in the foreign key list that matches this index's
definition with an equivalent index. */
UNIV_INTERN
void
dict_table_replace_index_in_foreign_list(
/*=====================================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index); /* in: index to be replaced */
-/*************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index); /*!< in: index to be replaced */
+/*********************************************************************//**
Checks if a index is defined for a foreign key constraint. Index is a part
of a foreign key constraint if the index is referenced by foreign key
-or index is a foreign key index */
+or index is a foreign key index
+@return pointer to foreign key struct if index is defined for foreign
+key, otherwise NULL */
UNIV_INTERN
dict_foreign_t*
dict_table_get_foreign_constraint(
/*==============================*/
- /* out: pointer to foreign key struct if index
- is defined for foreign key, otherwise NULL */
- dict_table_t* table, /* in: InnoDB table */
- dict_index_t* index); /* in: InnoDB index */
-/*************************************************************************
+ dict_table_t* table, /*!< in: InnoDB table */
+ dict_index_t* index); /*!< in: InnoDB index */
+/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
Each foreign key constraint must be accompanied with indexes in
bot participating tables. The indexes are allowed to contain more
-fields than mentioned in the constraint. */
+fields than mentioned in the constraint.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_foreign_constraints(
/*============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- const char* sql_string, /* in: table create statement where
+ trx_t* trx, /*!< in: transaction */
+ const char* sql_string, /*!< in: table create statement where
foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES
table2(c, d), table2 can be written
@@ -347,349 +352,345 @@ dict_create_foreign_constraints(
name before it: test.table2; the
default database id the database of
parameter name */
- const char* name, /* in: table full name in the
+ const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
- ibool reject_fks); /* in: if TRUE, fail with error
+ ibool reject_fks); /*!< in: if TRUE, fail with error
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
-/**************************************************************************
-Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */
+/**********************************************************************//**
+Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement.
+@return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the
+constraint id does not match */
UNIV_INTERN
ulint
dict_foreign_parse_drop_constraints(
/*================================*/
- /* out: DB_SUCCESS or
- DB_CANNOT_DROP_CONSTRAINT if
- syntax error or the constraint
- id does not match */
- mem_heap_t* heap, /* in: heap from which we can
+ mem_heap_t* heap, /*!< in: heap from which we can
allocate memory */
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table */
- ulint* n, /* out: number of constraints
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table */
+ ulint* n, /*!< out: number of constraints
to drop */
- const char*** constraints_to_drop); /* out: id's of the
+ const char*** constraints_to_drop); /*!< out: id's of the
constraints to drop */
-/**************************************************************************
+/**********************************************************************//**
Returns a table object and optionally increment its MySQL open handle count.
NOTE! This is a high-level function to be used mainly from outside the
'dict' directory. Inside this directory dict_table_get_low is usually the
-appropriate function. */
+appropriate function.
+@return table, NULL if does not exist */
UNIV_INTERN
dict_table_t*
dict_table_get(
/*===========*/
- /* out: table, NULL if
- does not exist */
- const char* table_name, /* in: table name */
+ const char* table_name, /*!< in: table name */
ibool inc_mysql_count);
- /* in: whether to increment the open
+ /*!< in: whether to increment the open
handle count on the table */
-/**************************************************************************
-Returns a index object, based on table and index id, and memoryfixes it. */
+/**********************************************************************//**
+Returns a index object, based on table and index id, and memoryfixes it.
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_index_get_on_id_low(
/*=====================*/
- /* out: index, NULL if does not
- exist */
- dict_table_t* table, /* in: table */
- dulint index_id); /* in: index id */
-/**************************************************************************
-Checks if a table is in the dictionary cache. */
+ dict_table_t* table, /*!< in: table */
+ dulint index_id); /*!< in: index id */
+/**********************************************************************//**
+Checks if a table is in the dictionary cache.
+@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_check_if_in_cache_low(
/*=============================*/
- /* out: table, NULL if not found */
- const char* table_name); /* in: table name */
-/**************************************************************************
+ const char* table_name); /*!< in: table name */
+/**********************************************************************//**
Gets a table; loads it to the dictionary cache if necessary. A low-level
-function. */
+function.
+@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_get_low(
/*===============*/
- /* out: table, NULL if not found */
- const char* table_name); /* in: table name */
-/**************************************************************************
-Returns a table object based on table id. */
+ const char* table_name); /*!< in: table name */
+/**********************************************************************//**
+Returns a table object based on table id.
+@return table, NULL if does not exist */
UNIV_INLINE
dict_table_t*
dict_table_get_on_id_low(
/*=====================*/
- /* out: table, NULL if does not exist */
- dulint table_id); /* in: table id */
-/**************************************************************************
+ dulint table_id); /*!< in: table id */
+/**********************************************************************//**
Find an index that is equivalent to the one passed in and is not marked
-for deletion. */
+for deletion.
+@return index equivalent to foreign->foreign_index, or NULL */
UNIV_INTERN
dict_index_t*
dict_foreign_find_equiv_index(
/*==========================*/
- /* out: index equivalent to
- foreign->foreign_index, or NULL */
- dict_foreign_t* foreign);/* in: foreign key */
-/**************************************************************************
-Returns an index object by matching on the name and column names and if
-more than index is found return the index with the higher id.*/
+ dict_foreign_t* foreign);/*!< in: foreign key */
+/**********************************************************************//**
+Returns an index object by matching on the name and column names and
+if more than one index matches return the index with the max id
+@return matching index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_table_get_index_by_max_id(
/*===========================*/
- /* out: matching index, NULL if not found */
- dict_table_t* table, /* in: table */
- const char* name, /* in: the index name to find */
- const char** columns,/* in: array of column names */
- ulint n_cols);/* in: number of columns */
-/**************************************************************************
-Returns a column's name. */
-
+ dict_table_t* table, /*!< in: table */
+ const char* name, /*!< in: the index name to find */
+ const char** columns,/*!< in: array of column names */
+ ulint n_cols);/*!< in: number of columns */
+/**********************************************************************//**
+Returns a column's name.
+@return column name. NOTE: not guaranteed to stay valid if table is
+modified in any way (columns added, etc.). */
+UNIV_INTERN
const char*
dict_table_get_col_name(
/*====================*/
- /* out: column name. NOTE: not
- guaranteed to stay valid if table is
- modified in any way (columns added,
- etc.). */
- const dict_table_t* table, /* in: table */
- ulint col_nr);/* in: column number */
+ const dict_table_t* table, /*!< in: table */
+ ulint col_nr);/*!< in: column number */
-/**************************************************************************
+/**********************************************************************//**
Prints a table definition. */
UNIV_INTERN
void
dict_table_print(
/*=============*/
- dict_table_t* table); /* in: table */
-/**************************************************************************
+ dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
void
dict_table_print_low(
/*=================*/
- dict_table_t* table); /* in: table */
-/**************************************************************************
+ dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Prints a table data when we know the table name. */
UNIV_INTERN
void
dict_table_print_by_name(
/*=====================*/
- const char* name);
-/**************************************************************************
+ const char* name); /*!< in: table name */
+/**********************************************************************//**
Outputs info on foreign keys of a table. */
UNIV_INTERN
void
dict_print_info_on_foreign_keys(
/*============================*/
- ibool create_table_format, /* in: if TRUE then print in
+ ibool create_table_format, /*!< in: if TRUE then print in
a format suitable to be inserted into
a CREATE TABLE, otherwise in the format
of SHOW TABLE STATUS */
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_table_t* table); /* in: table */
-/**************************************************************************
+ FILE* file, /*!< in: file where to print */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Outputs info on a foreign key of a table in a format suitable for
CREATE TABLE. */
UNIV_INTERN
void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign, /* in: foreign key constraint */
- ibool add_newline); /* in: whether to add a newline */
-/************************************************************************
+ FILE* file, /*!< in: file where to print */
+ trx_t* trx, /*!< in: transaction */
+ dict_foreign_t* foreign, /*!< in: foreign key constraint */
+ ibool add_newline); /*!< in: whether to add a newline */
+/********************************************************************//**
Displays the names of the index and the table. */
UNIV_INTERN
void
dict_index_name_print(
/*==================*/
- FILE* file, /* in: output stream */
- trx_t* trx, /* in: transaction */
- const dict_index_t* index); /* in: index to print */
+ FILE* file, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index); /*!< in: index to print */
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the first index on the table (the clustered index). */
+/********************************************************************//**
+Gets the first index on the table (the clustered index).
+@return index, NULL if none exists */
UNIV_INLINE
dict_index_t*
dict_table_get_first_index(
/*=======================*/
- /* out: index, NULL if none exists */
- const dict_table_t* table); /* in: table */
-/************************************************************************
-Gets the next index on the table. */
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
+Gets the next index on the table.
+@return index, NULL if none left */
UNIV_INLINE
dict_index_t*
dict_table_get_next_index(
/*======================*/
- /* out: index, NULL if none left */
- const dict_index_t* index); /* in: index */
+ const dict_index_t* index); /*!< in: index */
#else /* UNIV_DEBUG */
# define dict_table_get_first_index(table) UT_LIST_GET_FIRST((table)->indexes)
# define dict_table_get_next_index(index) UT_LIST_GET_NEXT(indexes, index)
#endif /* UNIV_DEBUG */
-/************************************************************************
-Check whether the index is the clustered index. */
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
+Check whether the index is the clustered index.
+@return nonzero for clustered index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_clust(
/*================*/
- /* out: nonzero for clustered index,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
__attribute__((pure));
-/************************************************************************
-Check whether the index is unique. */
+/********************************************************************//**
+Check whether the index is unique.
+@return nonzero for unique index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_unique(
/*=================*/
- /* out: nonzero for unique index,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
__attribute__((pure));
-/************************************************************************
-Check whether the index is the insert buffer tree. */
+/********************************************************************//**
+Check whether the index is the insert buffer tree.
+@return nonzero for insert buffer, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_ibuf(
/*===============*/
- /* out: nonzero for insert buffer,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
+ __attribute__((pure));
+/********************************************************************//**
+Check whether the index is a secondary index or the insert buffer tree.
+@return nonzero for insert buffer, zero for other indexes */
+UNIV_INLINE
+ulint
+dict_index_is_sec_or_ibuf(
+/*======================*/
+ const dict_index_t* index) /*!< in: index */
__attribute__((pure));
-/************************************************************************
+/********************************************************************//**
Gets the number of user-defined columns in a table in the dictionary
-cache. */
+cache.
+@return number of user-defined (e.g., not ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_user_cols(
/*=======================*/
- /* out: number of user-defined
- (e.g., not ROW_ID)
- columns of a table */
- const dict_table_t* table); /* in: table */
-/************************************************************************
-Gets the number of system columns in a table in the dictionary cache. */
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
+Gets the number of system columns in a table in the dictionary cache.
+@return number of system (e.g., ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_sys_cols(
/*======================*/
- /* out: number of system (e.g.,
- ROW_ID) columns of a table */
- const dict_table_t* table); /* in: table */
-/************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
Gets the number of all columns (also system) in a table in the dictionary
-cache. */
+cache.
+@return number of columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_cols(
/*==================*/
- /* out: number of columns of a table */
- const dict_table_t* table); /* in: table */
+ const dict_table_t* table); /*!< in: table */
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the nth column of a table. */
+/********************************************************************//**
+Gets the nth column of a table.
+@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_nth_col(
/*===================*/
- /* out: pointer to column object */
- const dict_table_t* table, /* in: table */
- ulint pos); /* in: position of column */
-/************************************************************************
-Gets the given system column of a table. */
+ const dict_table_t* table, /*!< in: table */
+ ulint pos); /*!< in: position of column */
+/********************************************************************//**
+Gets the given system column of a table.
+@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_sys_col(
/*===================*/
- /* out: pointer to column object */
- const dict_table_t* table, /* in: table */
- ulint sys); /* in: DATA_ROW_ID, ... */
+ const dict_table_t* table, /*!< in: table */
+ ulint sys); /*!< in: DATA_ROW_ID, ... */
#else /* UNIV_DEBUG */
#define dict_table_get_nth_col(table, pos) \
((table)->cols + (pos))
#define dict_table_get_sys_col(table, sys) \
((table)->cols + (table)->n_cols + (sys) - DATA_N_SYS_COLS)
#endif /* UNIV_DEBUG */
-/************************************************************************
-Gets the given system column number of a table. */
+/********************************************************************//**
+Gets the given system column number of a table.
+@return column number */
UNIV_INLINE
ulint
dict_table_get_sys_col_no(
/*======================*/
- /* out: column number */
- const dict_table_t* table, /* in: table */
- ulint sys); /* in: DATA_ROW_ID, ... */
-/************************************************************************
-Returns the minimum data size of an index record. */
+ const dict_table_t* table, /*!< in: table */
+ ulint sys); /*!< in: DATA_ROW_ID, ... */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Returns the minimum data size of an index record.
+@return minimum data size in bytes */
UNIV_INLINE
ulint
dict_index_get_min_size(
/*====================*/
- /* out: minimum data size in bytes */
- const dict_index_t* index); /* in: index */
-/************************************************************************
-Check whether the table uses the compact page format. */
+ const dict_index_t* index); /*!< in: index */
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
+Check whether the table uses the compact page format.
+@return TRUE if table uses the compact page format */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
- /* out: TRUE if table uses the
- compact page format */
- const dict_table_t* table); /* in: table */
-/************************************************************************
-Determine the file format of a table. */
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
+Determine the file format of a table.
+@return file format version */
UNIV_INLINE
ulint
dict_table_get_format(
/*==================*/
- /* out: file format version */
- const dict_table_t* table); /* in: table */
-/************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
Set the file format of a table. */
UNIV_INLINE
void
dict_table_set_format(
/*==================*/
- dict_table_t* table, /* in/out: table */
- ulint format);/* in: file format version */
-/************************************************************************
-Extract the compressed page size from table flags. */
+ dict_table_t* table, /*!< in/out: table */
+ ulint format);/*!< in: file format version */
+/********************************************************************//**
+Extract the compressed page size from table flags.
+@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_flags_to_zip_size(
/*=========================*/
- /* out: compressed page size,
- or 0 if not compressed */
- ulint flags) /* in: flags */
+ ulint flags) /*!< in: flags */
__attribute__((const));
-/************************************************************************
-Check whether the table uses the compressed compact page format. */
+/********************************************************************//**
+Check whether the table uses the compressed compact page format.
+@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_zip_size(
/*================*/
- /* out: compressed page size,
- or 0 if not compressed */
- const dict_table_t* table); /* in: table */
-/************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
Checks if a column is in the ordering columns of the clustered index of a
-table. Column prefixes are treated like whole columns. */
+table. Column prefixes are treated like whole columns.
+@return TRUE if the column, or its prefix, is in the clustered key */
UNIV_INTERN
ibool
dict_table_col_in_clustered_key(
/*============================*/
- /* out: TRUE if the column, or its
- prefix, is in the clustered key */
- const dict_table_t* table, /* in: table */
- ulint n); /* in: column number */
-/***********************************************************************
+ const dict_table_t* table, /*!< in: table */
+ ulint n); /*!< in: column number */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Copies types of columns contained in table to tuple and sets all
fields of the tuple to the SQL NULL value. This function should
be called right after dtuple_create(). */
@@ -697,411 +698,406 @@ UNIV_INTERN
void
dict_table_copy_types(
/*==================*/
- dtuple_t* tuple, /* in/out: data tuple */
- const dict_table_t* table); /* in: table */
-/**************************************************************************
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Looks for an index with the given id. NOTE that we do not reserve
the dictionary mutex: this function is for emergency purposes like
-printing info of a corrupt database page! */
+printing info of a corrupt database page!
+@return index or NULL if not found from cache */
UNIV_INTERN
dict_index_t*
dict_index_find_on_id_low(
/*======================*/
- /* out: index or NULL if not found from cache */
- dulint id); /* in: index id */
-/**************************************************************************
-Adds an index to the dictionary cache. */
+ dulint id); /*!< in: index id */
+/**********************************************************************//**
+Adds an index to the dictionary cache.
+@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
UNIV_INTERN
ulint
dict_index_add_to_cache(
/*====================*/
- /* out: DB_SUCCESS or error code */
- dict_table_t* table, /* in: table on which the index is */
- dict_index_t* index, /* in, own: index; NOTE! The index memory
+ dict_table_t* table, /*!< in: table on which the index is */
+ dict_index_t* index, /*!< in, own: index; NOTE! The index memory
object is freed in this function! */
- ulint page_no,/* in: root page number of the index */
- ibool strict);/* in: TRUE=refuse to create the index
+ ulint page_no,/*!< in: root page number of the index */
+ ibool strict);/*!< in: TRUE=refuse to create the index
if records could be too big to fit in
an B-tree page */
-/**************************************************************************
+/**********************************************************************//**
Removes an index from the dictionary cache. */
UNIV_INTERN
void
dict_index_remove_from_cache(
/*=========================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index); /* in, own: index */
-/************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index); /*!< in, own: index */
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Gets the number of fields in the internal representation of an index,
-including fields added by the dictionary system. */
+including fields added by the dictionary system.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_fields(
/*====================*/
- /* out: number of fields */
- const dict_index_t* index); /* in: an internal
+ const dict_index_t* index); /*!< in: an internal
representation of index (in
the dictionary cache) */
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index
that uniquely determine the position of an index entry in the index, if
we do not take multiversioning into account: in the B-tree use the value
-returned by dict_index_get_n_unique_in_tree. */
+returned by dict_index_get_n_unique_in_tree.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique(
/*====================*/
- /* out: number of fields */
- const dict_index_t* index); /* in: an internal representation
+ const dict_index_t* index); /*!< in: an internal representation
of index (in the dictionary cache) */
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index
which uniquely determine the position of an index entry in the index, if
-we also take multiversioning into account. */
+we also take multiversioning into account.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique_in_tree(
/*============================*/
- /* out: number of fields */
- const dict_index_t* index); /* in: an internal representation
+ const dict_index_t* index); /*!< in: an internal representation
of index (in the dictionary cache) */
-/************************************************************************
+/********************************************************************//**
Gets the number of user-defined ordering fields in the index. In the internal
representation we add the row id to the ordering fields to make all indexes
unique, but this function returns the number of fields the user defined
-in the index as ordering fields. */
+in the index as ordering fields.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_ordering_defined_by_user(
/*======================================*/
- /* out: number of fields */
- const dict_index_t* index); /* in: an internal representation
+ const dict_index_t* index); /*!< in: an internal representation
of index (in the dictionary cache) */
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the nth field of an index. */
+/********************************************************************//**
+Gets the nth field of an index.
+@return pointer to field object */
UNIV_INLINE
dict_field_t*
dict_index_get_nth_field(
/*=====================*/
- /* out: pointer to field object */
- const dict_index_t* index, /* in: index */
- ulint pos); /* in: position of field */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos); /*!< in: position of field */
#else /* UNIV_DEBUG */
# define dict_index_get_nth_field(index, pos) ((index)->fields + (pos))
#endif /* UNIV_DEBUG */
-/************************************************************************
-Gets pointer to the nth column in an index. */
+/********************************************************************//**
+Gets pointer to the nth column in an index.
+@return column */
UNIV_INLINE
const dict_col_t*
dict_index_get_nth_col(
/*===================*/
- /* out: column */
- const dict_index_t* index, /* in: index */
- ulint pos); /* in: position of the field */
-/************************************************************************
-Gets the column number of the nth field in an index. */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos); /*!< in: position of the field */
+/********************************************************************//**
+Gets the column number of the nth field in an index.
+@return column number */
UNIV_INLINE
ulint
dict_index_get_nth_col_no(
/*======================*/
- /* out: column number */
- const dict_index_t* index, /* in: index */
- ulint pos); /* in: position of the field */
-/************************************************************************
-Looks for column n in an index. */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos); /*!< in: position of the field */
+/********************************************************************//**
+Looks for column n in an index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
dict_index_get_nth_col_pos(
/*=======================*/
- /* out: position in internal
- representation of the index;
- if not contained, returns
- ULINT_UNDEFINED */
- const dict_index_t* index, /* in: index */
- ulint n); /* in: column number */
-/************************************************************************
-Returns TRUE if the index contains a column or a prefix of that column. */
+ const dict_index_t* index, /*!< in: index */
+ ulint n); /*!< in: column number */
+/********************************************************************//**
+Returns TRUE if the index contains a column or a prefix of that column.
+@return TRUE if contains the column or its prefix */
UNIV_INTERN
ibool
dict_index_contains_col_or_prefix(
/*==============================*/
- /* out: TRUE if contains the column
- or its prefix */
- const dict_index_t* index, /* in: index */
- ulint n); /* in: column number */
-/************************************************************************
+ const dict_index_t* index, /*!< in: index */
+ ulint n); /*!< in: column number */
+/********************************************************************//**
Looks for a matching field in an index. The column has to be the same. The
column in index must be complete, or must contain a prefix longer than the
column in index2. That is, we must be able to construct the prefix in index2
-from the prefix in index. */
+from the prefix in index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
dict_index_get_nth_field_pos(
/*=========================*/
- /* out: position in internal
- representation of the index;
- if not contained, returns
- ULINT_UNDEFINED */
- const dict_index_t* index, /* in: index from which to search */
- const dict_index_t* index2, /* in: index */
- ulint n); /* in: field number in index2 */
-/************************************************************************
-Looks for column n position in the clustered index. */
+ const dict_index_t* index, /*!< in: index from which to search */
+ const dict_index_t* index2, /*!< in: index */
+ ulint n); /*!< in: field number in index2 */
+/********************************************************************//**
+Looks for column n position in the clustered index.
+@return position in internal representation of the clustered index */
UNIV_INTERN
ulint
dict_table_get_nth_col_pos(
/*=======================*/
- /* out: position in internal
- representation of
- the clustered index */
- const dict_table_t* table, /* in: table */
- ulint n); /* in: column number */
-/************************************************************************
-Returns the position of a system column in an index. */
+ const dict_table_t* table, /*!< in: table */
+ ulint n); /*!< in: column number */
+/********************************************************************//**
+Returns the position of a system column in an index.
+@return position, ULINT_UNDEFINED if not contained */
UNIV_INLINE
ulint
dict_index_get_sys_col_pos(
/*=======================*/
- /* out: position,
- ULINT_UNDEFINED if not contained */
- const dict_index_t* index, /* in: index */
- ulint type); /* in: DATA_ROW_ID, ... */
-/***********************************************************************
+ const dict_index_t* index, /*!< in: index */
+ ulint type); /*!< in: DATA_ROW_ID, ... */
+/*******************************************************************//**
Adds a column to index. */
UNIV_INTERN
void
dict_index_add_col(
/*===============*/
- dict_index_t* index, /* in/out: index */
- const dict_table_t* table, /* in: table */
- dict_col_t* col, /* in: column */
- ulint prefix_len); /* in: column prefix length */
-/***********************************************************************
+ dict_index_t* index, /*!< in/out: index */
+ const dict_table_t* table, /*!< in: table */
+ dict_col_t* col, /*!< in: column */
+ ulint prefix_len); /*!< in: column prefix length */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Copies types of fields contained in index to tuple. */
UNIV_INTERN
void
dict_index_copy_types(
/*==================*/
- dtuple_t* tuple, /* in/out: data tuple */
- const dict_index_t* index, /* in: index */
- ulint n_fields); /* in: number of
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const dict_index_t* index, /*!< in: index */
+ ulint n_fields); /*!< in: number of
field types to copy */
-/*************************************************************************
-Gets the field column. */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Gets the field column.
+@return field->col, pointer to the table column */
UNIV_INLINE
const dict_col_t*
dict_field_get_col(
/*===============*/
- const dict_field_t* field);
-
-/**************************************************************************
+ const dict_field_t* field); /*!< in: index field */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Returns an index object if it is found in the dictionary cache.
-Assumes that dict_sys->mutex is already being held. */
+Assumes that dict_sys->mutex is already being held.
+@return index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_index_get_if_in_cache_low(
/*===========================*/
- /* out: index, NULL if not found */
- dulint index_id); /* in: index id */
+ dulint index_id); /*!< in: index id */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
-Returns an index object if it is found in the dictionary cache. */
+/**********************************************************************//**
+Returns an index object if it is found in the dictionary cache.
+@return index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_index_get_if_in_cache(
/*=======================*/
- /* out: index, NULL if not found */
- dulint index_id); /* in: index id */
+ dulint index_id); /*!< in: index id */
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Checks that a tuple has n_fields_cmp value in a sensible range, so that
-no comparison can occur with the page number field in a node pointer. */
+no comparison can occur with the page number field in a node pointer.
+@return TRUE if ok */
UNIV_INTERN
ibool
dict_index_check_search_tuple(
/*==========================*/
- /* out: TRUE if ok */
- const dict_index_t* index, /* in: index tree */
- const dtuple_t* tuple); /* in: tuple used in a search */
-/**************************************************************************
+ const dict_index_t* index, /*!< in: index tree */
+ const dtuple_t* tuple); /*!< in: tuple used in a search */
+/**********************************************************************//**
Check for duplicate index entries in a table [using the index name] */
UNIV_INTERN
void
dict_table_check_for_dup_indexes(
/*=============================*/
- const dict_table_t* table); /* in: Check for dup indexes
+ const dict_table_t* table); /*!< in: Check for dup indexes
in this table */
#endif /* UNIV_DEBUG */
-/**************************************************************************
-Builds a node pointer out of a physical record and a page number. */
+/**********************************************************************//**
+Builds a node pointer out of a physical record and a page number.
+@return own: node pointer */
UNIV_INTERN
dtuple_t*
dict_index_build_node_ptr(
/*======================*/
- /* out, own: node pointer */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record for which to build node
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record for which to build node
pointer */
- ulint page_no,/* in: page number to put in node
+ ulint page_no,/*!< in: page number to put in node
pointer */
- mem_heap_t* heap, /* in: memory heap where pointer
+ mem_heap_t* heap, /*!< in: memory heap where pointer
created */
- ulint level); /* in: level of rec in tree:
+ ulint level); /*!< in: level of rec in tree:
0 means leaf level */
-/**************************************************************************
+/**********************************************************************//**
Copies an initial segment of a physical record, long enough to specify an
-index entry uniquely. */
+index entry uniquely.
+@return pointer to the prefix record */
UNIV_INTERN
rec_t*
dict_index_copy_rec_order_prefix(
/*=============================*/
- /* out: pointer to the prefix record */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record for which to
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record for which to
copy prefix */
- ulint* n_fields,/* out: number of fields copied */
- byte** buf, /* in/out: memory buffer for the
+ ulint* n_fields,/*!< out: number of fields copied */
+ byte** buf, /*!< in/out: memory buffer for the
copied prefix, or NULL */
- ulint* buf_size);/* in/out: buffer size */
-/**************************************************************************
-Builds a typed data tuple out of a physical record. */
+ ulint* buf_size);/*!< in/out: buffer size */
+/**********************************************************************//**
+Builds a typed data tuple out of a physical record.
+@return own: data tuple */
UNIV_INTERN
dtuple_t*
dict_index_build_data_tuple(
/*========================*/
- /* out, own: data tuple */
- dict_index_t* index, /* in: index */
- rec_t* rec, /* in: record for which to build data tuple */
- ulint n_fields,/* in: number of data fields */
- mem_heap_t* heap); /* in: memory heap where tuple created */
-/*************************************************************************
-Gets the space id of the root of the index tree. */
+ dict_index_t* index, /*!< in: index */
+ rec_t* rec, /*!< in: record for which to build data tuple */
+ ulint n_fields,/*!< in: number of data fields */
+ mem_heap_t* heap); /*!< in: memory heap where tuple created */
+/*********************************************************************//**
+Gets the space id of the root of the index tree.
+@return space id */
UNIV_INLINE
ulint
dict_index_get_space(
/*=================*/
- /* out: space id */
- const dict_index_t* index); /* in: index */
-/*************************************************************************
+ const dict_index_t* index); /*!< in: index */
+/*********************************************************************//**
Sets the space id of the root of the index tree. */
UNIV_INLINE
void
dict_index_set_space(
/*=================*/
- dict_index_t* index, /* in/out: index */
- ulint space); /* in: space id */
-/*************************************************************************
-Gets the page number of the root of the index tree. */
+ dict_index_t* index, /*!< in/out: index */
+ ulint space); /*!< in: space id */
+/*********************************************************************//**
+Gets the page number of the root of the index tree.
+@return page number */
UNIV_INLINE
ulint
dict_index_get_page(
/*================*/
- /* out: page number */
- const dict_index_t* tree); /* in: index */
-/*************************************************************************
+ const dict_index_t* tree); /*!< in: index */
+/*********************************************************************//**
Sets the page number of the root of index tree. */
UNIV_INLINE
void
dict_index_set_page(
/*================*/
- dict_index_t* index, /* in/out: index */
- ulint page); /* in: page number */
-/*************************************************************************
-Gets the read-write lock of the index tree. */
+ dict_index_t* index, /*!< in/out: index */
+ ulint page); /*!< in: page number */
+/*********************************************************************//**
+Gets the read-write lock of the index tree.
+@return read-write lock */
UNIV_INLINE
rw_lock_t*
dict_index_get_lock(
/*================*/
- /* out: read-write lock */
- dict_index_t* index); /* in: index */
-/************************************************************************
+ dict_index_t* index); /*!< in: index */
+/********************************************************************//**
Returns free space reserved for future updates of records. This is
relevant only in the case of many consecutive inserts, as updates
-which make the records bigger might fragment the index. */
+which make the records bigger might fragment the index.
+@return number of free bytes on page, reserved for updates */
UNIV_INLINE
ulint
dict_index_get_space_reserve(void);
/*==============================*/
- /* out: number of free bytes on page,
- reserved for updates */
-/*************************************************************************
+/*********************************************************************//**
Calculates the minimum record length in an index. */
UNIV_INTERN
ulint
dict_index_calc_min_rec_len(
/*========================*/
- const dict_index_t* index); /* in: index */
-/*************************************************************************
+ const dict_index_t* index); /*!< in: index */
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics_low(
/*=======================*/
- dict_table_t* table, /* in/out: table */
- ibool has_dict_mutex);/* in: TRUE if the caller has the
+ dict_table_t* table, /*!< in/out: table */
+ ibool has_dict_mutex);/*!< in: TRUE if the caller has the
dictionary mutex */
-/*************************************************************************
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics(
/*===================*/
- dict_table_t* table); /* in/out: table */
-/************************************************************************
+ dict_table_t* table); /*!< in/out: table */
+/********************************************************************//**
Reserves the dictionary system mutex for MySQL. */
UNIV_INTERN
void
dict_mutex_enter_for_mysql(void);
/*============================*/
-/************************************************************************
+/********************************************************************//**
Releases the dictionary system mutex for MySQL. */
UNIV_INTERN
void
dict_mutex_exit_for_mysql(void);
/*===========================*/
-/************************************************************************
-Checks if the database name in two table names is the same. */
+/********************************************************************//**
+Checks if the database name in two table names is the same.
+@return TRUE if same db name */
UNIV_INTERN
ibool
dict_tables_have_same_db(
/*=====================*/
- /* out: TRUE if same db name */
- const char* name1, /* in: table name in the form
+ const char* name1, /*!< in: table name in the form
dbname '/' tablename */
- const char* name2); /* in: table name in the form
+ const char* name2); /*!< in: table name in the form
dbname '/' tablename */
-/*************************************************************************
+/*********************************************************************//**
Removes an index from the cache */
UNIV_INTERN
void
dict_index_remove_from_cache(
/*=========================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index); /* in, own: index */
-/**************************************************************************
-Get index by name */
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index); /*!< in, own: index */
+/**********************************************************************//**
+Get index by name
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_table_get_index_on_name(
/*=========================*/
- /* out: index, NULL if does not exist */
- dict_table_t* table, /* in: table */
- const char* name); /* in: name of the index to find */
-/**************************************************************************
+ dict_table_t* table, /*!< in: table */
+ const char* name); /*!< in: name of the index to find */
+/**********************************************************************//**
In case there is more than one index with the same name return the index
-with the min(id). */
+with the min(id).
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_table_get_index_on_name_and_min_id(
/*====================================*/
- /* out: index, NULL if does not exist */
- dict_table_t* table, /* in: table */
- const char* name); /* in: name of the index to find */
+ dict_table_t* table, /*!< in: table */
+ const char* name); /*!< in: name of the index to find */
UNIV_INTERN
void
@@ -1113,38 +1109,60 @@ and unique key errors */
extern FILE* dict_foreign_err_file;
extern mutex_t dict_foreign_err_mutex; /* mutex protecting the buffers */
-extern dict_sys_t* dict_sys; /* the dictionary system */
+/** the dictionary system */
+extern dict_sys_t* dict_sys;
+/** the data dictionary rw-latch protecting dict_sys */
extern rw_lock_t dict_operation_lock;
/* Dictionary system struct */
struct dict_sys_struct{
- mutex_t mutex; /* mutex protecting the data
+ mutex_t mutex; /*!< mutex protecting the data
dictionary; protects also the
disk-based dictionary system tables;
this mutex serializes CREATE TABLE
and DROP TABLE, as well as reading
the dictionary data for a table from
system tables */
- dulint row_id; /* the next row id to assign;
+ dulint row_id; /*!< the next row id to assign;
NOTE that at a checkpoint this
must be written to the dict system
header and flushed to a file; in
recovery this must be derived from
the log records */
- hash_table_t* table_hash; /* hash table of the tables, based
+ hash_table_t* table_hash; /*!< hash table of the tables, based
on name */
- hash_table_t* table_id_hash; /* hash table of the tables, based
+ hash_table_t* table_id_hash; /*!< hash table of the tables, based
on id */
UT_LIST_BASE_NODE_T(dict_table_t)
- table_LRU; /* LRU list of tables */
- ulint size; /* varying space in bytes occupied
+ table_LRU; /*!< LRU list of tables */
+ ulint size; /*!< varying space in bytes occupied
by the data dictionary table and
index objects */
- dict_table_t* sys_tables; /* SYS_TABLES table */
- dict_table_t* sys_columns; /* SYS_COLUMNS table */
- dict_table_t* sys_indexes; /* SYS_INDEXES table */
- dict_table_t* sys_fields; /* SYS_FIELDS table */
+ dict_table_t* sys_tables; /*!< SYS_TABLES table */
+ dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
+ dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
+ dict_table_t* sys_fields; /*!< SYS_FIELDS table */
};
+#endif /* !UNIV_HOTBACKUP */
+
+/** dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */
+extern dict_index_t* dict_ind_redundant;
+/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
+extern dict_index_t* dict_ind_compact;
+
+/**********************************************************************//**
+Inits dict_ind_redundant and dict_ind_compact. */
+UNIV_INTERN
+void
+dict_ind_init(void);
+/*===============*/
+
+/**********************************************************************//**
+Closes the data dictionary module. */
+UNIV_INTERN
+void
+dict_close(void);
+/*============*/
#ifndef UNIV_NONINL
#include "dict0dict.ic"
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 687e5f9fb13..aada3096261 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -16,24 +16,26 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/dict0dict.ic
Data dictionary system
Created 1/8/1996 Heikki Tuuri
***********************************************************************/
+#include "data0type.h"
+#ifndef UNIV_HOTBACKUP
#include "dict0load.h"
#include "rem0types.h"
-#include "data0type.h"
-/*************************************************************************
+/*********************************************************************//**
Gets the column data type. */
UNIV_INLINE
void
dict_col_copy_type(
/*===============*/
- const dict_col_t* col, /* in: column */
- dtype_t* type) /* out: data type */
+ const dict_col_t* col, /*!< in: column */
+ dtype_t* type) /*!< out: data type */
{
ut_ad(col && type);
@@ -43,17 +45,18 @@ dict_col_copy_type(
type->mbminlen = col->mbminlen;
type->mbmaxlen = col->mbmaxlen;
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Assert that a column and a data type match. */
+/*********************************************************************//**
+Assert that a column and a data type match.
+@return TRUE */
UNIV_INLINE
ibool
dict_col_type_assert_equal(
/*=======================*/
- /* out: TRUE */
- const dict_col_t* col, /* in: column */
- const dtype_t* type) /* in: data type */
+ const dict_col_t* col, /*!< in: column */
+ const dtype_t* type) /*!< in: data type */
{
ut_ad(col);
ut_ad(type);
@@ -61,83 +64,89 @@ dict_col_type_assert_equal(
ut_ad(col->mtype == type->mtype);
ut_ad(col->prtype == type->prtype);
ut_ad(col->len == type->len);
+# ifndef UNIV_HOTBACKUP
ut_ad(col->mbminlen == type->mbminlen);
ut_ad(col->mbmaxlen == type->mbmaxlen);
+# endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
#endif /* UNIV_DEBUG */
-/***************************************************************************
-Returns the minimum size of the column. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Returns the minimum size of the column.
+@return minimum size */
UNIV_INLINE
ulint
dict_col_get_min_size(
/*==================*/
- /* out: minimum size */
- const dict_col_t* col) /* in: column */
+ const dict_col_t* col) /*!< in: column */
{
return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
col->mbminlen, col->mbmaxlen));
}
-/***************************************************************************
-Returns the maximum size of the column. */
+/***********************************************************************//**
+Returns the maximum size of the column.
+@return maximum size */
UNIV_INLINE
ulint
dict_col_get_max_size(
/*==================*/
- /* out: maximum size */
- const dict_col_t* col) /* in: column */
+ const dict_col_t* col) /*!< in: column */
{
return(dtype_get_max_size_low(col->mtype, col->len));
}
-/***************************************************************************
-Returns the size of a fixed size column, 0 if not a fixed size column. */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************************//**
+Returns the size of a fixed size column, 0 if not a fixed size column.
+@return fixed size, or 0 */
UNIV_INLINE
ulint
dict_col_get_fixed_size(
/*====================*/
- /* out: fixed size, or 0 */
- const dict_col_t* col) /* in: column */
+ const dict_col_t* col, /*!< in: column */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
- col->mbminlen, col->mbmaxlen));
+ col->mbminlen, col->mbmaxlen, comp));
}
-/***************************************************************************
+/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
-For fixed length types it is the fixed length of the type, otherwise 0. */
+For fixed length types it is the fixed length of the type, otherwise 0.
+@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dict_col_get_sql_null_size(
/*=======================*/
- /* out: SQL null storage size
- in ROW_FORMAT=REDUNDANT */
- const dict_col_t* col) /* in: column */
+ const dict_col_t* col, /*!< in: column */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
- return(dict_col_get_fixed_size(col));
+ return(dict_col_get_fixed_size(col, comp));
}
-/*************************************************************************
-Gets the column number. */
+/*********************************************************************//**
+Gets the column number.
+@return col->ind, table column position (starting from 0) */
UNIV_INLINE
ulint
dict_col_get_no(
/*============*/
- const dict_col_t* col)
+ const dict_col_t* col) /*!< in: column */
{
ut_ad(col);
return(col->ind);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the column position in the clustered index. */
UNIV_INLINE
ulint
dict_col_get_clust_pos(
/*===================*/
- const dict_col_t* col, /* in: table column */
- const dict_index_t* clust_index) /* in: clustered index */
+ const dict_col_t* col, /*!< in: table column */
+ const dict_index_t* clust_index) /*!< in: clustered index */
{
ulint i;
@@ -156,15 +165,16 @@ dict_col_get_clust_pos(
return(ULINT_UNDEFINED);
}
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the first index on the table (the clustered index). */
+/********************************************************************//**
+Gets the first index on the table (the clustered index).
+@return index, NULL if none exists */
UNIV_INLINE
dict_index_t*
dict_table_get_first_index(
/*=======================*/
- /* out: index, NULL if none exists */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -172,14 +182,14 @@ dict_table_get_first_index(
return(UT_LIST_GET_FIRST(((dict_table_t*) table)->indexes));
}
-/************************************************************************
-Gets the next index on the table. */
+/********************************************************************//**
+Gets the next index on the table.
+@return index, NULL if none left */
UNIV_INLINE
dict_index_t*
dict_table_get_next_index(
/*======================*/
- /* out: index, NULL if none left */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -187,31 +197,30 @@ dict_table_get_next_index(
return(UT_LIST_GET_NEXT(indexes, (dict_index_t*) index));
}
#endif /* UNIV_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Check whether the index is the clustered index. */
+/********************************************************************//**
+Check whether the index is the clustered index.
+@return nonzero for clustered index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_clust(
/*================*/
- /* out: nonzero for clustered index,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
return(UNIV_UNLIKELY(index->type & DICT_CLUSTERED));
}
-/************************************************************************
-Check whether the index is unique. */
+/********************************************************************//**
+Check whether the index is unique.
+@return nonzero for unique index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_unique(
/*=================*/
- /* out: nonzero for unique index,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -219,15 +228,14 @@ dict_index_is_unique(
return(UNIV_UNLIKELY(index->type & DICT_UNIQUE));
}
-/************************************************************************
-Check whether the index is the insert buffer tree. */
+/********************************************************************//**
+Check whether the index is the insert buffer tree.
+@return nonzero for insert buffer, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_ibuf(
/*===============*/
- /* out: nonzero for insert buffer,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -235,17 +243,34 @@ dict_index_is_ibuf(
return(UNIV_UNLIKELY(index->type & DICT_IBUF));
}
-/************************************************************************
+/********************************************************************//**
+Check whether the index is a secondary index or the insert buffer tree.
+@return nonzero for insert buffer, zero for other indexes */
+UNIV_INLINE
+ulint
+dict_index_is_sec_or_ibuf(
+/*======================*/
+ const dict_index_t* index) /*!< in: index */
+{
+ ulint type;
+
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+
+ type = index->type;
+
+ return(UNIV_LIKELY(!(type & DICT_CLUSTERED) || (type & DICT_IBUF)));
+}
+
+/********************************************************************//**
Gets the number of user-defined columns in a table in the dictionary
-cache. */
+cache.
+@return number of user-defined (e.g., not ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_user_cols(
/*=======================*/
- /* out: number of user-defined
- (e.g., not ROW_ID)
- columns of a table */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -253,15 +278,14 @@ dict_table_get_n_user_cols(
return(table->n_cols - DATA_N_SYS_COLS);
}
-/************************************************************************
-Gets the number of system columns in a table in the dictionary cache. */
+/********************************************************************//**
+Gets the number of system columns in a table in the dictionary cache.
+@return number of system (e.g., ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_sys_cols(
/*======================*/
- /* out: number of system (e.g.,
- ROW_ID) columns of a table */
- const dict_table_t* table __attribute__((unused))) /* in: table */
+ const dict_table_t* table __attribute__((unused))) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -270,15 +294,15 @@ dict_table_get_n_sys_cols(
return(DATA_N_SYS_COLS);
}
-/************************************************************************
+/********************************************************************//**
Gets the number of all columns (also system) in a table in the dictionary
-cache. */
+cache.
+@return number of columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_cols(
/*==================*/
- /* out: number of columns of a table */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -287,15 +311,15 @@ dict_table_get_n_cols(
}
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the nth column of a table. */
+/********************************************************************//**
+Gets the nth column of a table.
+@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_nth_col(
/*===================*/
- /* out: pointer to column object */
- const dict_table_t* table, /* in: table */
- ulint pos) /* in: position of column */
+ const dict_table_t* table, /*!< in: table */
+ ulint pos) /*!< in: position of column */
{
ut_ad(table);
ut_ad(pos < table->n_def);
@@ -304,15 +328,15 @@ dict_table_get_nth_col(
return((dict_col_t*) (table->cols) + pos);
}
-/************************************************************************
-Gets the given system column of a table. */
+/********************************************************************//**
+Gets the given system column of a table.
+@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_sys_col(
/*===================*/
- /* out: pointer to column object */
- const dict_table_t* table, /* in: table */
- ulint sys) /* in: DATA_ROW_ID, ... */
+ const dict_table_t* table, /*!< in: table */
+ ulint sys) /*!< in: DATA_ROW_ID, ... */
{
dict_col_t* col;
@@ -329,15 +353,15 @@ dict_table_get_sys_col(
}
#endif /* UNIV_DEBUG */
-/************************************************************************
-Gets the given system column number of a table. */
+/********************************************************************//**
+Gets the given system column number of a table.
+@return column number */
UNIV_INLINE
ulint
dict_table_get_sys_col_no(
/*======================*/
- /* out: column number */
- const dict_table_t* table, /* in: table */
- ulint sys) /* in: DATA_ROW_ID, ... */
+ const dict_table_t* table, /*!< in: table */
+ ulint sys) /*!< in: DATA_ROW_ID, ... */
{
ut_ad(table);
ut_ad(sys < DATA_N_SYS_COLS);
@@ -346,15 +370,14 @@ dict_table_get_sys_col_no(
return(table->n_cols - DATA_N_SYS_COLS + sys);
}
-/************************************************************************
-Check whether the table uses the compact page format. */
+/********************************************************************//**
+Check whether the table uses the compact page format.
+@return TRUE if table uses the compact page format */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
- /* out: TRUE if table uses the
- compact page format */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
@@ -365,28 +388,28 @@ dict_table_is_comp(
return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
}
-/************************************************************************
-Determine the file format of a table. */
+/********************************************************************//**
+Determine the file format of a table.
+@return file format version */
UNIV_INLINE
ulint
dict_table_get_format(
/*==================*/
- /* out: file format version */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
return((table->flags & DICT_TF_FORMAT_MASK) >> DICT_TF_FORMAT_SHIFT);
}
-/************************************************************************
+/********************************************************************//**
Determine the file format of a table. */
UNIV_INLINE
void
dict_table_set_format(
/*==================*/
- dict_table_t* table, /* in/out: table */
- ulint format) /* in: file format version */
+ dict_table_t* table, /*!< in/out: table */
+ ulint format) /*!< in: file format version */
{
ut_ad(table);
@@ -394,15 +417,14 @@ dict_table_set_format(
| (format << DICT_TF_FORMAT_SHIFT);
}
-/************************************************************************
-Extract the compressed page size from table flags. */
+/********************************************************************//**
+Extract the compressed page size from table flags.
+@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_flags_to_zip_size(
/*=========================*/
- /* out: compressed page size,
- or 0 if not compressed */
- ulint flags) /* in: flags */
+ ulint flags) /*!< in: flags */
{
ulint zip_size = flags & DICT_TF_ZSSIZE_MASK;
@@ -416,30 +438,29 @@ dict_table_flags_to_zip_size(
return(zip_size);
}
-/************************************************************************
-Check whether the table uses the compressed compact page format. */
+/********************************************************************//**
+Check whether the table uses the compressed compact page format.
+@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_zip_size(
/*================*/
- /* out: compressed page size,
- or 0 if not compressed */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
return(dict_table_flags_to_zip_size(table->flags));
}
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index,
-including fields added by the dictionary system. */
+including fields added by the dictionary system.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_fields(
/*====================*/
- /* out: number of fields */
- const dict_index_t* index) /* in: an internal
+ const dict_index_t* index) /*!< in: an internal
representation of index (in
the dictionary cache) */
{
@@ -449,17 +470,17 @@ dict_index_get_n_fields(
return(index->n_fields);
}
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index
that uniquely determine the position of an index entry in the index, if
we do not take multiversioning into account: in the B-tree use the value
-returned by dict_index_get_n_unique_in_tree. */
+returned by dict_index_get_n_unique_in_tree.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique(
/*====================*/
- /* out: number of fields */
- const dict_index_t* index) /* in: an internal representation
+ const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
ut_ad(index);
@@ -469,16 +490,16 @@ dict_index_get_n_unique(
return(index->n_uniq);
}
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index
which uniquely determine the position of an index entry in the index, if
-we also take multiversioning into account. */
+we also take multiversioning into account.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique_in_tree(
/*============================*/
- /* out: number of fields */
- const dict_index_t* index) /* in: an internal representation
+ const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
ut_ad(index);
@@ -493,32 +514,32 @@ dict_index_get_n_unique_in_tree(
return(dict_index_get_n_fields(index));
}
-/************************************************************************
+/********************************************************************//**
Gets the number of user-defined ordering fields in the index. In the internal
representation of clustered indexes we add the row id to the ordering fields
to make a clustered index unique, but this function returns the number of
-fields the user defined in the index as ordering fields. */
+fields the user defined in the index as ordering fields.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_ordering_defined_by_user(
/*======================================*/
- /* out: number of fields */
- const dict_index_t* index) /* in: an internal representation
+ const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
return(index->n_user_defined_cols);
}
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the nth field of an index. */
+/********************************************************************//**
+Gets the nth field of an index.
+@return pointer to field object */
UNIV_INLINE
dict_field_t*
dict_index_get_nth_field(
/*=====================*/
- /* out: pointer to field object */
- const dict_index_t* index, /* in: index */
- ulint pos) /* in: position of field */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos) /*!< in: position of field */
{
ut_ad(index);
ut_ad(pos < index->n_def);
@@ -528,16 +549,15 @@ dict_index_get_nth_field(
}
#endif /* UNIV_DEBUG */
-/************************************************************************
-Returns the position of a system column in an index. */
+/********************************************************************//**
+Returns the position of a system column in an index.
+@return position, ULINT_UNDEFINED if not contained */
UNIV_INLINE
ulint
dict_index_get_sys_col_pos(
/*=======================*/
- /* out: position,
- ULINT_UNDEFINED if not contained */
- const dict_index_t* index, /* in: index */
- ulint type) /* in: DATA_ROW_ID, ... */
+ const dict_index_t* index, /*!< in: index */
+ ulint type) /*!< in: DATA_ROW_ID, ... */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -554,53 +574,55 @@ dict_index_get_sys_col_pos(
index, dict_table_get_sys_col_no(index->table, type)));
}
-/*************************************************************************
-Gets the field column. */
+/*********************************************************************//**
+Gets the field column.
+@return field->col, pointer to the table column */
UNIV_INLINE
const dict_col_t*
dict_field_get_col(
/*===============*/
- const dict_field_t* field)
+ const dict_field_t* field) /*!< in: index field */
{
ut_ad(field);
return(field->col);
}
-/************************************************************************
-Gets pointer to the nth column in an index. */
+/********************************************************************//**
+Gets pointer to the nth column in an index.
+@return column */
UNIV_INLINE
const dict_col_t*
dict_index_get_nth_col(
/*===================*/
- /* out: column */
- const dict_index_t* index, /* in: index */
- ulint pos) /* in: position of the field */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos) /*!< in: position of the field */
{
return(dict_field_get_col(dict_index_get_nth_field(index, pos)));
}
-/************************************************************************
-Gets the column number the nth field in an index. */
+/********************************************************************//**
+Gets the column number the nth field in an index.
+@return column number */
UNIV_INLINE
ulint
dict_index_get_nth_col_no(
/*======================*/
- /* out: column number */
- const dict_index_t* index, /* in: index */
- ulint pos) /* in: position of the field */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos) /*!< in: position of the field */
{
return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
}
-/************************************************************************
-Returns the minimum data size of an index record. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Returns the minimum data size of an index record.
+@return minimum data size in bytes */
UNIV_INLINE
ulint
dict_index_get_min_size(
/*====================*/
- /* out: minimum data size in bytes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ulint n = dict_index_get_n_fields(index);
ulint size = 0;
@@ -613,14 +635,14 @@ dict_index_get_min_size(
return(size);
}
-/*************************************************************************
-Gets the space id of the root of the index tree. */
+/*********************************************************************//**
+Gets the space id of the root of the index tree.
+@return space id */
UNIV_INLINE
ulint
dict_index_get_space(
/*=================*/
- /* out: space id */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -628,14 +650,14 @@ dict_index_get_space(
return(index->space);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the space id of the root of the index tree. */
UNIV_INLINE
void
dict_index_set_space(
/*=================*/
- dict_index_t* index, /* in/out: index */
- ulint space) /* in: space id */
+ dict_index_t* index, /*!< in/out: index */
+ ulint space) /*!< in: space id */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -643,14 +665,14 @@ dict_index_set_space(
index->space = space;
}
-/*************************************************************************
-Gets the page number of the root of the index tree. */
+/*********************************************************************//**
+Gets the page number of the root of the index tree.
+@return page number */
UNIV_INLINE
ulint
dict_index_get_page(
/*================*/
- /* out: page number */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -658,14 +680,14 @@ dict_index_get_page(
return(index->page);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the page number of the root of index tree. */
UNIV_INLINE
void
dict_index_set_page(
/*================*/
- dict_index_t* index, /* in/out: index */
- ulint page) /* in: page number */
+ dict_index_t* index, /*!< in/out: index */
+ ulint page) /*!< in: page number */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -673,14 +695,14 @@ dict_index_set_page(
index->page = page;
}
-/*************************************************************************
-Gets the read-write lock of the index tree. */
+/*********************************************************************//**
+Gets the read-write lock of the index tree.
+@return read-write lock */
UNIV_INLINE
rw_lock_t*
dict_index_get_lock(
/*================*/
- /* out: read-write lock */
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -688,28 +710,27 @@ dict_index_get_lock(
return(&(index->lock));
}
-/************************************************************************
+/********************************************************************//**
Returns free space reserved for future updates of records. This is
relevant only in the case of many consecutive inserts, as updates
-which make the records bigger might fragment the index. */
+which make the records bigger might fragment the index.
+@return number of free bytes on page, reserved for updates */
UNIV_INLINE
ulint
dict_index_get_space_reserve(void)
/*==============================*/
- /* out: number of free bytes on page,
- reserved for updates */
{
return(UNIV_PAGE_SIZE / 16);
}
-/**************************************************************************
-Checks if a table is in the dictionary cache. */
+/**********************************************************************//**
+Checks if a table is in the dictionary cache.
+@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_check_if_in_cache_low(
/*=============================*/
- /* out: table, NULL if not found */
- const char* table_name) /* in: table name */
+ const char* table_name) /*!< in: table name */
{
dict_table_t* table;
ulint table_fold;
@@ -733,15 +754,15 @@ dict_table_check_if_in_cache_low(
return(table);
}
-/**************************************************************************
+/**********************************************************************//**
Gets a table; loads it to the dictionary cache if necessary. A low-level
-function. */
+function.
+@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_get_low(
/*===============*/
- /* out: table, NULL if not found */
- const char* table_name) /* in: table name */
+ const char* table_name) /*!< in: table name */
{
dict_table_t* table;
@@ -759,14 +780,14 @@ dict_table_get_low(
return(table);
}
-/**************************************************************************
-Returns a table object based on table id. */
+/**********************************************************************//**
+Returns a table object based on table id.
+@return table, NULL if does not exist */
UNIV_INLINE
dict_table_t*
dict_table_get_on_id_low(
/*=====================*/
- /* out: table, NULL if does not exist */
- dulint table_id) /* in: table id */
+ dulint table_id) /*!< in: table id */
{
dict_table_t* table;
ulint fold;
@@ -795,4 +816,4 @@ dict_table_get_on_id_low(
return(table);
}
-
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/dict0load.h b/storage/xtradb/include/dict0load.h
index 759cbcdb14a..60b8c1fb632 100644
--- a/storage/xtradb/include/dict0load.h
+++ b/storage/xtradb/include/dict0load.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0load.h
Loads to the memory cache database object definitions
from dictionary tables
@@ -31,7 +32,7 @@ Created 4/24/1996 Heikki Tuuri
#include "ut0byte.h"
#include "mem0mem.h"
-/************************************************************************
+/********************************************************************//**
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
to what we already read with fil_load_single_table_tablespaces().
@@ -43,42 +44,39 @@ UNIV_INTERN
void
dict_check_tablespaces_and_store_max_id(
/*====================================*/
- ibool in_crash_recovery); /* in: are we doing a crash recovery */
-/************************************************************************
-Finds the first table name in the given database. */
+ ibool in_crash_recovery); /*!< in: are we doing a crash recovery */
+/********************************************************************//**
+Finds the first table name in the given database.
+@return own: table name, NULL if does not exist; the caller must free
+the memory in the string! */
UNIV_INTERN
char*
dict_get_first_table_name_in_db(
/*============================*/
- /* out, own: table name, NULL if
- does not exist; the caller must free
- the memory in the string! */
- const char* name); /* in: database name which ends to '/' */
-/************************************************************************
+ const char* name); /*!< in: database name which ends to '/' */
+/********************************************************************//**
Loads a table definition and also all its index definitions, and also
the cluster definition if the table is a member in a cluster. Also loads
all foreign key constraints where the foreign key is in the table or where
-a foreign key references columns in this table. */
+a foreign key references columns in this table.
+@return table, NULL if does not exist; if the table is stored in an
+.ibd file, but the file does not exist, then we set the
+ibd_file_missing flag TRUE in the table object we return */
UNIV_INTERN
dict_table_t*
dict_load_table(
/*============*/
- /* out: table, NULL if does not exist;
- if the table is stored in an .ibd file,
- but the file does not exist,
- then we set the ibd_file_missing flag TRUE
- in the table object we return */
- const char* name); /* in: table name in the
+ const char* name); /*!< in: table name in the
databasename/tablename format */
-/***************************************************************************
-Loads a table object based on the table id. */
+/***********************************************************************//**
+Loads a table object based on the table id.
+@return table; NULL if table does not exist */
UNIV_INTERN
dict_table_t*
dict_load_table_on_id(
/*==================*/
- /* out: table; NULL if table does not exist */
- dulint table_id); /* in: table id */
-/************************************************************************
+ dulint table_id); /*!< in: table id */
+/********************************************************************//**
This function is called when the database is booted.
Loads system table index definitions except for the clustered index which
is added to the dictionary cache at booting before calling this function. */
@@ -86,24 +84,22 @@ UNIV_INTERN
void
dict_load_sys_table(
/*================*/
- dict_table_t* table); /* in: system table */
-#ifndef UNIV_HOTBACKUP
-/***************************************************************************
+ dict_table_t* table); /*!< in: system table */
+/***********************************************************************//**
Loads foreign key constraints where the table is either the foreign key
holder or where the table is referenced by a foreign key. Adds these
constraints to the data dictionary. Note that we know that the dictionary
cache already contains all constraints where the other relevant table is
-already in the dictionary cache. */
+already in the dictionary cache.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_load_foreigns(
/*===============*/
- /* out: DB_SUCCESS or error code */
- const char* table_name, /* in: table name */
- ibool check_charsets);/* in: TRUE=check charsets
+ const char* table_name, /*!< in: table name */
+ ibool check_charsets);/*!< in: TRUE=check charsets
compatibility */
-#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Prints to the standard output information on all tables found in the data
dictionary system table. */
UNIV_INTERN
diff --git a/storage/xtradb/include/dict0load.ic b/storage/xtradb/include/dict0load.ic
index 72eac2f621a..ccc16db165b 100644
--- a/storage/xtradb/include/dict0load.ic
+++ b/storage/xtradb/include/dict0load.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0load.ic
Loads to the memory cache database object definitions
from dictionary tables
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index e2b3cfa3679..2d001111938 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0mem.h
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri
@@ -31,107 +32,118 @@ Created 1/8/1996 Heikki Tuuri
#include "mem0mem.h"
#include "rem0types.h"
#include "btr0types.h"
+#ifndef UNIV_HOTBACKUP
+# include "lock0types.h"
+# include "que0types.h"
+# include "sync0rw.h"
+#endif /* !UNIV_HOTBACKUP */
#include "ut0mem.h"
#include "ut0lst.h"
#include "ut0rnd.h"
#include "ut0byte.h"
-#include "sync0rw.h"
-#include "lock0types.h"
#include "hash0hash.h"
-#include "que0types.h"
#include "trx0types.h"
-/* Type flags of an index: OR'ing of the flags is allowed to define a
+/** Type flags of an index: OR'ing of the flags is allowed to define a
combination of types */
-#define DICT_CLUSTERED 1 /* clustered index */
-#define DICT_UNIQUE 2 /* unique index */
-#define DICT_UNIVERSAL 4 /* index which can contain records from any
+/* @{ */
+#define DICT_CLUSTERED 1 /*!< clustered index */
+#define DICT_UNIQUE 2 /*!< unique index */
+#define DICT_UNIVERSAL 4 /*!< index which can contain records from any
other index */
-#define DICT_IBUF 8 /* insert buffer tree */
+#define DICT_IBUF 8 /*!< insert buffer tree */
+/* @} */
-/* Types for a table object */
-#define DICT_TABLE_ORDINARY 1
+/** Types for a table object */
+#define DICT_TABLE_ORDINARY 1 /*!< ordinary table */
#if 0 /* not implemented */
#define DICT_TABLE_CLUSTER_MEMBER 2
#define DICT_TABLE_CLUSTER 3 /* this means that the table is
really a cluster definition */
#endif
-/* Table flags. All unused bits must be 0. */
+/** Table flags. All unused bits must be 0. */
+/* @{ */
#define DICT_TF_COMPACT 1 /* Compact page format.
This must be set for
new file formats
(later than
DICT_TF_FORMAT_51). */
-/* compressed page size (0=uncompressed, up to 15 compressed sizes) */
+/** Compressed page size (0=uncompressed, up to 15 compressed sizes) */
+/* @{ */
#define DICT_TF_ZSSIZE_SHIFT 1
#define DICT_TF_ZSSIZE_MASK (15 << DICT_TF_ZSSIZE_SHIFT)
#define DICT_TF_ZSSIZE_MAX (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 1)
+/* @} */
-
+/** File format */
+/* @{ */
#define DICT_TF_FORMAT_SHIFT 5 /* file format */
#define DICT_TF_FORMAT_MASK (127 << DICT_TF_FORMAT_SHIFT)
-#define DICT_TF_FORMAT_51 0 /* InnoDB/MySQL up to 5.1 */
-#define DICT_TF_FORMAT_ZIP 1 /* InnoDB plugin for 5.1:
+#define DICT_TF_FORMAT_51 0 /*!< InnoDB/MySQL up to 5.1 */
+#define DICT_TF_FORMAT_ZIP 1 /*!< InnoDB plugin for 5.1:
compressed tables,
new BLOB treatment */
+/** Maximum supported file format */
#define DICT_TF_FORMAT_MAX DICT_TF_FORMAT_ZIP
-#define DICT_TF_BITS 6 /* number of flag bits */
+#define DICT_TF_BITS 6 /*!< number of flag bits */
#if (1 << (DICT_TF_BITS - DICT_TF_FORMAT_SHIFT)) <= DICT_TF_FORMAT_MAX
# error "DICT_TF_BITS is insufficient for DICT_TF_FORMAT_MAX"
#endif
+/* @} */
+/* @} */
-/**************************************************************************
-Creates a table memory object. */
+/**********************************************************************//**
+Creates a table memory object.
+@return own: table object */
UNIV_INTERN
dict_table_t*
dict_mem_table_create(
/*==================*/
- /* out, own: table object */
- const char* name, /* in: table name */
- ulint space, /* in: space where the clustered index
+ const char* name, /*!< in: table name */
+ ulint space, /*!< in: space where the clustered index
of the table is placed; this parameter
is ignored if the table is made
a member of a cluster */
- ulint n_cols, /* in: number of columns */
- ulint flags); /* in: table flags */
-/********************************************************************
+ ulint n_cols, /*!< in: number of columns */
+ ulint flags); /*!< in: table flags */
+/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
void
dict_mem_table_free(
/*================*/
- dict_table_t* table); /* in: table */
-/**************************************************************************
+ dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Adds a column definition to a table. */
UNIV_INTERN
void
dict_mem_table_add_col(
/*===================*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap, /* in: temporary memory heap, or NULL */
- const char* name, /* in: column name, or NULL */
- ulint mtype, /* in: main datatype */
- ulint prtype, /* in: precise type */
- ulint len); /* in: precision */
-/**************************************************************************
-Creates an index memory object. */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap, /*!< in: temporary memory heap, or NULL */
+ const char* name, /*!< in: column name, or NULL */
+ ulint mtype, /*!< in: main datatype */
+ ulint prtype, /*!< in: precise type */
+ ulint len); /*!< in: precision */
+/**********************************************************************//**
+Creates an index memory object.
+@return own: index object */
UNIV_INTERN
dict_index_t*
dict_mem_index_create(
/*==================*/
- /* out, own: index object */
- const char* table_name, /* in: table name */
- const char* index_name, /* in: index name */
- ulint space, /* in: space where the index tree is
+ const char* table_name, /*!< in: table name */
+ const char* index_name, /*!< in: index name */
+ ulint space, /*!< in: space where the index tree is
placed, ignored if the index is of
the clustered type */
- ulint type, /* in: DICT_UNIQUE,
+ ulint type, /*!< in: DICT_UNIQUE,
DICT_CLUSTERED, ... ORed */
- ulint n_fields); /* in: number of fields */
-/**************************************************************************
+ ulint n_fields); /*!< in: number of fields */
+/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
by the column name may be released only after publishing the index. */
@@ -139,33 +151,34 @@ UNIV_INTERN
void
dict_mem_index_add_field(
/*=====================*/
- dict_index_t* index, /* in: index */
- const char* name, /* in: column name */
- ulint prefix_len); /* in: 0 or the column prefix length
+ dict_index_t* index, /*!< in: index */
+ const char* name, /*!< in: column name */
+ ulint prefix_len); /*!< in: 0 or the column prefix length
in a MySQL index like
INDEX (textcol(25)) */
-/**************************************************************************
+/**********************************************************************//**
Frees an index memory object. */
UNIV_INTERN
void
dict_mem_index_free(
/*================*/
- dict_index_t* index); /* in: index */
-/**************************************************************************
-Creates and initializes a foreign constraint memory object. */
+ dict_index_t* index); /*!< in: index */
+/**********************************************************************//**
+Creates and initializes a foreign constraint memory object.
+@return own: foreign constraint struct */
UNIV_INTERN
dict_foreign_t*
dict_mem_foreign_create(void);
/*=========================*/
- /* out, own: foreign constraint struct */
-/* Data structure for a column in a table */
+/** Data structure for a column in a table */
struct dict_col_struct{
/*----------------------*/
- /* The following are copied from dtype_t,
+ /** The following are copied from dtype_t,
so that all bit-fields can be packed tightly. */
- unsigned mtype:8; /* main data type */
- unsigned prtype:24; /* precise type; MySQL data
+ /* @{ */
+ unsigned mtype:8; /*!< main data type */
+ unsigned prtype:24; /*!< precise type; MySQL data
type, charset code, flags to
indicate nullability,
signedness, whether this is a
@@ -175,7 +188,7 @@ struct dict_col_struct{
/* the remaining fields do not affect alphabetical ordering: */
- unsigned len:16; /* length; for MySQL data this
+ unsigned len:16; /*!< length; for MySQL data this
is field->pack_length(),
except that for a >= 5.0.3
type true VARCHAR this is the
@@ -184,258 +197,276 @@ struct dict_col_struct{
the string, MySQL uses 1 or 2
bytes to store the string length) */
- unsigned mbminlen:2; /* minimum length of a
+ unsigned mbminlen:2; /*!< minimum length of a
character, in bytes */
- unsigned mbmaxlen:3; /* maximum length of a
+ unsigned mbmaxlen:3; /*!< maximum length of a
character, in bytes */
/*----------------------*/
/* End of definitions copied from dtype_t */
+ /* @} */
- unsigned ind:10; /* table column position
+ unsigned ind:10; /*!< table column position
(starting from 0) */
- unsigned ord_part:1; /* nonzero if this column
+ unsigned ord_part:1; /*!< nonzero if this column
appears in the ordering fields
of an index */
};
-/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum
-indexed column length (or indexed prefix length). It is set to 3*256,
-so that one can create a column prefix index on 256 characters of a
-TEXT or VARCHAR column also in the UTF-8 charset. In that charset,
-a character may take at most 3 bytes.
-This constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
-files would be at risk! */
+/** @brief DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum
+indexed column length (or indexed prefix length).
+It is set to 3*256, so that one can create a column prefix index on
+256 characters of a TEXT or VARCHAR column also in the UTF-8
+charset. In that charset, a character may take at most 3 bytes. This
+constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
+files would be at risk! */
#define DICT_MAX_INDEX_COL_LEN REC_MAX_INDEX_COL_LEN
-/* Data structure for a field in an index */
+/** Data structure for a field in an index */
struct dict_field_struct{
- dict_col_t* col; /* pointer to the table column */
- const char* name; /* name of the column */
- unsigned prefix_len:10; /* 0 or the length of the column
+ dict_col_t* col; /*!< pointer to the table column */
+ const char* name; /*!< name of the column */
+ unsigned prefix_len:10; /*!< 0 or the length of the column
prefix in bytes in a MySQL index of
type, e.g., INDEX (textcol(25));
must be smaller than
DICT_MAX_INDEX_COL_LEN; NOTE that
in the UTF-8 charset, MySQL sets this
to 3 * the prefix len in UTF-8 chars */
- unsigned fixed_len:10; /* 0 or the fixed length of the
+ unsigned fixed_len:10; /*!< 0 or the fixed length of the
column if smaller than
DICT_MAX_INDEX_COL_LEN */
};
-/* Data structure for an index. Most fields will be
+/** Data structure for an index. Most fields will be
initialized to 0, NULL or FALSE in dict_mem_index_create(). */
struct dict_index_struct{
- dulint id; /* id of the index */
- mem_heap_t* heap; /* memory heap */
- const char* name; /* index name */
- const char* table_name; /* table name */
- dict_table_t* table; /* back pointer to table */
+ dulint id; /*!< id of the index */
+ mem_heap_t* heap; /*!< memory heap */
+ const char* name; /*!< index name */
+ const char* table_name;/*!< table name */
+ dict_table_t* table; /*!< back pointer to table */
+#ifndef UNIV_HOTBACKUP
unsigned space:32;
- /* space where the index tree is placed */
- unsigned page:32;/* index tree root page number */
- unsigned type:4; /* index type (DICT_CLUSTERED, DICT_UNIQUE,
+ /*!< space where the index tree is placed */
+ unsigned page:32;/*!< index tree root page number */
+#endif /* !UNIV_HOTBACKUP */
+ unsigned type:4; /*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
DICT_UNIVERSAL, DICT_IBUF) */
- unsigned trx_id_offset:10;/* position of the trx id column
+ unsigned trx_id_offset:10;/*!< position of the trx id column
in a clustered index record, if the fields
before it are known to be of a fixed size,
0 otherwise */
unsigned n_user_defined_cols:10;
- /* number of columns the user defined to
+ /*!< number of columns the user defined to
be in the index: in the internal
representation we add more columns */
- unsigned n_uniq:10;/* number of fields from the beginning
+ unsigned n_uniq:10;/*!< number of fields from the beginning
which are enough to determine an index
entry uniquely */
- unsigned n_def:10;/* number of fields defined so far */
- unsigned n_fields:10;/* number of fields in the index */
- unsigned n_nullable:10;/* number of nullable fields */
- unsigned cached:1;/* TRUE if the index object is in the
+ unsigned n_def:10;/*!< number of fields defined so far */
+ unsigned n_fields:10;/*!< number of fields in the index */
+ unsigned n_nullable:10;/*!< number of nullable fields */
+ unsigned cached:1;/*!< TRUE if the index object is in the
dictionary cache */
unsigned to_be_dropped:1;
- /* TRUE if this index is marked to be
+ /*!< TRUE if this index is marked to be
dropped in ha_innobase::prepare_drop_index(),
otherwise FALSE */
- dict_field_t* fields; /* array of field descriptions */
+ dict_field_t* fields; /*!< array of field descriptions */
+#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)
- indexes;/* list of indexes of the table */
- btr_search_t* search_info; /* info used in optimistic searches */
+ indexes;/*!< list of indexes of the table */
+ btr_search_t* search_info; /*!< info used in optimistic searches */
/*----------------------*/
+ /** Statistics for query optimization */
+ /* @{ */
ib_int64_t* stat_n_diff_key_vals;
- /* approximate number of different key values
- for this index, for each n-column prefix
- where n <= dict_get_n_unique(index); we
- periodically calculate new estimates */
+ /*!< approximate number of different
+ key values for this index, for each
+ n-column prefix where n <=
+ dict_get_n_unique(index); we
+ periodically calculate new
+ estimates */
ulint stat_index_size;
- /* approximate index size in database pages */
+ /*!< approximate index size in
+ database pages */
ulint stat_n_leaf_pages;
- /* approximate number of leaf pages in the
+ /*!< approximate number of leaf pages in the
index tree */
- rw_lock_t lock; /* read-write lock protecting the upper levels
- of the index tree */
-#ifdef ROW_MERGE_IS_INDEX_USABLE
- dulint trx_id; /* id of the transaction that created this
- index, or ut_dulint_zero if the index existed
+ /* @} */
+ rw_lock_t lock; /*!< read-write lock protecting the
+ upper levels of the index tree */
+ ib_uint64_t trx_id; /*!< id of the transaction that created this
+ index, or 0 if the index existed
when InnoDB was started up */
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
- ulint magic_n;/* magic number */
+ ulint magic_n;/*!< magic number */
+/** Value of dict_index_struct::magic_n */
# define DICT_INDEX_MAGIC_N 76789786
#endif
};
-/* Data structure for a foreign key constraint; an example:
+/** Data structure for a foreign key constraint; an example:
FOREIGN KEY (A, B) REFERENCES TABLE2 (C, D). Most fields will be
initialized to 0, NULL or FALSE in dict_mem_foreign_create(). */
-
struct dict_foreign_struct{
- mem_heap_t* heap; /* this object is allocated from
+ mem_heap_t* heap; /*!< this object is allocated from
this memory heap */
- char* id; /* id of the constraint as a
+ char* id; /*!< id of the constraint as a
null-terminated string */
- unsigned n_fields:10; /* number of indexes' first fields
- for which the the foreign key
+ unsigned n_fields:10; /*!< number of indexes' first fields
+ for which the foreign key
constraint is defined: we allow the
indexes to contain more fields than
mentioned in the constraint, as long
as the first fields are as mentioned */
- unsigned type:6; /* 0 or DICT_FOREIGN_ON_DELETE_CASCADE
+ unsigned type:6; /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE
or DICT_FOREIGN_ON_DELETE_SET_NULL */
- char* foreign_table_name;/* foreign table name */
- dict_table_t* foreign_table; /* table where the foreign key is */
- const char** foreign_col_names;/* names of the columns in the
+ char* foreign_table_name;/*!< foreign table name */
+ dict_table_t* foreign_table; /*!< table where the foreign key is */
+ const char** foreign_col_names;/*!< names of the columns in the
foreign key */
- char* referenced_table_name;/* referenced table name */
- dict_table_t* referenced_table;/* table where the referenced key
+ char* referenced_table_name;/*!< referenced table name */
+ dict_table_t* referenced_table;/*!< table where the referenced key
is */
- const char** referenced_col_names;/* names of the referenced
+ const char** referenced_col_names;/*!< names of the referenced
columns in the referenced table */
- dict_index_t* foreign_index; /* foreign index; we require that
+ dict_index_t* foreign_index; /*!< foreign index; we require that
both tables contain explicitly defined
indexes for the constraint: InnoDB
does not generate new indexes
implicitly */
- dict_index_t* referenced_index;/* referenced index */
+ dict_index_t* referenced_index;/*!< referenced index */
UT_LIST_NODE_T(dict_foreign_t)
- foreign_list; /* list node for foreign keys of the
+ foreign_list; /*!< list node for foreign keys of the
table */
UT_LIST_NODE_T(dict_foreign_t)
- referenced_list;/* list node for referenced keys of the
- table */
+ referenced_list;/*!< list node for referenced
+ keys of the table */
};
-/* The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
+/** The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
a foreign key constraint is enforced, therefore RESTRICT just means no flag */
-#define DICT_FOREIGN_ON_DELETE_CASCADE 1
-#define DICT_FOREIGN_ON_DELETE_SET_NULL 2
-#define DICT_FOREIGN_ON_UPDATE_CASCADE 4
-#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8
-#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16
-#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32
+/* @{ */
+#define DICT_FOREIGN_ON_DELETE_CASCADE 1 /*!< ON DELETE CASCADE */
+#define DICT_FOREIGN_ON_DELETE_SET_NULL 2 /*!< ON UPDATE SET NULL */
+#define DICT_FOREIGN_ON_UPDATE_CASCADE 4 /*!< ON DELETE CASCADE */
+#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8 /*!< ON UPDATE SET NULL */
+#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 /*!< ON DELETE NO ACTION */
+#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 /*!< ON UPDATE NO ACTION */
+/* @} */
-/* Data structure for a database table. Most fields will be
+/** Data structure for a database table. Most fields will be
initialized to 0, NULL or FALSE in dict_mem_table_create(). */
struct dict_table_struct{
- dulint id; /* id of the table */
- mem_heap_t* heap; /* memory heap */
- const char* name; /* table name */
- const char* dir_path_of_temp_table;/* NULL or the directory path
+ dulint id; /*!< id of the table */
+ mem_heap_t* heap; /*!< memory heap */
+ const char* name; /*!< table name */
+ const char* dir_path_of_temp_table;/*!< NULL or the directory path
where a TEMPORARY table that was explicitly
created by a user should be placed if
innodb_file_per_table is defined in my.cnf;
in Unix this is usually /tmp/..., in Windows
- \temp\... */
+ temp\... */
unsigned space:32;
- /* space where the clustered index of the
+ /*!< space where the clustered index of the
table is placed */
- unsigned flags:DICT_TF_BITS;/* DICT_TF_COMPACT, ... */
+ unsigned flags:DICT_TF_BITS;/*!< DICT_TF_COMPACT, ... */
unsigned ibd_file_missing:1;
- /* TRUE if this is in a single-table
+ /*!< TRUE if this is in a single-table
tablespace and the .ibd file is missing; then
we must return in ha_innodb.cc an error if the
user tries to query such an orphaned table */
unsigned tablespace_discarded:1;
- /* this flag is set TRUE when the user
+ /*!< this flag is set TRUE when the user
calls DISCARD TABLESPACE on this
table, and reset to FALSE in IMPORT
TABLESPACE */
- unsigned cached:1;/* TRUE if the table object has been added
+ unsigned cached:1;/*!< TRUE if the table object has been added
to the dictionary cache */
- unsigned n_def:10;/* number of columns defined so far */
- unsigned n_cols:10;/* number of columns */
- dict_col_t* cols; /* array of column descriptions */
+ unsigned n_def:10;/*!< number of columns defined so far */
+ unsigned n_cols:10;/*!< number of columns */
+ dict_col_t* cols; /*!< array of column descriptions */
const char* col_names;
- /* Column names packed in a character string
+ /*!< Column names packed in a character string
"name1\0name2\0...nameN\0". Until
the string contains n_cols, it will be
allocated from a temporary heap. The final
string will be allocated from table->heap. */
- hash_node_t name_hash; /* hash chain node */
- hash_node_t id_hash; /* hash chain node */
+#ifndef UNIV_HOTBACKUP
+ hash_node_t name_hash; /*!< hash chain node */
+ hash_node_t id_hash; /*!< hash chain node */
UT_LIST_BASE_NODE_T(dict_index_t)
- indexes; /* list of indexes of the table */
+ indexes; /*!< list of indexes of the table */
UT_LIST_BASE_NODE_T(dict_foreign_t)
- foreign_list;/* list of foreign key constraints
+ foreign_list;/*!< list of foreign key constraints
in the table; these refer to columns
in other tables */
UT_LIST_BASE_NODE_T(dict_foreign_t)
- referenced_list;/* list of foreign key constraints
+ referenced_list;/*!< list of foreign key constraints
which refer to this table */
UT_LIST_NODE_T(dict_table_t)
- table_LRU; /* node of the LRU list of tables */
+ table_LRU; /*!< node of the LRU list of tables */
ulint n_mysql_handles_opened;
- /* count of how many handles MySQL has opened
+ /*!< count of how many handles MySQL has opened
to this table; dropping of the table is
NOT allowed until this count gets to zero;
MySQL does NOT itself check the number of
open handles at drop */
ulint n_foreign_key_checks_running;
- /* count of how many foreign key check
+ /*!< count of how many foreign key check
operations are currently being performed
on the table: we cannot drop the table while
there are foreign key checks running on
it! */
- dulint query_cache_inv_trx_id;
- /* transactions whose trx id < than this
- number are not allowed to store to the MySQL
- query cache or retrieve from it; when a trx
- with undo logs commits, it sets this to the
- value of the trx id counter for the tables it
- had an IX lock on */
+ trx_id_t query_cache_inv_trx_id;
+ /*!< transactions whose trx id is
+ smaller than this number are not
+ allowed to store to the MySQL query
+ cache or retrieve from it; when a trx
+ with undo logs commits, it sets this
+ to the value of the trx id counter for
+ the tables it had an IX lock on */
UT_LIST_BASE_NODE_T(lock_t)
- locks; /* list of locks on the table */
+ locks; /*!< list of locks on the table */
#ifdef UNIV_DEBUG
/*----------------------*/
ibool does_not_fit_in_memory;
- /* this field is used to specify in simulations
- tables which are so big that disk should be
- accessed: disk access is simulated by
- putting the thread to sleep for a while;
- NOTE that this flag is not stored to the data
- dictionary on disk, and the database will
- forget about value TRUE if it has to reload
- the table definition from disk */
+ /*!< this field is used to specify in
+ simulations tables which are so big
+ that disk should be accessed: disk
+ access is simulated by putting the
+ thread to sleep for a while; NOTE that
+ this flag is not stored to the data
+ dictionary on disk, and the database
+ will forget about value TRUE if it has
+ to reload the table definition from
+ disk */
#endif /* UNIV_DEBUG */
/*----------------------*/
unsigned big_rows:1;
- /* flag: TRUE if the maximum length of
+ /*!< flag: TRUE if the maximum length of
a single row exceeds BIG_ROW_SIZE;
initialized in dict_table_add_to_cache() */
- unsigned stat_initialized:1; /* TRUE if statistics have
+ /** Statistics for query optimization */
+ /* @{ */
+ unsigned stat_initialized:1; /*!< TRUE if statistics have
been calculated the first time
after database startup or table creation */
ib_int64_t stat_n_rows;
- /* approximate number of rows in the table;
+ /*!< approximate number of rows in the table;
we periodically calculate new estimates */
ulint stat_clustered_index_size;
- /* approximate clustered index size in
+ /*!< approximate clustered index size in
database pages */
ulint stat_sum_of_other_index_sizes;
- /* other indexes in database pages */
+ /*!< other indexes in database pages */
ulint stat_modified_counter;
- /* when a row is inserted, updated, or deleted,
+ /*!< when a row is inserted, updated,
+ or deleted,
we add 1 to this number; we calculate new
estimates for the stat_... values for the
table and the indexes at an interval of 2 GB
@@ -446,8 +477,9 @@ struct dict_table_struct{
calculation; this counter is not protected by
any latch, because this is only used for
heuristics */
+ /* @} */
/*----------------------*/
- /* The following fields are used by the
+ /**!< The following fields are used by the
AUTOINC code. The actual collection of
tables locked during AUTOINC read/write is
kept in trx_t. In order to quickly determine
@@ -461,8 +493,9 @@ struct dict_table_struct{
corresponding lock instance is created on
the trx lock heap rather than use the
pre-allocated instance in autoinc_lock below.*/
+ /* @{ */
lock_t* autoinc_lock;
- /* a buffer for an AUTOINC lock
+ /*!< a buffer for an AUTOINC lock
for this table: we allocate the memory here
so that individual transactions can get it
and release it without a need to allocate
@@ -470,12 +503,12 @@ struct dict_table_struct{
otherwise the lock heap would grow rapidly
if we do a large insert from a select */
mutex_t autoinc_mutex;
- /* mutex protecting the autoincrement
+ /*!< mutex protecting the autoincrement
counter */
- ib_uint64_t autoinc;/* autoinc counter value to give to the
+ ib_uint64_t autoinc;/*!< autoinc counter value to give to the
next inserted row */
ulong n_waiting_or_granted_auto_inc_locks;
- /* This counter is used to track the number
+ /*!< This counter is used to track the number
of granted and pending autoinc locks on this
table. This value is set after acquiring the
kernel mutex but we peek the contents to
@@ -484,12 +517,15 @@ struct dict_table_struct{
only one transaction can be granted the
lock but there can be multiple waiters. */
const trx_t* autoinc_trx;
- /* The transaction that currently holds the
+ /*!< The transaction that currently holds the
the AUTOINC lock on this table. */
+ /* @} */
/*----------------------*/
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
- ulint magic_n;/* magic number */
+ ulint magic_n;/*!< magic number */
+/** Value of dict_table_struct::magic_n */
# define DICT_TABLE_MAGIC_N 76333786
#endif /* UNIV_DEBUG */
};
diff --git a/storage/xtradb/include/dict0mem.ic b/storage/xtradb/include/dict0mem.ic
index 6916393a9cd..c36adb07a18 100644
--- a/storage/xtradb/include/dict0mem.ic
+++ b/storage/xtradb/include/dict0mem.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/dict0mem.ic
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/dict0types.h b/storage/xtradb/include/dict0types.h
index b93e995e01b..7ad69193cc9 100644
--- a/storage/xtradb/include/dict0types.h
+++ b/storage/xtradb/include/dict0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0types.h
Data dictionary global types
Created 1/8/1996 Heikki Tuuri
@@ -25,8 +26,6 @@ Created 1/8/1996 Heikki Tuuri
#ifndef dict0types_h
#define dict0types_h
-#include "ut0list.h"
-
typedef struct dict_sys_struct dict_sys_t;
typedef struct dict_col_struct dict_col_t;
typedef struct dict_field_struct dict_field_t;
@@ -42,4 +41,8 @@ typedef dict_table_t dict_cluster_t;
typedef struct ind_node_struct ind_node_t;
typedef struct tab_node_struct tab_node_t;
+/* Space id and page no where the dictionary header resides */
+#define DICT_HDR_SPACE 0 /* the SYSTEM tablespace */
+#define DICT_HDR_PAGE_NO FSP_DICT_HDR_PAGE_NO
+
#endif
diff --git a/storage/xtradb/include/dyn0dyn.h b/storage/xtradb/include/dyn0dyn.h
index c06d6b88d2f..121a5946ac7 100644
--- a/storage/xtradb/include/dyn0dyn.h
+++ b/storage/xtradb/include/dyn0dyn.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dyn0dyn.h
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
@@ -29,148 +30,153 @@ Created 2/5/1996 Heikki Tuuri
#include "ut0lst.h"
#include "mem0mem.h"
+/** A block in a dynamically allocated array */
typedef struct dyn_block_struct dyn_block_t;
+/** Dynamically allocated array */
typedef dyn_block_t dyn_array_t;
-/* This is the initial 'payload' size of a dynamic array;
+/** This is the initial 'payload' size of a dynamic array;
this must be > MLOG_BUF_MARGIN + 30! */
#define DYN_ARRAY_DATA_SIZE 512
-/*************************************************************************
-Initializes a dynamic array. */
+/*********************************************************************//**
+Initializes a dynamic array.
+@return initialized dyn array */
UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
- /* out: initialized dyn array */
- dyn_array_t* arr); /* in: pointer to a memory buffer of
+ dyn_array_t* arr); /*!< in: pointer to a memory buffer of
size sizeof(dyn_array_t) */
-/****************************************************************
+/************************************************************//**
Frees a dynamic array. */
UNIV_INLINE
void
dyn_array_free(
/*===========*/
- dyn_array_t* arr); /* in: dyn array */
-/*************************************************************************
+ dyn_array_t* arr); /*!< in: dyn array */
+/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to a buffer in it.
After copying the elements, the caller must close the buffer using
-dyn_array_close. */
+dyn_array_close.
+@return pointer to the buffer */
UNIV_INLINE
byte*
dyn_array_open(
/*===========*/
- /* out: pointer to the buffer */
- dyn_array_t* arr, /* in: dynamic array */
- ulint size); /* in: size in bytes of the buffer; MUST be
+ dyn_array_t* arr, /*!< in: dynamic array */
+ ulint size); /*!< in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
-/*************************************************************************
+/*********************************************************************//**
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
void
dyn_array_close(
/*============*/
- dyn_array_t* arr, /* in: dynamic array */
- byte* ptr); /* in: buffer space from ptr up was not used */
-/*************************************************************************
+ dyn_array_t* arr, /*!< in: dynamic array */
+ byte* ptr); /*!< in: buffer space from ptr up was not used */
+/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to
the added element. The caller must copy the element to
-the pointer returned. */
+the pointer returned.
+@return pointer to the element */
UNIV_INLINE
void*
dyn_array_push(
/*===========*/
- /* out: pointer to the element */
- dyn_array_t* arr, /* in: dynamic array */
- ulint size); /* in: size in bytes of the element */
-/****************************************************************
-Returns pointer to an element in dyn array. */
+ dyn_array_t* arr, /*!< in: dynamic array */
+ ulint size); /*!< in: size in bytes of the element */
+/************************************************************//**
+Returns pointer to an element in dyn array.
+@return pointer to element */
UNIV_INLINE
void*
dyn_array_get_element(
/*==================*/
- /* out: pointer to element */
- dyn_array_t* arr, /* in: dyn array */
- ulint pos); /* in: position of element as bytes
+ dyn_array_t* arr, /*!< in: dyn array */
+ ulint pos); /*!< in: position of element as bytes
from array start */
-/****************************************************************
-Returns the size of stored data in a dyn array. */
+/************************************************************//**
+Returns the size of stored data in a dyn array.
+@return data size in bytes */
UNIV_INLINE
ulint
dyn_array_get_data_size(
/*====================*/
- /* out: data size in bytes */
- dyn_array_t* arr); /* in: dyn array */
-/****************************************************************
+ dyn_array_t* arr); /*!< in: dyn array */
+/************************************************************//**
Gets the first block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_first_block(
/*======================*/
- dyn_array_t* arr); /* in: dyn array */
-/****************************************************************
+ dyn_array_t* arr); /*!< in: dyn array */
+/************************************************************//**
Gets the last block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_last_block(
/*=====================*/
- dyn_array_t* arr); /* in: dyn array */
-/************************************************************************
-Gets the next block in a dyn array. */
+ dyn_array_t* arr); /*!< in: dyn array */
+/********************************************************************//**
+Gets the next block in a dyn array.
+@return pointer to next, NULL if end of list */
UNIV_INLINE
dyn_block_t*
dyn_array_get_next_block(
/*=====================*/
- /* out: pointer to next, NULL if end of list */
- dyn_array_t* arr, /* in: dyn array */
- dyn_block_t* block); /* in: dyn array block */
-/************************************************************************
-Gets the number of used bytes in a dyn array block. */
+ dyn_array_t* arr, /*!< in: dyn array */
+ dyn_block_t* block); /*!< in: dyn array block */
+/********************************************************************//**
+Gets the number of used bytes in a dyn array block.
+@return number of bytes used */
UNIV_INLINE
ulint
dyn_block_get_used(
/*===============*/
- /* out: number of bytes used */
- dyn_block_t* block); /* in: dyn array block */
-/************************************************************************
-Gets pointer to the start of data in a dyn array block. */
+ dyn_block_t* block); /*!< in: dyn array block */
+/********************************************************************//**
+Gets pointer to the start of data in a dyn array block.
+@return pointer to data */
UNIV_INLINE
byte*
dyn_block_get_data(
/*===============*/
- /* out: pointer to data */
- dyn_block_t* block); /* in: dyn array block */
-/************************************************************
+ dyn_block_t* block); /*!< in: dyn array block */
+/********************************************************//**
Pushes n bytes to a dyn array. */
UNIV_INLINE
void
dyn_push_string(
/*============*/
- dyn_array_t* arr, /* in: dyn array */
- const byte* str, /* in: string to write */
- ulint len); /* in: string length */
+ dyn_array_t* arr, /*!< in: dyn array */
+ const byte* str, /*!< in: string to write */
+ ulint len); /*!< in: string length */
/*#################################################################*/
-/* NOTE! Do not use the fields of the struct directly: the definition
+/** @brief A block in a dynamically allocated array.
+NOTE! Do not access the fields of the struct directly: the definition
appears here only for the compiler to know its size! */
struct dyn_block_struct{
- mem_heap_t* heap; /* in the first block this is != NULL
+ mem_heap_t* heap; /*!< in the first block this is != NULL
if dynamic allocation has been needed */
- ulint used; /* number of data bytes used in this block */
+ ulint used; /*!< number of data bytes used in this block;
+ DYN_BLOCK_FULL_FLAG is set when the block
+ becomes full */
byte data[DYN_ARRAY_DATA_SIZE];
- /* storage for array elements */
+ /*!< storage for array elements */
UT_LIST_BASE_NODE_T(dyn_block_t) base;
- /* linear list of dyn blocks: this node is
+ /*!< linear list of dyn blocks: this node is
used only in the first block */
UT_LIST_NODE_T(dyn_block_t) list;
- /* linear list node: used in all blocks */
+ /*!< linear list node: used in all blocks */
#ifdef UNIV_DEBUG
- ulint buf_end;/* only in the debug version: if dyn array is
- opened, this is the buffer end offset, else
- this is 0 */
- ulint magic_n;
+ ulint buf_end;/*!< only in the debug version: if dyn
+ array is opened, this is the buffer
+ end offset, else this is 0 */
+ ulint magic_n;/*!< magic number (DYN_BLOCK_MAGIC_N) */
#endif
};
diff --git a/storage/xtradb/include/dyn0dyn.ic b/storage/xtradb/include/dyn0dyn.ic
index 1ef8b284a99..110e674abff 100644
--- a/storage/xtradb/include/dyn0dyn.ic
+++ b/storage/xtradb/include/dyn0dyn.ic
@@ -16,43 +16,46 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dyn0dyn.ic
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
*******************************************************/
+/** Value of dyn_block_struct::magic_n */
#define DYN_BLOCK_MAGIC_N 375767
+/** Flag for dyn_block_struct::used that indicates a full block */
#define DYN_BLOCK_FULL_FLAG 0x1000000UL
-/****************************************************************
-Adds a new block to a dyn array. */
+/************************************************************//**
+Adds a new block to a dyn array.
+@return created block */
UNIV_INTERN
dyn_block_t*
dyn_array_add_block(
/*================*/
- /* out: created block */
- dyn_array_t* arr); /* in: dyn array */
+ dyn_array_t* arr); /*!< in: dyn array */
-/****************************************************************
+/************************************************************//**
Gets the first block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_first_block(
/*======================*/
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
return(arr);
}
-/****************************************************************
+/************************************************************//**
Gets the last block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_last_block(
/*=====================*/
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
if (arr->heap == NULL) {
@@ -62,15 +65,15 @@ dyn_array_get_last_block(
return(UT_LIST_GET_LAST(arr->base));
}
-/************************************************************************
-Gets the next block in a dyn array. */
+/********************************************************************//**
+Gets the next block in a dyn array.
+@return pointer to next, NULL if end of list */
UNIV_INLINE
dyn_block_t*
dyn_array_get_next_block(
/*=====================*/
- /* out: pointer to next, NULL if end of list */
- dyn_array_t* arr, /* in: dyn array */
- dyn_block_t* block) /* in: dyn array block */
+ dyn_array_t* arr, /*!< in: dyn array */
+ dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(arr && block);
@@ -83,42 +86,42 @@ dyn_array_get_next_block(
return(UT_LIST_GET_NEXT(list, block));
}
-/************************************************************************
-Gets the number of used bytes in a dyn array block. */
+/********************************************************************//**
+Gets the number of used bytes in a dyn array block.
+@return number of bytes used */
UNIV_INLINE
ulint
dyn_block_get_used(
/*===============*/
- /* out: number of bytes used */
- dyn_block_t* block) /* in: dyn array block */
+ dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(block);
return((block->used) & ~DYN_BLOCK_FULL_FLAG);
}
-/************************************************************************
-Gets pointer to the start of data in a dyn array block. */
+/********************************************************************//**
+Gets pointer to the start of data in a dyn array block.
+@return pointer to data */
UNIV_INLINE
byte*
dyn_block_get_data(
/*===============*/
- /* out: pointer to data */
- dyn_block_t* block) /* in: dyn array block */
+ dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(block);
return(block->data);
}
-/*************************************************************************
-Initializes a dynamic array. */
+/*********************************************************************//**
+Initializes a dynamic array.
+@return initialized dyn array */
UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
- /* out: initialized dyn array */
- dyn_array_t* arr) /* in: pointer to a memory buffer of
+ dyn_array_t* arr) /*!< in: pointer to a memory buffer of
size sizeof(dyn_array_t) */
{
ut_ad(arr);
@@ -136,13 +139,13 @@ dyn_array_create(
return(arr);
}
-/****************************************************************
+/************************************************************//**
Frees a dynamic array. */
UNIV_INLINE
void
dyn_array_free(
/*===========*/
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
if (arr->heap != NULL) {
mem_heap_free(arr->heap);
@@ -153,16 +156,16 @@ dyn_array_free(
#endif
}
-/*************************************************************************
+/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to the added element.
-The caller must copy the element to the pointer returned. */
+The caller must copy the element to the pointer returned.
+@return pointer to the element */
UNIV_INLINE
void*
dyn_array_push(
/*===========*/
- /* out: pointer to the element */
- dyn_array_t* arr, /* in: dynamic array */
- ulint size) /* in: size in bytes of the element */
+ dyn_array_t* arr, /*!< in: dynamic array */
+ ulint size) /*!< in: size in bytes of the element */
{
dyn_block_t* block;
ulint used;
@@ -193,17 +196,17 @@ dyn_array_push(
return((block->data) + used);
}
-/*************************************************************************
+/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to a buffer in it.
After copying the elements, the caller must close the buffer using
-dyn_array_close. */
+dyn_array_close.
+@return pointer to the buffer */
UNIV_INLINE
byte*
dyn_array_open(
/*===========*/
- /* out: pointer to the buffer */
- dyn_array_t* arr, /* in: dynamic array */
- ulint size) /* in: size in bytes of the buffer; MUST be
+ dyn_array_t* arr, /*!< in: dynamic array */
+ ulint size) /*!< in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
{
dyn_block_t* block;
@@ -239,14 +242,14 @@ dyn_array_open(
return((block->data) + used);
}
-/*************************************************************************
+/*********************************************************************//**
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
void
dyn_array_close(
/*============*/
- dyn_array_t* arr, /* in: dynamic array */
- byte* ptr) /* in: buffer space from ptr up was not used */
+ dyn_array_t* arr, /*!< in: dynamic array */
+ byte* ptr) /*!< in: buffer space from ptr up was not used */
{
dyn_block_t* block;
@@ -266,15 +269,15 @@ dyn_array_close(
#endif
}
-/****************************************************************
-Returns pointer to an element in dyn array. */
+/************************************************************//**
+Returns pointer to an element in dyn array.
+@return pointer to element */
UNIV_INLINE
void*
dyn_array_get_element(
/*==================*/
- /* out: pointer to element */
- dyn_array_t* arr, /* in: dyn array */
- ulint pos) /* in: position of element as bytes
+ dyn_array_t* arr, /*!< in: dyn array */
+ ulint pos) /*!< in: position of element as bytes
from array start */
{
dyn_block_t* block;
@@ -304,14 +307,14 @@ dyn_array_get_element(
return(block->data + pos);
}
-/****************************************************************
-Returns the size of stored data in a dyn array. */
+/************************************************************//**
+Returns the size of stored data in a dyn array.
+@return data size in bytes */
UNIV_INLINE
ulint
dyn_array_get_data_size(
/*====================*/
- /* out: data size in bytes */
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
dyn_block_t* block;
ulint sum = 0;
@@ -335,15 +338,15 @@ dyn_array_get_data_size(
return(sum);
}
-/************************************************************
+/********************************************************//**
Pushes n bytes to a dyn array. */
UNIV_INLINE
void
dyn_push_string(
/*============*/
- dyn_array_t* arr, /* in: dyn array */
- const byte* str, /* in: string to write */
- ulint len) /* in: string length */
+ dyn_array_t* arr, /*!< in: dyn array */
+ const byte* str, /*!< in: string to write */
+ ulint len) /*!< in: string length */
{
ulint n_copied;
diff --git a/storage/xtradb/include/eval0eval.h b/storage/xtradb/include/eval0eval.h
index 75cf9b38c3a..60aefd8d453 100644
--- a/storage/xtradb/include/eval0eval.h
+++ b/storage/xtradb/include/eval0eval.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/eval0eval.h
SQL evaluator: evaluates simple data structures, like expressions, in
a query graph
@@ -31,7 +32,7 @@ Created 12/29/1997 Heikki Tuuri
#include "pars0sym.h"
#include "pars0pars.h"
-/*********************************************************************
+/*****************************************************************//**
Free the buffer from global dynamic memory for a value of a que_node,
if it has been allocated in the above function. The freeing for pushed
column values is done in sel_col_prefetch_buf_free. */
@@ -39,71 +40,71 @@ UNIV_INTERN
void
eval_node_free_val_buf(
/*===================*/
- que_node_t* node); /* in: query graph node */
-/*********************************************************************
+ que_node_t* node); /*!< in: query graph node */
+/*****************************************************************//**
Evaluates a symbol table symbol. */
UNIV_INLINE
void
eval_sym(
/*=====*/
- sym_node_t* sym_node); /* in: symbol table node */
-/*********************************************************************
+ sym_node_t* sym_node); /*!< in: symbol table node */
+/*****************************************************************//**
Evaluates an expression. */
UNIV_INLINE
void
eval_exp(
/*=====*/
- que_node_t* exp_node); /* in: expression */
-/*********************************************************************
+ que_node_t* exp_node); /*!< in: expression */
+/*****************************************************************//**
Sets an integer value as the value of an expression node. */
UNIV_INLINE
void
eval_node_set_int_val(
/*==================*/
- que_node_t* node, /* in: expression node */
- lint val); /* in: value to set */
-/*********************************************************************
-Gets an integer value from an expression node. */
+ que_node_t* node, /*!< in: expression node */
+ lint val); /*!< in: value to set */
+/*****************************************************************//**
+Gets an integer value from an expression node.
+@return integer value */
UNIV_INLINE
lint
eval_node_get_int_val(
/*==================*/
- /* out: integer value */
- que_node_t* node); /* in: expression node */
-/*********************************************************************
+ que_node_t* node); /*!< in: expression node */
+/*****************************************************************//**
Copies a binary string value as the value of a query graph node. Allocates a
new buffer if necessary. */
UNIV_INLINE
void
eval_node_copy_and_alloc_val(
/*=========================*/
- que_node_t* node, /* in: query graph node */
- const byte* str, /* in: binary string */
- ulint len); /* in: string length or UNIV_SQL_NULL */
-/*********************************************************************
+ que_node_t* node, /*!< in: query graph node */
+ const byte* str, /*!< in: binary string */
+ ulint len); /*!< in: string length or UNIV_SQL_NULL */
+/*****************************************************************//**
Copies a query node value to another node. */
UNIV_INLINE
void
eval_node_copy_val(
/*===============*/
- que_node_t* node1, /* in: node to copy to */
- que_node_t* node2); /* in: node to copy from */
-/*********************************************************************
-Gets a iboolean value from a query node. */
+ que_node_t* node1, /*!< in: node to copy to */
+ que_node_t* node2); /*!< in: node to copy from */
+/*****************************************************************//**
+Gets a iboolean value from a query node.
+@return iboolean value */
UNIV_INLINE
ibool
eval_node_get_ibool_val(
/*====================*/
- /* out: iboolean value */
- que_node_t* node); /* in: query graph node */
-/*********************************************************************
-Evaluates a comparison node. */
+ que_node_t* node); /*!< in: query graph node */
+/*****************************************************************//**
+Evaluates a comparison node.
+@return the result of the comparison */
UNIV_INTERN
ibool
eval_cmp(
/*=====*/
- /* out: the result of the comparison */
- func_node_t* cmp_node); /* in: comparison node */
+ func_node_t* cmp_node); /*!< in: comparison node */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/eval0eval.ic b/storage/xtradb/include/eval0eval.ic
index a6330ae441f..fe767f39b00 100644
--- a/storage/xtradb/include/eval0eval.ic
+++ b/storage/xtradb/include/eval0eval.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/eval0eval.ic
SQL evaluator: evaluates simple data structures, like expressions, in
a query graph
@@ -27,41 +28,41 @@ Created 12/29/1997 Heikki Tuuri
#include "rem0cmp.h"
#include "pars0grm.h"
-/*********************************************************************
+/*****************************************************************//**
Evaluates a function node. */
UNIV_INTERN
void
eval_func(
/*======*/
- func_node_t* func_node); /* in: function node */
-/*********************************************************************
+ func_node_t* func_node); /*!< in: function node */
+/*****************************************************************//**
Allocate a buffer from global dynamic memory for a value of a que_node.
NOTE that this memory must be explicitly freed when the query graph is
freed. If the node already has allocated buffer, that buffer is freed
here. NOTE that this is the only function where dynamic memory should be
-allocated for a query node val field. */
+allocated for a query node val field.
+@return pointer to allocated buffer */
UNIV_INTERN
byte*
eval_node_alloc_val_buf(
/*====================*/
- /* out: pointer to allocated buffer */
- que_node_t* node, /* in: query graph node; sets the val field
+ que_node_t* node, /*!< in: query graph node; sets the val field
data field to point to the new buffer, and
len field equal to size */
- ulint size); /* in: buffer size */
+ ulint size); /*!< in: buffer size */
-/*********************************************************************
-Allocates a new buffer if needed. */
+/*****************************************************************//**
+Allocates a new buffer if needed.
+@return pointer to buffer */
UNIV_INLINE
byte*
eval_node_ensure_val_buf(
/*=====================*/
- /* out: pointer to buffer */
- que_node_t* node, /* in: query graph node; sets the val field
+ que_node_t* node, /*!< in: query graph node; sets the val field
data field to point to the new buffer, and
len field equal to size */
- ulint size) /* in: buffer size */
+ ulint size) /*!< in: buffer size */
{
dfield_t* dfield;
byte* data;
@@ -79,13 +80,13 @@ eval_node_ensure_val_buf(
return(data);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a symbol table symbol. */
UNIV_INLINE
void
eval_sym(
/*=====*/
- sym_node_t* sym_node) /* in: symbol table node */
+ sym_node_t* sym_node) /*!< in: symbol table node */
{
ut_ad(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
@@ -99,13 +100,13 @@ eval_sym(
}
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates an expression. */
UNIV_INLINE
void
eval_exp(
/*=====*/
- que_node_t* exp_node) /* in: expression */
+ que_node_t* exp_node) /*!< in: expression */
{
if (que_node_get_type(exp_node) == QUE_NODE_SYMBOL) {
@@ -117,14 +118,14 @@ eval_exp(
eval_func(exp_node);
}
-/*********************************************************************
+/*****************************************************************//**
Sets an integer value as the value of an expression node. */
UNIV_INLINE
void
eval_node_set_int_val(
/*==================*/
- que_node_t* node, /* in: expression node */
- lint val) /* in: value to set */
+ que_node_t* node, /*!< in: expression node */
+ lint val) /*!< in: value to set */
{
dfield_t* dfield;
byte* data;
@@ -142,14 +143,14 @@ eval_node_set_int_val(
mach_write_to_4(data, (ulint)val);
}
-/*********************************************************************
-Gets an integer non-SQL null value from an expression node. */
+/*****************************************************************//**
+Gets an integer non-SQL null value from an expression node.
+@return integer value */
UNIV_INLINE
lint
eval_node_get_int_val(
/*==================*/
- /* out: integer value */
- que_node_t* node) /* in: expression node */
+ que_node_t* node) /*!< in: expression node */
{
dfield_t* dfield;
@@ -160,14 +161,14 @@ eval_node_get_int_val(
return((int)mach_read_from_4(dfield_get_data(dfield)));
}
-/*********************************************************************
-Gets a iboolean value from a query node. */
+/*****************************************************************//**
+Gets a iboolean value from a query node.
+@return iboolean value */
UNIV_INLINE
ibool
eval_node_get_ibool_val(
/*====================*/
- /* out: iboolean value */
- que_node_t* node) /* in: query graph node */
+ que_node_t* node) /*!< in: query graph node */
{
dfield_t* dfield;
byte* data;
@@ -181,14 +182,14 @@ eval_node_get_ibool_val(
return(mach_read_from_1(data));
}
-/*********************************************************************
+/*****************************************************************//**
Sets a iboolean value as the value of a function node. */
UNIV_INLINE
void
eval_node_set_ibool_val(
/*====================*/
- func_node_t* func_node, /* in: function node */
- ibool val) /* in: value to set */
+ func_node_t* func_node, /*!< in: function node */
+ ibool val) /*!< in: value to set */
{
dfield_t* dfield;
byte* data;
@@ -208,16 +209,16 @@ eval_node_set_ibool_val(
mach_write_to_1(data, val);
}
-/*********************************************************************
+/*****************************************************************//**
Copies a binary string value as the value of a query graph node. Allocates a
new buffer if necessary. */
UNIV_INLINE
void
eval_node_copy_and_alloc_val(
/*=========================*/
- que_node_t* node, /* in: query graph node */
- const byte* str, /* in: binary string */
- ulint len) /* in: string length or UNIV_SQL_NULL */
+ que_node_t* node, /*!< in: query graph node */
+ const byte* str, /*!< in: binary string */
+ ulint len) /*!< in: string length or UNIV_SQL_NULL */
{
byte* data;
@@ -232,14 +233,14 @@ eval_node_copy_and_alloc_val(
ut_memcpy(data, str, len);
}
-/*********************************************************************
+/*****************************************************************//**
Copies a query node value to another node. */
UNIV_INLINE
void
eval_node_copy_val(
/*===============*/
- que_node_t* node1, /* in: node to copy to */
- que_node_t* node2) /* in: node to copy from */
+ que_node_t* node1, /*!< in: node to copy to */
+ que_node_t* node2) /*!< in: node to copy from */
{
dfield_t* dfield2;
diff --git a/storage/xtradb/include/eval0proc.h b/storage/xtradb/include/eval0proc.h
index 58937c18124..13e2e365320 100644
--- a/storage/xtradb/include/eval0proc.h
+++ b/storage/xtradb/include/eval0proc.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/eval0proc.h
Executes SQL stored procedures and their control structures
Created 1/20/1998 Heikki Tuuri
@@ -30,70 +31,70 @@ Created 1/20/1998 Heikki Tuuri
#include "pars0sym.h"
#include "pars0pars.h"
-/**************************************************************************
-Performs an execution step of a procedure node. */
+/**********************************************************************//**
+Performs an execution step of a procedure node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
proc_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of an if-statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of an if-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
if_step(
/*====*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of a while-statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of a while-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
while_step(
/*=======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of a for-loop node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of a for-loop node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
for_step(
/*=====*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of an assignment statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of an assignment statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
assign_step(
/*========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of a procedure call node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of a procedure call node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
proc_eval_step(
/*===========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of an exit statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of an exit statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
exit_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of a return-statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of a return-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
return_step(
/*========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/eval0proc.ic b/storage/xtradb/include/eval0proc.ic
index 6bd978ad3fc..c602af0a694 100644
--- a/storage/xtradb/include/eval0proc.ic
+++ b/storage/xtradb/include/eval0proc.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/eval0proc.ic
Executes SQL stored procedures and their control structures
Created 1/20/1998 Heikki Tuuri
@@ -26,14 +27,14 @@ Created 1/20/1998 Heikki Tuuri
#include "que0que.h"
#include "eval0eval.h"
-/**************************************************************************
-Performs an execution step of a procedure node. */
+/**********************************************************************//**
+Performs an execution step of a procedure node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
proc_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
proc_node_t* node;
@@ -61,14 +62,14 @@ proc_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of a procedure call node. */
+/**********************************************************************//**
+Performs an execution step of a procedure call node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
proc_eval_step(
/*===========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
func_node_t* node;
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 587e5ee48a8..805948f5b5d 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/fil0fil.h
The low-level file system
Created 10/25/1995 Heikki Tuuri
@@ -26,58 +27,62 @@ Created 10/25/1995 Heikki Tuuri
#define fil0fil_h
#include "univ.i"
+#ifndef UNIV_HOTBACKUP
#include "sync0rw.h"
+#endif /* !UNIV_HOTBACKUP */
#include "dict0types.h"
#include "ut0byte.h"
#include "os0file.h"
-/* When mysqld is run, the default directory "." is the mysqld datadir, but in
-ibbackup we must set it explicitly; the patgh must NOT contain the trailing
-'/' or '\' */
+/** When mysqld is run, the default directory "." is the mysqld datadir,
+but in the MySQL Embedded Server Library and ibbackup it is not the default
+directory, and we must set the base file path explicitly */
extern const char* fil_path_to_mysql_datadir;
-/* Initial size of a single-table tablespace in pages */
+/** Initial size of a single-table tablespace in pages */
#define FIL_IBD_FILE_INITIAL_SIZE 4
-/* 'null' (undefined) page offset in the context of file spaces */
+/** 'null' (undefined) page offset in the context of file spaces */
#define FIL_NULL ULINT32_UNDEFINED
/* Space address data type; this is intended to be used when
addresses accurate to a byte are stored in file pages. If the page part
of the address is FIL_NULL, the address is considered undefined. */
-typedef byte fil_faddr_t; /* 'type' definition in C: an address
+typedef byte fil_faddr_t; /*!< 'type' definition in C: an address
stored in a file page is a string of bytes */
#define FIL_ADDR_PAGE 0 /* first in address is the page offset */
#define FIL_ADDR_BYTE 4 /* then comes 2-byte byte offset within page*/
#define FIL_ADDR_SIZE 6 /* address size is 6 bytes */
-/* A struct for storing a space address FIL_ADDR, when it is used
+/** A struct for storing a space address FIL_ADDR, when it is used
in C program data structures. */
typedef struct fil_addr_struct fil_addr_t;
+/** File space address */
struct fil_addr_struct{
- ulint page; /* page number within a space */
- ulint boffset; /* byte offset within the page */
+ ulint page; /*!< page number within a space */
+ ulint boffset; /*!< byte offset within the page */
};
-/* Null file address */
+/** The null file address */
extern fil_addr_t fil_addr_null;
-/* The byte offsets on a file page for various variables */
-#define FIL_PAGE_SPACE_OR_CHKSUM 0 /* in < MySQL-4.0.14 space id the
+/** The byte offsets on a file page for various variables @{ */
+#define FIL_PAGE_SPACE_OR_CHKSUM 0 /*!< in < MySQL-4.0.14 space id the
page belongs to (== 0) but in later
versions the 'new' checksum of the
page */
-#define FIL_PAGE_OFFSET 4 /* page offset inside space */
-#define FIL_PAGE_PREV 8 /* if there is a 'natural' predecessor
- of the page, its offset.
- Otherwise FIL_NULL.
- This field is not set on BLOB pages,
- which are stored as a singly-linked
- list. See also FIL_PAGE_NEXT. */
-#define FIL_PAGE_NEXT 12 /* if there is a 'natural' successor
+#define FIL_PAGE_OFFSET 4 /*!< page offset inside space */
+#define FIL_PAGE_PREV 8 /*!< if there is a 'natural'
+ predecessor of the page, its
+ offset. Otherwise FIL_NULL.
+ This field is not set on BLOB
+ pages, which are stored as a
+ singly-linked list. See also
+ FIL_PAGE_NEXT. */
+#define FIL_PAGE_NEXT 12 /*!< if there is a 'natural' successor
of the page, its offset.
Otherwise FIL_NULL.
B-tree index pages
@@ -87,9 +92,9 @@ extern fil_addr_t fil_addr_null;
FIL_PAGE_PREV and FIL_PAGE_NEXT
in the collation order of the
smallest user record on each page. */
-#define FIL_PAGE_LSN 16 /* lsn of the end of the newest
+#define FIL_PAGE_LSN 16 /*!< lsn of the end of the newest
modification log record to the page */
-#define FIL_PAGE_TYPE 24 /* file page type: FIL_PAGE_INDEX,...,
+#define FIL_PAGE_TYPE 24 /*!< file page type: FIL_PAGE_INDEX,...,
2 bytes.
The contents of this field can only
@@ -104,167 +109,172 @@ extern fil_addr_t fil_addr_null;
MySQL/InnoDB 5.1.7 or later, the
contents of this field is valid
for all uncompressed pages. */
-#define FIL_PAGE_FILE_FLUSH_LSN 26 /* this is only defined for the
+#define FIL_PAGE_FILE_FLUSH_LSN 26 /*!< this is only defined for the
first page in a data file: the file
has been flushed to disk at least up
to this lsn */
-#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /* starting from 4.1.x this
+#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
contains the space id of the page */
-#define FIL_PAGE_DATA 38 /* start of the data on the page */
-
-/* File page trailer */
-#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /* the low 4 bytes of this are used
+#define FIL_PAGE_DATA 38 /*!< start of the data on the page */
+/* @} */
+/** File page trailer @{ */
+#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /*!< the low 4 bytes of this are used
to store the page checksum, the
last 4 bytes should be identical
to the last 4 bytes of FIL_PAGE_LSN */
-#define FIL_PAGE_DATA_END 8
-
-/* File page types (values of FIL_PAGE_TYPE) */
-#define FIL_PAGE_INDEX 17855 /* B-tree node */
-#define FIL_PAGE_UNDO_LOG 2 /* Undo log page */
-#define FIL_PAGE_INODE 3 /* Index node */
-#define FIL_PAGE_IBUF_FREE_LIST 4 /* Insert buffer free list */
+#define FIL_PAGE_DATA_END 8 /*!< size of the page trailer */
+/* @} */
+
+/** File page types (values of FIL_PAGE_TYPE) @{ */
+#define FIL_PAGE_INDEX 17855 /*!< B-tree node */
+#define FIL_PAGE_UNDO_LOG 2 /*!< Undo log page */
+#define FIL_PAGE_INODE 3 /*!< Index node */
+#define FIL_PAGE_IBUF_FREE_LIST 4 /*!< Insert buffer free list */
/* File page types introduced in MySQL/InnoDB 5.1.7 */
-#define FIL_PAGE_TYPE_ALLOCATED 0 /* Freshly allocated page */
-#define FIL_PAGE_IBUF_BITMAP 5 /* Insert buffer bitmap */
-#define FIL_PAGE_TYPE_SYS 6 /* System page */
-#define FIL_PAGE_TYPE_TRX_SYS 7 /* Transaction system data */
-#define FIL_PAGE_TYPE_FSP_HDR 8 /* File space header */
-#define FIL_PAGE_TYPE_XDES 9 /* Extent descriptor page */
-#define FIL_PAGE_TYPE_BLOB 10 /* Uncompressed BLOB page */
-#define FIL_PAGE_TYPE_ZBLOB 11 /* First compressed BLOB page */
-#define FIL_PAGE_TYPE_ZBLOB2 12 /* Subsequent compressed BLOB page */
-
-/* Space types */
-#define FIL_TABLESPACE 501
-#define FIL_LOG 502
-
+#define FIL_PAGE_TYPE_ALLOCATED 0 /*!< Freshly allocated page */
+#define FIL_PAGE_IBUF_BITMAP 5 /*!< Insert buffer bitmap */
+#define FIL_PAGE_TYPE_SYS 6 /*!< System page */
+#define FIL_PAGE_TYPE_TRX_SYS 7 /*!< Transaction system data */
+#define FIL_PAGE_TYPE_FSP_HDR 8 /*!< File space header */
+#define FIL_PAGE_TYPE_XDES 9 /*!< Extent descriptor page */
+#define FIL_PAGE_TYPE_BLOB 10 /*!< Uncompressed BLOB page */
+#define FIL_PAGE_TYPE_ZBLOB 11 /*!< First compressed BLOB page */
+#define FIL_PAGE_TYPE_ZBLOB2 12 /*!< Subsequent compressed BLOB page */
+/* @} */
+
+/** Space types @{ */
+#define FIL_TABLESPACE 501 /*!< tablespace */
+#define FIL_LOG 502 /*!< redo log */
+/* @} */
+
+/** The number of fsyncs done to the log */
extern ulint fil_n_log_flushes;
+/** Number of pending redo log flushes */
extern ulint fil_n_pending_log_flushes;
+/** Number of pending tablespace flushes */
extern ulint fil_n_pending_tablespace_flushes;
-/***********************************************************************
-Returns the version number of a tablespace, -1 if not found. */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Returns the version number of a tablespace, -1 if not found.
+@return version number, -1 if the tablespace does not exist in the
+memory cache */
UNIV_INTERN
ib_int64_t
fil_space_get_version(
/*==================*/
- /* out: version number, -1 if the tablespace does not
- exist in the memory cache */
- ulint id); /* in: space id */
-/***********************************************************************
-Returns the latch of a file space. */
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
+Returns the latch of a file space.
+@return latch protecting storage allocation */
UNIV_INTERN
rw_lock_t*
fil_space_get_latch(
/*================*/
- /* out: latch protecting storage allocation */
- ulint id, /* in: space id */
- ulint* zip_size);/* out: compressed page size, or
+ ulint id, /*!< in: space id */
+ ulint* zip_size);/*!< out: compressed page size, or
0 for uncompressed tablespaces */
-/***********************************************************************
-Returns the type of a file space. */
+/*******************************************************************//**
+Returns the type of a file space.
+@return FIL_TABLESPACE or FIL_LOG */
UNIV_INTERN
ulint
fil_space_get_type(
/*===============*/
- /* out: FIL_TABLESPACE or FIL_LOG */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
Appends a new file to the chain of files of a space. File must be closed. */
UNIV_INTERN
void
fil_node_create(
/*============*/
- const char* name, /* in: file name (file must be closed) */
- ulint size, /* in: file size in database blocks, rounded
+ const char* name, /*!< in: file name (file must be closed) */
+ ulint size, /*!< in: file size in database blocks, rounded
downwards to an integer */
- ulint id, /* in: space id where to append */
- ibool is_raw);/* in: TRUE if a raw device or
+ ulint id, /*!< in: space id where to append */
+ ibool is_raw);/*!< in: TRUE if a raw device or
a raw disk partition */
#ifdef UNIV_LOG_ARCHIVE
-/********************************************************************
+/****************************************************************//**
Drops files from the start of a file space, so that its size is cut by
the amount given. */
UNIV_INTERN
void
fil_space_truncate_start(
/*=====================*/
- ulint id, /* in: space id */
- ulint trunc_len); /* in: truncate by this much; it is an error
+ ulint id, /*!< in: space id */
+ ulint trunc_len); /*!< in: truncate by this much; it is an error
if this does not equal to the combined size of
some initial files in the space */
#endif /* UNIV_LOG_ARCHIVE */
-/***********************************************************************
+/*******************************************************************//**
Creates a space memory object and puts it to the 'fil system' hash table. If
-there is an error, prints an error message to the .err log. */
+there is an error, prints an error message to the .err log.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_space_create(
/*=============*/
- /* out: TRUE if success */
- const char* name, /* in: space name */
- ulint id, /* in: space id */
- ulint zip_size,/* in: compressed page size, or
+ const char* name, /*!< in: space name */
+ ulint id, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or
0 for uncompressed tablespaces */
- ulint purpose);/* in: FIL_TABLESPACE, or FIL_LOG if log */
-/***********************************************************************
-Frees a space object from a the tablespace memory cache. Closes the files in
-the chain but does not delete them. */
-UNIV_INTERN
-ibool
-fil_space_free(
-/*===========*/
- /* out: TRUE if success */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint purpose);/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
+/*******************************************************************//**
Returns the size of the space in pages. The tablespace must be cached in the
-memory cache. */
+memory cache.
+@return space size, 0 if space not found */
UNIV_INTERN
ulint
fil_space_get_size(
/*===============*/
- /* out: space size, 0 if space not found */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
Returns the flags of the space. The tablespace must be cached
-in the memory cache. */
+in the memory cache.
+@return flags, ULINT_UNDEFINED if space not found */
UNIV_INTERN
ulint
fil_space_get_flags(
/*================*/
- /* out: flags, ULINT_UNDEFINED if space not found */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
Returns the compressed page size of the space, or 0 if the space
-is not compressed. The tablespace must be cached in the memory cache. */
+is not compressed. The tablespace must be cached in the memory cache.
+@return compressed page size, ULINT_UNDEFINED if space not found */
UNIV_INTERN
ulint
fil_space_get_zip_size(
/*===================*/
- /* out: compressed page size, ULINT_UNDEFINED
- if space not found */
- ulint id); /* in: space id */
-/***********************************************************************
+ 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. */
+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(
/*===========================*/
- /* out: TRUE if the address is meaningful */
- ulint id, /* in: space id */
- ulint page_no);/* in: page number */
-/********************************************************************
+ ulint id, /*!< in: space id */
+ ulint page_no);/*!< in: page number */
+/****************************************************************//**
Initializes the tablespace memory cache. */
UNIV_INTERN
void
fil_init(
/*=====*/
- ulint max_n_open); /* in: max number of open files */
-/***********************************************************************
+ ulint hash_size, /*!< in: hash table size */
+ ulint max_n_open); /*!< in: max number of open files */
+/*******************************************************************//**
+Initializes the tablespace memory cache. */
+UNIV_INTERN
+void
+fil_close(void);
+/*===========*/
+/*******************************************************************//**
Opens all log files and system tablespace data files. They stay open until the
database server shutdown. This should be called at a server startup after the
space objects for the log and the system tablespace have been created. The
@@ -274,67 +284,68 @@ UNIV_INTERN
void
fil_open_log_and_system_tablespace_files(void);
/*==========================================*/
-/***********************************************************************
+/*******************************************************************//**
Closes all open files. There must not be any pending i/o's or not flushed
modifications in the files. */
UNIV_INTERN
void
fil_close_all_files(void);
/*=====================*/
-/***********************************************************************
+/*******************************************************************//**
Sets the max tablespace id counter if the given number is bigger than the
previous value. */
UNIV_INTERN
void
fil_set_max_space_id_if_bigger(
/*===========================*/
- ulint max_id);/* in: maximum known id */
-/********************************************************************
+ ulint max_id);/*!< in: maximum known id */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Writes the flushed lsn and the latest archived log number to the page
-header of the first page of each data file in the system tablespace. */
+header of the first page of each data file in the system tablespace.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
fil_write_flushed_lsn_to_data_files(
/*================================*/
- /* out: DB_SUCCESS or error number */
- ib_uint64_t lsn, /* in: lsn to write */
- ulint arch_log_no); /* in: latest archived log
+ ib_uint64_t lsn, /*!< in: lsn to write */
+ ulint arch_log_no); /*!< in: latest archived log
file number */
-/***********************************************************************
+/*******************************************************************//**
Reads the flushed lsn and arch no fields from a data file at database
startup. */
UNIV_INTERN
void
fil_read_flushed_lsn_and_arch_log_no(
/*=================================*/
- os_file_t data_file, /* in: open data file */
- ibool one_read_already, /* in: TRUE if min and max
+ os_file_t data_file, /*!< in: open data file */
+ ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
#ifdef UNIV_LOG_ARCHIVE
- ulint* min_arch_log_no, /* in/out: */
- ulint* max_arch_log_no, /* in/out: */
+ ulint* min_arch_log_no, /*!< in/out: */
+ ulint* max_arch_log_no, /*!< in/out: */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t* min_flushed_lsn, /* in/out: */
- ib_uint64_t* max_flushed_lsn); /* in/out: */
-/***********************************************************************
+ ib_uint64_t* min_flushed_lsn, /*!< in/out: */
+ ib_uint64_t* max_flushed_lsn); /*!< in/out: */
+/*******************************************************************//**
Increments the count of pending insert buffer page merges, if space is not
-being deleted. */
+being deleted.
+@return TRUE if being deleted, and ibuf merges should be skipped */
UNIV_INTERN
ibool
fil_inc_pending_ibuf_merges(
/*========================*/
- /* out: TRUE if being deleted, and ibuf merges should
- be skipped */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
Decrements the count of pending insert buffer page merges. */
UNIV_INTERN
void
fil_decr_pending_ibuf_merges(
/*=========================*/
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
Parses the body of a log record written about an .ibd file operation. That is,
the log record part after the standard (type, space id, page no) header of the
log record.
@@ -345,87 +356,91 @@ at that path does not exist yet. If the database directory for the file to be
created does not exist, then we create the directory, too.
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
-datadir that we should use in replaying the file operations. */
+datadir that we should use in replaying the file operations.
+@return end of log record, or NULL if the record was not completely
+contained between ptr and end_ptr */
UNIV_INTERN
byte*
fil_op_log_parse_or_replay(
/*=======================*/
- /* out: end of log record, or NULL if the
- record was not completely contained between
- ptr and end_ptr */
- byte* ptr, /* in: buffer containing the log record body,
+ byte* ptr, /*!< in: buffer containing the log record body,
or an initial segment of it, if the record does
not fir completely between ptr and end_ptr */
- byte* end_ptr, /* in: buffer end */
- ulint type, /* in: the type of this log record */
- ulint space_id); /* in: the space id of the tablespace in
+ byte* end_ptr, /*!< in: buffer end */
+ ulint type, /*!< in: the type of this log record */
+ ulint space_id, /*!< in: the space id of the tablespace in
question, or 0 if the log record should
only be parsed but not replayed */
-/***********************************************************************
+ ulint log_flags); /*!< in: redo log flags
+ (stored in the page number parameter) */
+/*******************************************************************//**
Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache. */
+memory cache.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_delete_tablespace(
/*==================*/
- /* out: TRUE if success */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Discards a single-table tablespace. The tablespace must be cached in the
memory cache. Discarding is like deleting a tablespace, but
1) we do not drop the table from the data dictionary;
2) we remove all insert buffer entries for the tablespace immediately; in DROP
TABLE they are only removed gradually in the background;
3) when the user does IMPORT TABLESPACE, the tablespace will have the same id
-as it originally had. */
+as it originally had.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_discard_tablespace(
/*===================*/
- /* out: TRUE if success */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
Renames a single-table tablespace. The tablespace must be cached in the
-tablespace memory cache. */
+tablespace memory cache.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_rename_tablespace(
/*==================*/
- /* out: TRUE if success */
- const char* old_name, /* in: old table name in the standard
+ const char* old_name, /*!< in: old table name in the standard
databasename/tablename format of
InnoDB, or NULL if we do the rename
based on the space id only */
- ulint id, /* in: space id */
- const char* new_name); /* in: new table name in the standard
+ ulint id, /*!< in: space id */
+ const char* new_name); /*!< in: new table name in the standard
databasename/tablename format
of InnoDB */
-/***********************************************************************
+/*******************************************************************//**
Creates a new single-table tablespace to a database directory of MySQL.
Database directories are under the 'datadir' of MySQL. The datadir is the
directory of a running mysqld program. We can refer to it by simply the
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
-dir of the mysqld server. */
+dir of the mysqld server.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
fil_create_new_single_table_tablespace(
/*===================================*/
- /* out: DB_SUCCESS or error code */
- ulint* space_id, /* in/out: space id; if this is != 0,
+ ulint* space_id, /*!< in/out: space id; if this is != 0,
then this is an input parameter,
otherwise output */
- const char* tablename, /* in: the table name in the usual
+ const char* tablename, /*!< in: the table name in the usual
databasename/tablename format
of InnoDB, or a dir path to a temp
table */
- ibool is_temp, /* in: TRUE if a table created with
+ ibool is_temp, /*!< in: TRUE if a table created with
CREATE TEMPORARY TABLE */
- ulint flags, /* in: tablespace flags */
- ulint size); /* in: the initial size of the
+ ulint flags, /*!< in: tablespace flags */
+ ulint size); /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
function is used to open a tablespace when we start up mysqld, and also in
@@ -433,24 +448,24 @@ IMPORT TABLESPACE.
NOTE that we assume this operation is used either at the database startup
or under the protection of the dictionary mutex, so that two users cannot
race here. This operation does not leave the file associated with the
-tablespace open, but closes it after we have looked at the space id in it. */
+tablespace open, but closes it after we have looked at the space id in it.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_open_single_table_tablespace(
/*=============================*/
- /* out: TRUE if success */
- ibool check_space_id, /* in: should we check that the space
+ ibool check_space_id, /*!< in: should we check that the space
id in the file is right; we assume
that this function runs much faster
if no check is made, since accessing
the file inode probably is much
faster (the OS caches them) than
accessing the first page of the file */
- ulint id, /* in: space id */
- ulint flags, /* in: tablespace flags */
- const char* name); /* in: table name in the
+ ulint id, /*!< in: space id */
+ ulint flags, /*!< in: tablespace flags */
+ const char* name); /*!< in: table name in the
databasename/tablename format */
-/************************************************************************
+/********************************************************************//**
It is possible, though very improbable, that the lsn's in the tablespace to be
imported have risen above the current system lsn, if a lengthy purge, ibuf
merge, or rollback was performed on a backup taken with ibbackup. If that is
@@ -458,30 +473,31 @@ the case, reset page lsn's in the file. We assume that mysqld was shut down
after it performed these cleanup operations on the .ibd file, so that it at
the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the
first page of the .ibd file, and we can determine whether we need to reset the
-lsn's just by looking at that flush lsn. */
+lsn's just by looking at that flush lsn.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_reset_too_high_lsns(
/*====================*/
- /* out: TRUE if success */
- const char* name, /* in: table name in the
+ const char* name, /*!< in: table name in the
databasename/tablename format */
- ib_uint64_t current_lsn); /* in: reset lsn's if the lsn stamped
+ ib_uint64_t current_lsn); /*!< in: reset lsn's if the lsn stamped
to FIL_PAGE_FILE_FLUSH_LSN in the
first page is too high */
-/************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
At the server startup, if we need crash recovery, scans the database
directories under the MySQL datadir, looking for .ibd files. Those files are
single-table tablespaces. We need to know the space id in each of them so that
we know into which file we should look to check the contents of a page stored
in the doublewrite buffer, also to know where to apply log records where the
-space id is != 0. */
+space id is != 0.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
fil_load_single_table_tablespaces(void);
/*===================================*/
- /* out: DB_SUCCESS or error number */
-/************************************************************************
+/********************************************************************//**
If we need crash recovery, and we have called
fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
we can call this function to print an error message of orphaned .ibd files
@@ -491,117 +507,118 @@ UNIV_INTERN
void
fil_print_orphaned_tablespaces(void);
/*================================*/
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if a single-table tablespace does not exist in the memory cache,
-or is being deleted there. */
+or is being deleted there.
+@return TRUE if does not exist or is being\ deleted */
UNIV_INTERN
ibool
fil_tablespace_deleted_or_being_deleted_in_mem(
/*===========================================*/
- /* out: TRUE if does not exist or is being\
- deleted */
- ulint id, /* in: space id */
- ib_int64_t version);/* in: tablespace_version should be this; if
+ ulint id, /*!< in: space id */
+ ib_int64_t version);/*!< in: tablespace_version should be this; if
you pass -1 as the value of this, then this
parameter is ignored */
-/***********************************************************************
-Returns TRUE if a single-table tablespace exists in the memory cache. */
+/*******************************************************************//**
+Returns TRUE if a single-table tablespace exists in the memory cache.
+@return TRUE if exists */
UNIV_INTERN
ibool
fil_tablespace_exists_in_mem(
/*=========================*/
- /* out: TRUE if exists */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
cache. Note that if we have not done a crash recovery at the database startup,
-there may be many tablespaces which are not yet in the memory cache. */
+there may be many tablespaces which are not yet in the memory cache.
+@return TRUE if a matching tablespace exists in the memory cache */
UNIV_INTERN
ibool
fil_space_for_table_exists_in_mem(
/*==============================*/
- /* out: TRUE if a matching tablespace
- exists in the memory cache */
- ulint id, /* in: space id */
- const char* name, /* in: table name in the standard
+ ulint id, /*!< in: space id */
+ const char* name, /*!< in: table name in the standard
'databasename/tablename' format or
the dir path to a temp table */
- ibool is_temp, /* in: TRUE if created with CREATE
+ ibool is_temp, /*!< in: TRUE if created with CREATE
TEMPORARY TABLE */
- ibool mark_space, /* in: in crash recovery, at database
+ ibool mark_space, /*!< in: in crash recovery, at database
startup we mark all spaces which have
an associated table in the InnoDB
data dictionary, so that
we can print a warning about orphaned
tablespaces */
ibool print_error_if_does_not_exist);
- /* in: print detailed error
+ /*!< in: print detailed error
information to the .err log if a
matching tablespace is not found from
memory */
-/**************************************************************************
+#else /* !UNIV_HOTBACKUP */
+/********************************************************************//**
+Extends all tablespaces to the size stored in the space header. During the
+ibbackup --apply-log phase we extended the spaces on-demand so that log records
+could be appllied, but that may have left spaces still too small compared to
+the size stored in the space header. */
+UNIV_INTERN
+void
+fil_extend_tablespaces_to_stored_len(void);
+/*======================================*/
+#endif /* !UNIV_HOTBACKUP */
+/**********************************************************************//**
Tries to extend a data file so that it would accommodate the number of pages
given. The tablespace must be cached in the memory cache. If the space is big
-enough already, does nothing. */
+enough already, does nothing.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_extend_space_to_desired_size(
/*=============================*/
- /* out: TRUE if success */
- ulint* actual_size, /* out: size of the space after extension;
+ ulint* actual_size, /*!< out: size of the space after extension;
if we ran out of disk space this may be lower
than the desired size */
- ulint space_id, /* in: space id */
- ulint size_after_extend);/* in: desired size in pages after the
+ ulint space_id, /*!< in: space id */
+ ulint size_after_extend);/*!< in: desired size in pages after the
extension; if the current space size is bigger
than this already, the function does nothing */
-#ifdef UNIV_HOTBACKUP
-/************************************************************************
-Extends all tablespaces to the size stored in the space header. During the
-ibbackup --apply-log phase we extended the spaces on-demand so that log records
-could be appllied, but that may have left spaces still too small compared to
-the size stored in the space header. */
-UNIV_INTERN
-void
-fil_extend_tablespaces_to_stored_len(void);
-/*======================================*/
-#endif
-/***********************************************************************
-Tries to reserve free extents in a file space. */
+/*******************************************************************//**
+Tries to reserve free extents in a file space.
+@return TRUE if succeed */
UNIV_INTERN
ibool
fil_space_reserve_free_extents(
/*===========================*/
- /* out: TRUE if succeed */
- ulint id, /* in: space id */
- ulint n_free_now, /* in: number of free extents now */
- ulint n_to_reserve); /* in: how many one wants to reserve */
-/***********************************************************************
+ ulint id, /*!< in: space id */
+ ulint n_free_now, /*!< in: number of free extents now */
+ ulint n_to_reserve); /*!< in: how many one wants to reserve */
+/*******************************************************************//**
Releases free extents in a file space. */
UNIV_INTERN
void
fil_space_release_free_extents(
/*===========================*/
- ulint id, /* in: space id */
- ulint n_reserved); /* in: how many one reserved */
-/***********************************************************************
+ ulint id, /*!< in: space id */
+ ulint n_reserved); /*!< in: how many one reserved */
+/*******************************************************************//**
Gets the number of reserved extents. If the database is silent, this number
should be zero. */
UNIV_INTERN
ulint
fil_space_get_n_reserved_extents(
/*=============================*/
- ulint id); /* in: space id */
-/************************************************************************
-Reads or writes data. This operation is asynchronous (aio). */
+ ulint id); /*!< in: space id */
+/********************************************************************//**
+Reads or writes data. This operation is asynchronous (aio).
+@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
+i/o on a tablespace which does not exist */
+#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message) \
+ _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, NULL)
+
UNIV_INTERN
ulint
-fil_io(
+_fil_io(
/*===*/
- /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
- if we are trying to do i/o on a tablespace
- which does not exist */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE,
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
and ORed to OS_AIO_SIMULATED_WAKE_LATER
if simulated aio and we want to post a
@@ -610,23 +627,40 @@ fil_io(
because i/os are not actually handled until
all have been posted: use with great
caution! */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes;
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint block_offset, /* in: offset in number of blocks */
- ulint byte_offset, /* in: remainder of offset in bytes; in
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
aio this must be divisible by the OS block
size */
- ulint len, /* in: how many bytes to read or write; this
+ ulint len, /*!< in: how many bytes to read or write; this
must not cross a file boundary; in aio this
must be a block size multiple */
- void* buf, /* in/out: buffer where to store read data
+ void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
- void* message); /* in: message for aio handler if non-sync
+ void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
-/**************************************************************************
+ trx_t* trx);
+/********************************************************************//**
+Confirm whether the parameters are valid or not */
+UNIV_INTERN
+ibool
+fil_area_is_exist(
+/*==============*/
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
+ 0 for uncompressed pages */
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
+ aio this must be divisible by the OS block
+ size */
+ ulint len); /*!< in: how many bytes to read or write; this
+ must not cross a file boundary; in aio this
+ must be a block size multiple */
+/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
into segments (see os0file.c for more info). The thread specifies which
@@ -635,65 +669,73 @@ UNIV_INTERN
void
fil_aio_wait(
/*=========*/
- ulint segment); /* in: the number of the segment in the aio
+ ulint segment); /*!< in: the number of the segment in the aio
array to wait for */
-/**************************************************************************
+/**********************************************************************//**
Flushes to disk possible writes cached by the OS. If the space does not exist
or is being dropped, does not do anything. */
UNIV_INTERN
void
fil_flush(
/*======*/
- ulint space_id); /* in: file space id (this can be a group of
+ ulint space_id); /*!< in: file space id (this can be a group of
log files or a tablespace of the database) */
-/**************************************************************************
+/**********************************************************************//**
Flushes to disk writes in file spaces of the given type possibly cached by
the OS. */
UNIV_INTERN
void
fil_flush_file_spaces(
/*==================*/
- ulint purpose); /* in: FIL_TABLESPACE, FIL_LOG */
-/**********************************************************************
-Checks the consistency of the tablespace cache. */
+ ulint purpose); /*!< in: FIL_TABLESPACE, FIL_LOG */
+/******************************************************************//**
+Checks the consistency of the tablespace cache.
+@return TRUE if ok */
UNIV_INTERN
ibool
fil_validate(void);
/*==============*/
- /* out: TRUE if ok */
-/************************************************************************
-Returns TRUE if file address is undefined. */
+/********************************************************************//**
+Returns TRUE if file address is undefined.
+@return TRUE if undefined */
UNIV_INTERN
ibool
fil_addr_is_null(
/*=============*/
- /* out: TRUE if undefined */
- fil_addr_t addr); /* in: address */
-/************************************************************************
-Accessor functions for a file page */
+ fil_addr_t addr); /*!< in: address */
+/********************************************************************//**
+Get the predecessor of a file page.
+@return FIL_PAGE_PREV */
UNIV_INTERN
ulint
-fil_page_get_prev(const byte* page);
+fil_page_get_prev(
+/*==============*/
+ const byte* page); /*!< in: file page */
+/********************************************************************//**
+Get the successor of a file page.
+@return FIL_PAGE_NEXT */
+UNIV_INTERN
ulint
-fil_page_get_next(const byte* page);
-/*************************************************************************
+fil_page_get_next(
+/*==============*/
+ const byte* page); /*!< in: file page */
+/*********************************************************************//**
Sets the file page type. */
UNIV_INTERN
void
fil_page_set_type(
/*==============*/
- byte* page, /* in: file page */
- ulint type); /* in: type */
-/*************************************************************************
-Gets the file page type. */
+ byte* page, /*!< in/out: file page */
+ ulint type); /*!< in: type */
+/*********************************************************************//**
+Gets the file page type.
+@return type; NOTE that if the type has not been written to page, the
+return value not defined */
UNIV_INTERN
ulint
fil_page_get_type(
/*==============*/
- /* out: type; NOTE that if the type
- has not been written to page, the
- return value not defined */
- const byte* page); /* in: file page */
+ const byte* page); /*!< in: file page */
/*************************************************************************
Return local hash table informations. */
diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h
index 1f6ae4b614b..7abd3914eda 100644
--- a/storage/xtradb/include/fsp0fsp.h
+++ b/storage/xtradb/include/fsp0fsp.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/fsp0fsp.h
File space management
Created 12/18/1995 Heikki Tuuri
@@ -31,90 +32,67 @@ Created 12/18/1995 Heikki Tuuri
#include "fut0lst.h"
#include "ut0byte.h"
#include "page0types.h"
+#include "fsp0types.h"
-/* If records are inserted in order, there are the following
-flags to tell this (their type is made byte for the compiler
-to warn if direction and hint parameters are switched in
-fseg_alloc_free_page): */
-#define FSP_UP ((byte)111) /* alphabetically upwards */
-#define FSP_DOWN ((byte)112) /* alphabetically downwards */
-#define FSP_NO_DIR ((byte)113) /* no order */
-
-/* File space extent size (one megabyte) in pages */
-#define FSP_EXTENT_SIZE (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
-
-/* On a page of any file segment, data may be put starting from this offset: */
-#define FSEG_PAGE_DATA FIL_PAGE_DATA
-
-/* File segment header which points to the inode describing the file segment */
-typedef byte fseg_header_t;
-
-#define FSEG_HDR_SPACE 0 /* space id of the inode */
-#define FSEG_HDR_PAGE_NO 4 /* page number of the inode */
-#define FSEG_HDR_OFFSET 8 /* byte offset of the inode */
-
-#define FSEG_HEADER_SIZE 10
-
-/**************************************************************************
+/**********************************************************************//**
Initializes the file space system. */
UNIV_INTERN
void
fsp_init(void);
/*==========*/
-/**************************************************************************
+/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
-means the place of the first page which has never been put to the the
+means the place of the first page which has never been put to the
free list for allocation. The space above that address is initialized
-to zero. Sets also the global variable log_fsp_current_free_limit. */
+to zero. Sets also the global variable log_fsp_current_free_limit.
+@return free limit in megabytes */
UNIV_INTERN
ulint
fsp_header_get_free_limit(void);
/*===========================*/
- /* out: free limit in megabytes */
-/**************************************************************************
+/**********************************************************************//**
Gets the size of the system tablespace from the tablespace header. If
we do not have an auto-extending data file, this should be equal to
the size of the data files. If there is an auto-extending data file,
-this can be smaller. */
+this can be smaller.
+@return size in pages */
UNIV_INTERN
ulint
fsp_header_get_tablespace_size(void);
/*================================*/
- /* out: size in pages */
-/**************************************************************************
-Reads the file space size stored in the header page. */
+/**********************************************************************//**
+Reads the file space size stored in the header page.
+@return tablespace size stored in the space header */
UNIV_INTERN
ulint
fsp_get_size_low(
/*=============*/
- /* out: tablespace size stored in the space header */
- page_t* page); /* in: header page (page 0 in the tablespace) */
-/**************************************************************************
-Reads the space id from the first page of a tablespace. */
+ page_t* page); /*!< in: header page (page 0 in the tablespace) */
+/**********************************************************************//**
+Reads the space id from the first page of a tablespace.
+@return space id, ULINT UNDEFINED if error */
UNIV_INTERN
ulint
fsp_header_get_space_id(
/*====================*/
- /* out: space id, ULINT UNDEFINED if error */
- const page_t* page); /* in: first page of a tablespace */
-/**************************************************************************
-Reads the space flags from the first page of a tablespace. */
+ const page_t* page); /*!< in: first page of a tablespace */
+/**********************************************************************//**
+Reads the space flags from the first page of a tablespace.
+@return flags */
UNIV_INTERN
ulint
fsp_header_get_flags(
/*=================*/
- /* out: flags */
- const page_t* page); /* in: first page of a tablespace */
-/**************************************************************************
-Reads the compressed page size from the first page of a tablespace. */
+ const page_t* page); /*!< in: first page of a tablespace */
+/**********************************************************************//**
+Reads the compressed page size from the first page of a tablespace.
+@return compressed page size in bytes, or 0 if uncompressed */
UNIV_INTERN
ulint
fsp_header_get_zip_size(
/*====================*/
- /* out: compressed page size in bytes,
- or 0 if uncompressed */
- const page_t* page); /* in: first page of a tablespace */
-/**************************************************************************
+ const page_t* page); /*!< in: first page of a tablespace */
+/**********************************************************************//**
Writes the space id and compressed page size to a tablespace header.
This function is used past the buffer pool when we in fil0fil.c create
a new single-table tablespace. */
@@ -122,122 +100,118 @@ UNIV_INTERN
void
fsp_header_init_fields(
/*===================*/
- page_t* page, /* in/out: first page in the space */
- ulint space_id, /* in: space id */
- ulint flags); /* in: tablespace flags (FSP_SPACE_FLAGS):
+ page_t* page, /*!< in/out: first page in the space */
+ ulint space_id, /*!< in: space id */
+ ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */
-/**************************************************************************
+/**********************************************************************//**
Initializes the space header of a new created space and creates also the
insert buffer tree root if space == 0. */
UNIV_INTERN
void
fsp_header_init(
/*============*/
- ulint space, /* in: space id */
- ulint size, /* in: current size in blocks */
- mtr_t* mtr); /* in: mini-transaction handle */
-/**************************************************************************
+ ulint space, /*!< in: space id */
+ ulint size, /*!< in: current size in blocks */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/**********************************************************************//**
Increases the space size field of a space. */
UNIV_INTERN
void
fsp_header_inc_size(
/*================*/
- ulint space, /* in: space id */
- ulint size_inc,/* in: size increment in pages */
- mtr_t* mtr); /* in: mini-transaction handle */
-/**************************************************************************
-Creates a new segment. */
+ ulint space, /*!< in: space id */
+ ulint size_inc,/*!< in: size increment in pages */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/**********************************************************************//**
+Creates a new segment.
+@return the block where the segment header is placed, x-latched, NULL
+if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create(
/*========*/
- /* out: the block where the segment header is placed,
- x-latched, NULL if could not create segment
- because of lack of space */
- ulint space, /* in: space id */
- ulint page, /* in: page where the segment header is placed: if
+ 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
+ ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
-Creates a new segment. */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
+Creates a new segment.
+@return the block where the segment header is placed, x-latched, NULL
+if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create_general(
/*================*/
- /* out: the block where the segment header is placed,
- x-latched, NULL if could not create segment
- because of lack of space */
- ulint space, /* in: space id */
- ulint page, /* in: page where the segment header is placed: if
+ 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
+ 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
+ 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: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
-currently used. */
+currently used.
+@return number of reserved pages */
UNIV_INTERN
ulint
fseg_n_reserved_pages(
/*==================*/
- /* out: number of reserved pages */
- fseg_header_t* header, /* in: segment header */
- ulint* used, /* out: number of pages used (<= reserved) */
- mtr_t* mtr); /* in: mtr handle */
-/**************************************************************************
+ fseg_header_t* header, /*!< in: segment header */
+ ulint* used, /*!< out: number of pages used (<= reserved) */
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize
-file space fragmentation. */
+file space fragmentation.
+@return the allocated page offset FIL_NULL if no page could be allocated */
UNIV_INTERN
ulint
fseg_alloc_free_page(
/*=================*/
- /* out: the allocated page offset
- FIL_NULL if no page could be allocated */
- fseg_header_t* seg_header, /* in: segment header */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction, /* in: if the new page is needed because
+ fseg_header_t* seg_header, /*!< in: segment header */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction, /*!< in: 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 */
- mtr_t* mtr); /* in: mtr handle */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return allocated page offset, FIL_NULL if no page could be allocated */
UNIV_INTERN
ulint
fseg_alloc_free_page_general(
/*=========================*/
- /* out: allocated page offset, FIL_NULL if no
- page could be allocated */
- fseg_header_t* seg_header,/* in: segment header */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction,/* in: if the new page is needed because
+ fseg_header_t* seg_header,/*!< in: segment header */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction,/*!< in: 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 */
- ibool has_done_reservation, /* in: TRUE if the caller has
+ ibool has_done_reservation, /*!< in: TRUE if the caller has
already done the reservation for the page
with fsp_reserve_free_extents, then there
is no need to do the check for this individual
page */
- mtr_t* mtr); /* in: mtr handle */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Reserves free pages from a tablespace. All mini-transactions which may
use several pages from the tablespace should call this function beforehand
and reserve enough free extents so that they certainly will be able
@@ -261,171 +235,123 @@ Single-table tablespaces whose size is < 32 pages are a special case. In this
function we would liberally reserve several 64 page extents for every page
split or merge in a B-tree. But we do not want to waste disk space if the table
only occupies < 32 pages. That is why we apply different rules in that special
-case, just ensuring that there are 3 free pages available. */
+case, just ensuring that there are 3 free pages available.
+@return TRUE if we were able to make the reservation */
UNIV_INTERN
ibool
fsp_reserve_free_extents(
/*=====================*/
- /* out: TRUE if we were able to make the reservation */
- ulint* n_reserved,/* out: number of extents actually reserved; if we
+ ulint* n_reserved,/*!< out: number of extents actually reserved; if we
return TRUE and the tablespace size is < 64 pages,
then this can be 0, otherwise it is n_ext */
- ulint space, /* in: space id */
- ulint n_ext, /* in: number of extents to reserve */
- ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ ulint space, /*!< in: space id */
+ ulint n_ext, /*!< in: number of extents to reserve */
+ ulint alloc_type,/*!< in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
This function should be used to get information on how much we still
will be able to insert new data to the database without running out the
tablespace. Only free extents are taken into account and we also subtract
-the safety margin required by the above function fsp_reserve_free_extents. */
+the safety margin required by the above function fsp_reserve_free_extents.
+@return available space in kB */
UNIV_INTERN
ullint
fsp_get_available_space_in_free_extents(
/*====================================*/
- /* out: available space in kB */
- ulint space); /* in: space id */
-/**************************************************************************
+ ulint space); /*!< in: space id */
+/**********************************************************************//**
Frees a single page of a segment. */
UNIV_INTERN
void
fseg_free_page(
/*===========*/
- fseg_header_t* seg_header, /* in: segment header */
- ulint space, /* in: space id */
- ulint page, /* in: page offset */
- mtr_t* mtr); /* in: mtr handle */
-/***********************************************************************
-Frees a segment. The freeing is performed in several mini-transactions,
-so that there is no danger of bufferfixing too many buffer pages. */
-UNIV_INTERN
-void
-fseg_free(
-/*======*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
- or 0 for uncompressed pages */
- ulint page_no,/* in: page number where the segment header is
- placed */
- ulint offset);/* in: byte offset of the segment header on that
- page */
-/**************************************************************************
+ fseg_header_t* seg_header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
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. */
+too big a mini-transaction.
+@return TRUE if freeing completed */
UNIV_INTERN
ibool
fseg_free_step(
/*===========*/
- /* out: TRUE if freeing completed */
- fseg_header_t* header, /* in, own: segment header; NOTE: if the header
+ 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 */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Frees part of a segment. Differs from fseg_free_step because this function
-leaves the header page unfreed. */
+leaves the header page unfreed.
+@return TRUE if freeing completed, except the header page */
UNIV_INTERN
ibool
fseg_free_step_not_header(
/*======================*/
- /* out: TRUE if freeing completed, except the
- header page */
- fseg_header_t* header, /* in: segment header which must reside on
+ fseg_header_t* header, /*!< in: segment header which must reside on
the first fragment page of the segment */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************************
-Checks if a page address is an extent descriptor page address. */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************************//**
+Checks if a page address is an extent descriptor page address.
+@return TRUE if a descriptor page */
UNIV_INLINE
ibool
fsp_descr_page(
/*===========*/
- /* out: TRUE if a descriptor page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no);/* in: page number */
-/***************************************************************
-Parses a redo log record of a file page init. */
+ ulint page_no);/*!< in: page number */
+/***********************************************************//**
+Parses a redo log record of a file page init.
+@return end of log record or NULL */
UNIV_INTERN
byte*
fsp_parse_init_file_page(
/*=====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr, /* in: buffer end */
- buf_block_t* block); /* in: block or NULL */
-/***********************************************************************
-Validates the file space system and its segments. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr, /*!< in: buffer end */
+ buf_block_t* block); /*!< in: block or NULL */
+/*******************************************************************//**
+Validates the file space system and its segments.
+@return TRUE if ok */
UNIV_INTERN
ibool
fsp_validate(
/*=========*/
- /* out: TRUE if ok */
- ulint space); /* in: space id */
-/***********************************************************************
+ ulint space); /*!< in: space id */
+/*******************************************************************//**
Prints info of a file space. */
UNIV_INTERN
void
fsp_print(
/*======*/
- ulint space); /* in: space id */
-/***********************************************************************
-Validates a segment. */
+ ulint space); /*!< in: space id */
+#ifdef UNIV_DEBUG
+/*******************************************************************//**
+Validates a segment.
+@return TRUE if ok */
UNIV_INTERN
ibool
fseg_validate(
/*==========*/
- /* out: TRUE if ok */
- fseg_header_t* header, /* in: segment header */
- mtr_t* mtr2); /* in: mtr */
+ fseg_header_t* header, /*!< in: segment header */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* UNIV_DEBUG */
#ifdef UNIV_BTR_PRINT
-/***********************************************************************
+/*******************************************************************//**
Writes info of a segment. */
UNIV_INTERN
void
fseg_print(
/*=======*/
- fseg_header_t* header, /* in: segment header */
- mtr_t* mtr); /* in: mtr */
+ fseg_header_t* header, /*!< in: segment header */
+ mtr_t* mtr); /*!< in: mtr */
#endif /* UNIV_BTR_PRINT */
-/* Flags for fsp_reserve_free_extents */
-#define FSP_NORMAL 1000000
-#define FSP_UNDO 2000000
-#define FSP_CLEANING 3000000
-
-/* Number of pages described in a single descriptor page: currently each page
-description takes less than 1 byte; a descriptor page is repeated every
-this many file pages */
-/* #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE */
-/* This has been replaced with either UNIV_PAGE_SIZE or page_zip->size. */
-
-/* The space low address page map */
-/*--------------------------------------*/
- /* The following two pages are repeated
- every XDES_DESCRIBED_PER_PAGE pages in
- every tablespace. */
-#define FSP_XDES_OFFSET 0 /* extent descriptor */
-#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */
- /* The ibuf bitmap pages are the ones whose
- page number is the number above plus a
- multiple of XDES_DESCRIBED_PER_PAGE */
-
-#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */
- /* The following pages exist
- in the system tablespace (space 0). */
-#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */
-#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */
- /* The ibuf tree root page number in
- tablespace 0; its fseg inode is on the page
- number FSP_FIRST_INODE_PAGE_NO */
-#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */
-#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */
-#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */
-/*--------------------------------------*/
-
#ifndef UNIV_NONINL
#include "fsp0fsp.ic"
#endif
diff --git a/storage/xtradb/include/fsp0fsp.ic b/storage/xtradb/include/fsp0fsp.ic
index f0301cc5e18..434c370b527 100644
--- a/storage/xtradb/include/fsp0fsp.ic
+++ b/storage/xtradb/include/fsp0fsp.ic
@@ -16,22 +16,23 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/fsp0fsp.ic
File space management
Created 12/18/1995 Heikki Tuuri
*******************************************************/
-/***************************************************************************
-Checks if a page address is an extent descriptor page address. */
+/***********************************************************************//**
+Checks if a page address is an extent descriptor page address.
+@return TRUE if a descriptor page */
UNIV_INLINE
ibool
fsp_descr_page(
/*===========*/
- /* out: TRUE if a descriptor page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no)/* in: page number */
+ ulint page_no)/*!< in: page number */
{
ut_ad(ut_is_2pow(zip_size));
diff --git a/storage/xtradb/include/fsp0types.h b/storage/xtradb/include/fsp0types.h
new file mode 100644
index 00000000000..496081c2346
--- /dev/null
+++ b/storage/xtradb/include/fsp0types.h
@@ -0,0 +1,110 @@
+/*****************************************************************************
+
+Copyright (c) 1995, 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
+
+*****************************************************************************/
+
+/******************************************************
+@file include/fsp0types.h
+File space management types
+
+Created May 26, 2009 Vasil Dimov
+*******************************************************/
+
+#ifndef fsp0types_h
+#define fsp0types_h
+
+#include "univ.i"
+
+#include "fil0fil.h" /* for FIL_PAGE_DATA */
+
+/** @name Flags for inserting records in order
+If records are inserted in order, there are the following
+flags to tell this (their type is made byte for the compiler
+to warn if direction and hint parameters are switched in
+fseg_alloc_free_page) */
+/* @{ */
+#define FSP_UP ((byte)111) /*!< alphabetically upwards */
+#define FSP_DOWN ((byte)112) /*!< alphabetically downwards */
+#define FSP_NO_DIR ((byte)113) /*!< no order */
+/* @} */
+
+/** File space extent size (one megabyte) in pages */
+#define FSP_EXTENT_SIZE (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
+
+/** On a page of any file segment, data may be put starting from this
+offset */
+#define FSEG_PAGE_DATA FIL_PAGE_DATA
+
+/** @name File segment header
+The file segment header points to the inode describing the file segment. */
+/* @{ */
+/** Data type for file segment header */
+typedef byte fseg_header_t;
+
+#define FSEG_HDR_SPACE 0 /*!< space id of the inode */
+#define FSEG_HDR_PAGE_NO 4 /*!< page number of the inode */
+#define FSEG_HDR_OFFSET 8 /*!< byte offset of the inode */
+
+#define FSEG_HEADER_SIZE 10 /*!< Length of the file system
+ header, in bytes */
+/* @} */
+
+/** Flags for fsp_reserve_free_extents @{ */
+#define FSP_NORMAL 1000000
+#define FSP_UNDO 2000000
+#define FSP_CLEANING 3000000
+/* @} */
+
+/* Number of pages described in a single descriptor page: currently each page
+description takes less than 1 byte; a descriptor page is repeated every
+this many file pages */
+/* #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE */
+/* This has been replaced with either UNIV_PAGE_SIZE or page_zip->size. */
+
+/** @name The space low address page map
+The pages at FSP_XDES_OFFSET and FSP_IBUF_BITMAP_OFFSET are repeated
+every XDES_DESCRIBED_PER_PAGE pages in every tablespace. */
+/* @{ */
+/*--------------------------------------*/
+#define FSP_XDES_OFFSET 0 /* !< extent descriptor */
+#define FSP_IBUF_BITMAP_OFFSET 1 /* !< insert buffer bitmap */
+ /* The ibuf bitmap pages are the ones whose
+ page number is the number above plus a
+ multiple of XDES_DESCRIBED_PER_PAGE */
+
+#define FSP_FIRST_INODE_PAGE_NO 2 /*!< in every tablespace */
+ /* The following pages exist
+ in the system tablespace (space 0). */
+#define FSP_IBUF_HEADER_PAGE_NO 3 /*!< insert buffer
+ header page, in
+ tablespace 0 */
+#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /*!< insert buffer
+ B-tree root page in
+ tablespace 0 */
+ /* The ibuf tree root page number in
+ tablespace 0; its fseg inode is on the page
+ number FSP_FIRST_INODE_PAGE_NO */
+#define FSP_TRX_SYS_PAGE_NO 5 /*!< transaction
+ system header, in
+ tablespace 0 */
+#define FSP_FIRST_RSEG_PAGE_NO 6 /*!< first rollback segment
+ page, in tablespace 0 */
+#define FSP_DICT_HDR_PAGE_NO 7 /*!< data dictionary header
+ page, in tablespace 0 */
+/*--------------------------------------*/
+/* @} */
+
+#endif /* fsp0types_h */
diff --git a/storage/xtradb/include/fut0fut.h b/storage/xtradb/include/fut0fut.h
index 4de0c97294c..dce20b3bad6 100644
--- a/storage/xtradb/include/fut0fut.h
+++ b/storage/xtradb/include/fut0fut.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/fut0fut.h
File-based utilities
Created 12/13/1995 Heikki Tuuri
@@ -31,20 +32,20 @@ Created 12/13/1995 Heikki Tuuri
#include "fil0fil.h"
#include "mtr0mtr.h"
-/************************************************************************
-Gets a pointer to a file address and latches the page. */
+/********************************************************************//**
+Gets a pointer to a file address and latches the page.
+@return pointer to a byte in a frame; the file page in the frame is
+bufferfixed and latched */
UNIV_INLINE
byte*
fut_get_ptr(
/*========*/
- /* out: pointer to a byte in a frame; the file
- page in the frame is bufferfixed and latched */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fil_addr_t addr, /* in: file address */
- ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH */
- mtr_t* mtr); /* in: mtr handle */
+ fil_addr_t addr, /*!< in: file address */
+ ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH */
+ mtr_t* mtr); /*!< in: mtr handle */
#ifndef UNIV_NONINL
#include "fut0fut.ic"
diff --git a/storage/xtradb/include/fut0fut.ic b/storage/xtradb/include/fut0fut.ic
index f7e820da008..0b52719a055 100644
--- a/storage/xtradb/include/fut0fut.ic
+++ b/storage/xtradb/include/fut0fut.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/fut0fut.ic
File-based utilities
Created 12/13/1995 Heikki Tuuri
@@ -25,20 +26,20 @@ Created 12/13/1995 Heikki Tuuri
#include "sync0rw.h"
#include "buf0buf.h"
-/************************************************************************
-Gets a pointer to a file address and latches the page. */
+/********************************************************************//**
+Gets a pointer to a file address and latches the page.
+@return pointer to a byte in a frame; the file page in the frame is
+bufferfixed and latched */
UNIV_INLINE
byte*
fut_get_ptr(
/*========*/
- /* out: pointer to a byte in a frame; the file
- page in the frame is bufferfixed and latched */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fil_addr_t addr, /* in: file address */
- ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH */
- mtr_t* mtr) /* in: mtr handle */
+ fil_addr_t addr, /*!< in: file address */
+ ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH */
+ mtr_t* mtr) /*!< in: mtr handle */
{
buf_block_t* block;
byte* ptr;
diff --git a/storage/xtradb/include/fut0lst.h b/storage/xtradb/include/fut0lst.h
index f812874fe00..fe024c2498f 100644
--- a/storage/xtradb/include/fut0lst.h
+++ b/storage/xtradb/include/fut0lst.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/fut0lst.h
File-based list utilities
Created 11/28/1995 Heikki Tuuri
@@ -44,63 +45,63 @@ typedef byte flst_node_t;
/* The physical size of a list node in bytes */
#define FLST_NODE_SIZE (2 * FIL_ADDR_SIZE)
-
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Initializes a list base node. */
UNIV_INLINE
void
flst_init(
/*======*/
- flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Adds a node as the last node in a list. */
UNIV_INTERN
void
flst_add_last(
/*==========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Adds a node as the first node in a list. */
UNIV_INTERN
void
flst_add_first(
/*===========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Inserts a node after another in a list. */
UNIV_INTERN
void
flst_insert_after(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node1, /* in: node to insert after */
- flst_node_t* node2, /* in: node to add */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node1, /*!< in: node to insert after */
+ flst_node_t* node2, /*!< in: node to add */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Inserts a node before another in a list. */
UNIV_INTERN
void
flst_insert_before(
/*===============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: node to insert */
- flst_node_t* node3, /* in: node to insert before */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: node to insert */
+ flst_node_t* node3, /*!< in: node to insert before */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Removes a node. */
UNIV_INTERN
void
flst_remove(
/*========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: node to remove */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: node to remove */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Cuts off the tail of the list, including the node given. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@@ -108,12 +109,12 @@ UNIV_INTERN
void
flst_cut_end(
/*=========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: first node to remove */
- ulint n_nodes,/* in: number of nodes to remove,
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: first node to remove */
+ ulint n_nodes,/*!< in: number of nodes to remove,
must be >= 1 */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Cuts off the tail of the list, not including the given node. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@@ -121,94 +122,96 @@ UNIV_INTERN
void
flst_truncate_end(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: first node not to remove */
- ulint n_nodes,/* in: number of nodes to remove */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list length. */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: first node not to remove */
+ ulint n_nodes,/*!< in: number of nodes to remove */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list length.
+@return length */
UNIV_INLINE
ulint
flst_get_len(
/*=========*/
- /* out: length */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list first node address. */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list first node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_first(
/*===========*/
- /* out: file address */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list last node address. */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list last node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_last(
/*==========*/
- /* out: file address */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list next node address. */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list next node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_next_addr(
/*===============*/
- /* out: file address */
- const flst_node_t* node, /* in: pointer to node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list prev node address. */
+ const flst_node_t* node, /*!< in: pointer to node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list prev node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_prev_addr(
/*===============*/
- /* out: file address */
- const flst_node_t* node, /* in: pointer to node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ const flst_node_t* node, /*!< in: pointer to node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Writes a file address. */
UNIV_INLINE
void
flst_write_addr(
/*============*/
- fil_faddr_t* faddr, /* in: pointer to file faddress */
- fil_addr_t addr, /* in: file address */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Reads a file address. */
+ fil_faddr_t* faddr, /*!< in: pointer to file faddress */
+ fil_addr_t addr, /*!< in: file address */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Reads a file address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_read_addr(
/*===========*/
- /* out: file address */
- const fil_faddr_t* faddr, /* in: pointer to file faddress */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Validates a file-based list. */
+ const fil_faddr_t* faddr, /*!< in: pointer to file faddress */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Validates a file-based list.
+@return TRUE if ok */
UNIV_INTERN
ibool
flst_validate(
/*==========*/
- /* out: TRUE if ok */
- const flst_base_node_t* base, /* in: pointer to base node of list */
- mtr_t* mtr1); /* in: mtr */
-/************************************************************************
+ const flst_base_node_t* base, /*!< in: pointer to base node of list */
+ mtr_t* mtr1); /*!< in: mtr */
+/********************************************************************//**
Prints info of a file-based list. */
UNIV_INTERN
void
flst_print(
/*=======*/
- const flst_base_node_t* base, /* in: pointer to base node of list */
- mtr_t* mtr); /* in: mtr */
+ const flst_base_node_t* base, /*!< in: pointer to base node of list */
+ mtr_t* mtr); /*!< in: mtr */
#ifndef UNIV_NONINL
#include "fut0lst.ic"
#endif
+#endif /* !UNIV_HOTBACKUP */
+
#endif
diff --git a/storage/xtradb/include/fut0lst.ic b/storage/xtradb/include/fut0lst.ic
index 5899e996059..dcd13c61871 100644
--- a/storage/xtradb/include/fut0lst.ic
+++ b/storage/xtradb/include/fut0lst.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/fut0lst.ic
File-based list utilities
Created 11/28/1995 Heikki Tuuri
@@ -42,15 +43,15 @@ Created 11/28/1995 Heikki Tuuri
last element of the list; undefined
if empty list */
-/************************************************************************
+/********************************************************************//**
Writes a file address. */
UNIV_INLINE
void
flst_write_addr(
/*============*/
- fil_faddr_t* faddr, /* in: pointer to file faddress */
- fil_addr_t addr, /* in: file address */
- mtr_t* mtr) /* in: mini-transaction handle */
+ fil_faddr_t* faddr, /*!< in: pointer to file faddress */
+ fil_addr_t addr, /*!< in: file address */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(faddr && mtr);
ut_ad(mtr_memo_contains_page(mtr, faddr, MTR_MEMO_PAGE_X_FIX));
@@ -62,15 +63,15 @@ flst_write_addr(
MLOG_2BYTES, mtr);
}
-/************************************************************************
-Reads a file address. */
+/********************************************************************//**
+Reads a file address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_read_addr(
/*===========*/
- /* out: file address */
- const fil_faddr_t* faddr, /* in: pointer to file faddress */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const fil_faddr_t* faddr, /*!< in: pointer to file faddress */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fil_addr_t addr;
@@ -84,14 +85,14 @@ flst_read_addr(
return(addr);
}
-/************************************************************************
+/********************************************************************//**
Initializes a list base node. */
UNIV_INLINE
void
flst_init(
/*======*/
- flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
@@ -100,67 +101,67 @@ flst_init(
flst_write_addr(base + FLST_LAST, fil_addr_null, mtr);
}
-/************************************************************************
-Gets list length. */
+/********************************************************************//**
+Gets list length.
+@return length */
UNIV_INLINE
ulint
flst_get_len(
/*=========*/
- /* out: length */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(mtr_read_ulint(base + FLST_LEN, MLOG_4BYTES, mtr));
}
-/************************************************************************
-Gets list first node address. */
+/********************************************************************//**
+Gets list first node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_first(
/*===========*/
- /* out: file address */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(flst_read_addr(base + FLST_FIRST, mtr));
}
-/************************************************************************
-Gets list last node address. */
+/********************************************************************//**
+Gets list last node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_last(
/*==========*/
- /* out: file address */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(flst_read_addr(base + FLST_LAST, mtr));
}
-/************************************************************************
-Gets list next node address. */
+/********************************************************************//**
+Gets list next node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_next_addr(
/*===============*/
- /* out: file address */
- const flst_node_t* node, /* in: pointer to node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_node_t* node, /*!< in: pointer to node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(flst_read_addr(node + FLST_NEXT, mtr));
}
-/************************************************************************
-Gets list prev node address. */
+/********************************************************************//**
+Gets list prev node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_prev_addr(
/*===============*/
- /* out: file address */
- const flst_node_t* node, /* in: pointer to node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_node_t* node, /*!< in: pointer to node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(flst_read_addr(node + FLST_PREV, mtr));
}
diff --git a/storage/xtradb/include/ha0ha.h b/storage/xtradb/include/ha0ha.h
index 768f3d7aca3..1ffbd3440aa 100644
--- a/storage/xtradb/include/ha0ha.h
+++ b/storage/xtradb/include/ha0ha.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ha0ha.h
The hash table with external chains
Created 8/18/1994 Heikki Tuuri
@@ -31,156 +32,208 @@ Created 8/18/1994 Heikki Tuuri
#include "page0types.h"
#include "buf0types.h"
-/*****************************************************************
-Looks for an element in a hash table. */
+/*************************************************************//**
+Looks for an element in a hash table.
+@return pointer to the data of the first hash table node in chain
+having the fold number, NULL if not found */
UNIV_INLINE
void*
ha_search_and_get_data(
/*===================*/
- /* out: pointer to the data of the first hash
- table node in chain having the fold number,
- NULL if not found */
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: folded value of the searched data */
-/*************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: folded value of the searched data */
+/*********************************************************//**
Looks for an element when we know the pointer to the data and updates
the pointer to data if found. */
UNIV_INTERN
void
ha_search_and_update_if_found_func(
/*===============================*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data, /* in: pointer to the data */
+ hash_table_t* table, /*!< in/out: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data, /*!< in: pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* new_block,/* in: block containing new_data */
+ buf_block_t* new_block,/*!< in: block containing new_data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* new_data);/* in: new pointer to the data */
+ void* new_data);/*!< in: new pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+/** Looks for an element when we know the pointer to the data and
+updates the pointer to data if found.
+@param table in/out: hash table
+@param fold in: folded value of the searched data
+@param data in: pointer to the data
+@param new_block in: block containing new_data
+@param new_data in: new pointer to the data */
# define ha_search_and_update_if_found(table,fold,data,new_block,new_data) \
ha_search_and_update_if_found_func(table,fold,data,new_block,new_data)
#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+/** Looks for an element when we know the pointer to the data and
+updates the pointer to data if found.
+@param table in/out: hash table
+@param fold in: folded value of the searched data
+@param data in: pointer to the data
+@param new_block ignored: block containing new_data
+@param new_data in: new pointer to the data */
# define ha_search_and_update_if_found(table,fold,data,new_block,new_data) \
ha_search_and_update_if_found_func(table,fold,data,new_data)
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-/*****************************************************************
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n. */
+/*************************************************************//**
+Creates a hash table with at least n array cells. The actual number
+of cells is chosen to be a prime number slightly bigger than n.
+@return own: created table */
UNIV_INTERN
hash_table_t*
ha_create_func(
/*===========*/
- /* out, own: created table */
- ulint n, /* in: number of array cells */
+ ulint n, /*!< in: number of array cells */
#ifdef UNIV_SYNC_DEBUG
- ulint mutex_level, /* in: level of the mutexes in the latching
+ ulint mutex_level, /*!< in: level of the mutexes in the latching
order: this is used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes); /* in: number of mutexes to protect the
- hash table: must be a power of 2 */
+ ulint n_mutexes); /*!< in: number of mutexes to protect the
+ hash table: must be a power of 2, or 0 */
#ifdef UNIV_SYNC_DEBUG
+/** Creates a hash table.
+@return own: created table
+@param n_c in: number of array cells. The actual number of cells is
+chosen to be a slightly bigger prime number.
+@param level in: level of the mutexes in the latching order
+@param n_m in: number of mutexes to protect the hash table;
+ must be a power of 2, or 0 */
# define ha_create(n_c,n_m,level) ha_create_func(n_c,level,n_m)
#else /* UNIV_SYNC_DEBUG */
+/** Creates a hash table.
+@return own: created table
+@param n_c in: number of array cells. The actual number of cells is
+chosen to be a slightly bigger prime number.
+@param level in: level of the mutexes in the latching order
+@param n_m in: number of mutexes to protect the hash table;
+ must be a power of 2, or 0 */
# define ha_create(n_c,n_m,level) ha_create_func(n_c,n_m)
#endif /* UNIV_SYNC_DEBUG */
-/*****************************************************************
+/*************************************************************//**
Empties a hash table and frees the memory heaps. */
UNIV_INTERN
void
ha_clear(
/*=====*/
- hash_table_t* table); /* in, own: hash table */
+ hash_table_t* table); /*!< in, own: hash table */
-/*****************************************************************
+/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
-is inserted. */
+is inserted.
+@return TRUE if succeed, FALSE if no more memory could be allocated */
UNIV_INTERN
ibool
ha_insert_for_fold_func(
/*====================*/
- /* out: TRUE if succeed, FALSE if no more
- memory could be allocated */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of data; if a node with
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of data; if a node with
the same fold value already exists, it is
updated to point to the same data, and no new
node is created! */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* block, /* in: buffer block containing the data */
+ buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* data); /* in: data, must not be NULL */
+ void* data); /*!< in: data, must not be NULL */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+/**
+Inserts an entry into a hash table. If an entry with the same fold number
+is found, its node is updated to point to the new data, and no new node
+is inserted.
+@return TRUE if succeed, FALSE if no more memory could be allocated
+@param t in: hash table
+@param f in: folded value of data
+@param b in: buffer block containing the data
+@param d in: data, must not be NULL */
# define ha_insert_for_fold(t,f,b,d) ha_insert_for_fold_func(t,f,b,d)
#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+/**
+Inserts an entry into a hash table. If an entry with the same fold number
+is found, its node is updated to point to the new data, and no new node
+is inserted.
+@return TRUE if succeed, FALSE if no more memory could be allocated
+@param t in: hash table
+@param f in: folded value of data
+@param b ignored: buffer block containing the data
+@param d in: data, must not be NULL */
# define ha_insert_for_fold(t,f,b,d) ha_insert_for_fold_func(t,f,d)
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-/*****************************************************************
-Deletes an entry from a hash table. */
-UNIV_INTERN
-void
-ha_delete(
-/*======*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of data */
- void* data); /* in: data, must not be NULL and must exist
- in the hash table */
-/*************************************************************
+/*********************************************************//**
Looks for an element when we know the pointer to the data and deletes
-it from the hash table if found. */
+it from the hash table if found.
+@return TRUE if found */
UNIV_INLINE
ibool
ha_search_and_delete_if_found(
/*==========================*/
- /* out: TRUE if found */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data); /* in: pointer to the data */
-/*********************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data); /*!< in: pointer to the data */
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
points to the page given. */
UNIV_INTERN
void
ha_remove_all_nodes_to_page(
/*========================*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: fold value */
- const page_t* page); /* in: buffer page */
-/*****************************************************************
-Validates a given range of the cells in hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: fold value */
+ const page_t* page); /*!< in: buffer page */
+/*************************************************************//**
+Validates a given range of the cells in hash table.
+@return TRUE if ok */
UNIV_INTERN
ibool
ha_validate(
/*========*/
- /* out: TRUE if ok */
- hash_table_t* table, /* in: hash table */
- ulint start_index, /* in: start index */
- ulint end_index); /* in: end index */
-/*****************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint start_index, /*!< in: start index */
+ ulint end_index); /*!< in: end index */
+/*************************************************************//**
Prints info of a hash table. */
UNIV_INTERN
void
ha_print_info(
/*==========*/
- FILE* file, /* in: file where to print */
- hash_table_t* table); /* in: hash table */
-
-/* The hash table external chain node */
+ FILE* file, /*!< in: file where to print */
+ hash_table_t* table); /*!< in: hash table */
+#endif /* !UNIV_HOTBACKUP */
+/** The hash table external chain node */
typedef struct ha_node_struct ha_node_t;
+
+/** The hash table external chain node */
struct ha_node_struct {
- ha_node_t* next; /* next chain node or NULL if none */
+ ha_node_t* next; /*!< next chain node or NULL if none */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* block; /* buffer block containing the data, or NULL */
+ buf_block_t* block; /*!< buffer block containing the data, or NULL */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* data; /* pointer to the data */
- ulint fold; /* fold value for the data */
+ void* data; /*!< pointer to the data */
+ ulint fold; /*!< fold value for the data */
};
+#ifndef UNIV_HOTBACKUP
+/** Assert that the current thread is holding the mutex protecting a
+hash bucket corresponding to a fold value.
+@param table in: hash table
+@param fold in: fold value */
+# define ASSERT_HASH_MUTEX_OWN(table, fold) \
+ ut_ad(!(table)->mutexes || mutex_own(hash_get_mutex(table, fold)))
+#else /* !UNIV_HOTBACKUP */
+/** Assert that the current thread is holding the mutex protecting a
+hash bucket corresponding to a fold value.
+@param table in: hash table
+@param fold in: fold value */
+# define ASSERT_HASH_MUTEX_OWN(table, fold) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
+
#ifndef UNIV_NONINL
#include "ha0ha.ic"
#endif
diff --git a/storage/xtradb/include/ha0ha.ic b/storage/xtradb/include/ha0ha.ic
index 35fd802eaef..734403c4cd9 100644
--- a/storage/xtradb/include/ha0ha.ic
+++ b/storage/xtradb/include/ha0ha.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/ha0ha.ic
The hash table with external chains
Created 8/18/1994 Heikki Tuuri
@@ -25,38 +26,38 @@ Created 8/18/1994 Heikki Tuuri
#include "ut0rnd.h"
#include "mem0mem.h"
-/***************************************************************
+/***********************************************************//**
Deletes a hash node. */
UNIV_INTERN
void
ha_delete_hash_node(
/*================*/
- hash_table_t* table, /* in: hash table */
- ha_node_t* del_node); /* in: node to be deleted */
+ hash_table_t* table, /*!< in: hash table */
+ ha_node_t* del_node); /*!< in: node to be deleted */
-/**********************************************************************
-Gets a hash node data. */
+/******************************************************************//**
+Gets a hash node data.
+@return pointer to the data */
UNIV_INLINE
void*
ha_node_get_data(
/*=============*/
- /* out: pointer to the data */
- ha_node_t* node) /* in: hash chain node */
+ ha_node_t* node) /*!< in: hash chain node */
{
return(node->data);
}
-/**********************************************************************
+/******************************************************************//**
Sets hash node data. */
UNIV_INLINE
void
ha_node_set_data_func(
/*==================*/
- ha_node_t* node, /* in: hash chain node */
+ ha_node_t* node, /*!< in: hash chain node */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* block, /* in: buffer block containing the data */
+ buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* data) /* in: pointer to the data */
+ void* data) /*!< in: pointer to the data */
{
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
node->block = block;
@@ -65,52 +66,59 @@ ha_node_set_data_func(
}
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+/** Sets hash node data.
+@param n in: hash chain node
+@param b in: buffer block containing the data
+@param d in: pointer to the data */
# define ha_node_set_data(n,b,d) ha_node_set_data_func(n,b,d)
#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+/** Sets hash node data.
+@param n in: hash chain node
+@param b in: buffer block containing the data
+@param d in: pointer to the data */
# define ha_node_set_data(n,b,d) ha_node_set_data_func(n,d)
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-/**********************************************************************
-Gets the next node in a hash chain. */
+/******************************************************************//**
+Gets the next node in a hash chain.
+@return next node, NULL if none */
UNIV_INLINE
ha_node_t*
ha_chain_get_next(
/*==============*/
- /* out: next node, NULL if none */
- ha_node_t* node) /* in: hash chain node */
+ ha_node_t* node) /*!< in: hash chain node */
{
return(node->next);
}
-/**********************************************************************
-Gets the first node in a hash chain. */
+/******************************************************************//**
+Gets the first node in a hash chain.
+@return first node, NULL if none */
UNIV_INLINE
ha_node_t*
ha_chain_get_first(
/*===============*/
- /* out: first node, NULL if none */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold value determining the chain */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold value determining the chain */
{
return((ha_node_t*)
hash_get_nth_cell(table, hash_calc_hash(fold, table))->node);
}
-/*****************************************************************
-Looks for an element in a hash table. */
+/*************************************************************//**
+Looks for an element in a hash table.
+@return pointer to the first hash table node in chain having the fold
+number, NULL if not found */
UNIV_INLINE
ha_node_t*
ha_search(
/*======*/
- /* out: pointer to the first hash table node
- in chain having the fold number, NULL if not
- found */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: folded value of the searched data */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: folded value of the searched data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@@ -126,21 +134,20 @@ ha_search(
return(NULL);
}
-/*****************************************************************
-Looks for an element in a hash table. */
+/*************************************************************//**
+Looks for an element in a hash table.
+@return pointer to the data of the first hash table node in chain
+having the fold number, NULL if not found */
UNIV_INLINE
void*
ha_search_and_get_data(
/*===================*/
- /* out: pointer to the data of the first hash
- table node in chain having the fold number,
- NULL if not found */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: folded value of the searched data */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: folded value of the searched data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@@ -156,21 +163,20 @@ ha_search_and_get_data(
return(NULL);
}
-/*************************************************************
-Looks for an element when we know the pointer to the data. */
+/*********************************************************//**
+Looks for an element when we know the pointer to the data.
+@return pointer to the hash table node, NULL if not found in the table */
UNIV_INLINE
ha_node_t*
ha_search_with_data(
/*================*/
- /* out: pointer to the hash table node, NULL
- if not found in the table */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data) /* in: pointer to the data */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data) /*!< in: pointer to the data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@@ -186,21 +192,21 @@ ha_search_with_data(
return(NULL);
}
-/*************************************************************
+/*********************************************************//**
Looks for an element when we know the pointer to the data, and deletes
-it from the hash table, if found. */
+it from the hash table, if found.
+@return TRUE if found */
UNIV_INLINE
ibool
ha_search_and_delete_if_found(
/*==========================*/
- /* out: TRUE if found */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data) /* in: pointer to the data */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data) /*!< in: pointer to the data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_search_with_data(table, fold, data);
diff --git a/storage/xtradb/include/ha0storage.h b/storage/xtradb/include/ha0storage.h
index f5a3938f434..c30bd840579 100644
--- a/storage/xtradb/include/ha0storage.h
+++ b/storage/xtradb/include/ha0storage.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ha0storage.h
Hash storage.
Provides a data structure that stores chunks of data in
its own storage, avoiding duplicates.
@@ -29,29 +30,30 @@ Created September 22, 2007 Vasil Dimov
#include "univ.i"
-/* This value is used by default by ha_storage_create(). More memory
+/** This value is used by default by ha_storage_create(). More memory
is allocated later when/if it is needed. */
#define HA_STORAGE_DEFAULT_HEAP_BYTES 1024
-/* This value is used by default by ha_storage_create(). It is a
+/** This value is used by default by ha_storage_create(). It is a
constant per ha_storage's lifetime. */
#define HA_STORAGE_DEFAULT_HASH_CELLS 4096
+/** Hash storage */
typedef struct ha_storage_struct ha_storage_t;
-/***********************************************************************
+/*******************************************************************//**
Creates a hash storage. If any of the parameters is 0, then a default
-value is used. */
+value is used.
+@return own: hash storage */
UNIV_INLINE
ha_storage_t*
ha_storage_create(
/*==============*/
- /* out, own: hash storage */
- ulint initial_heap_bytes, /* in: initial heap's size */
- ulint initial_hash_cells); /* in: initial number of cells
+ ulint initial_heap_bytes, /*!< in: initial heap's size */
+ ulint initial_hash_cells); /*!< in: initial number of cells
in the hash table */
-/***********************************************************************
+/*******************************************************************//**
Copies data into the storage and returns a pointer to the copy. If the
same data chunk is already present, then pointer to it is returned.
Data chunks are considered to be equal if len1 == len2 and
@@ -59,40 +61,50 @@ memcmp(data1, data2, len1) == 0. If "data" is not present (and thus
data_len bytes need to be allocated) and the size of storage is going to
become more than "memlim" then "data" is not added and NULL is returned.
To disable this behavior "memlim" can be set to 0, which stands for
-"no limit". */
-
+"no limit".
+@return pointer to the copy */
+UNIV_INTERN
const void*
ha_storage_put_memlim(
/*==================*/
- /* out: pointer to the copy */
- ha_storage_t* storage, /* in/out: hash storage */
- const void* data, /* in: data to store */
- ulint data_len, /* in: data length */
- ulint memlim); /* in: memory limit to obey */
-
-/***********************************************************************
-Same as ha_storage_put_memlim() but without memory limit. */
-
+ ha_storage_t* storage, /*!< in/out: hash storage */
+ const void* data, /*!< in: data to store */
+ ulint data_len, /*!< in: data length */
+ ulint memlim); /*!< in: memory limit to obey */
+
+/*******************************************************************//**
+Same as ha_storage_put_memlim() but without memory limit.
+@param storage in/out: hash storage
+@param data in: data to store
+@param data_len in: data length
+@return pointer to the copy of the string */
#define ha_storage_put(storage, data, data_len) \
ha_storage_put_memlim((storage), (data), (data_len), 0)
-/***********************************************************************
+/*******************************************************************//**
Copies string into the storage and returns a pointer to the copy. If the
same string is already present, then pointer to it is returned.
-Strings are considered to be equal if strcmp(str1, str2) == 0. */
-
+Strings are considered to be equal if strcmp(str1, str2) == 0.
+@param storage in/out: hash storage
+@param str in: string to put
+@return pointer to the copy of the string */
#define ha_storage_put_str(storage, str) \
((const char*) ha_storage_put((storage), (str), strlen(str) + 1))
-/***********************************************************************
+/*******************************************************************//**
Copies string into the storage and returns a pointer to the copy obeying
-a memory limit. */
-
+a memory limit.
+If the same string is already present, then pointer to it is returned.
+Strings are considered to be equal if strcmp(str1, str2) == 0.
+@param storage in/out: hash storage
+@param str in: string to put
+@param memlim in: memory limit to obey
+@return pointer to the copy of the string */
#define ha_storage_put_str_memlim(storage, str, memlim) \
((const char*) ha_storage_put_memlim((storage), (str), \
strlen(str) + 1, (memlim)))
-/***********************************************************************
+/*******************************************************************//**
Empties a hash storage, freeing memory occupied by data chunks.
This invalidates any pointers previously returned by ha_storage_put().
The hash storage is not invalidated itself and can be used again. */
@@ -100,27 +112,26 @@ UNIV_INLINE
void
ha_storage_empty(
/*=============*/
- ha_storage_t** storage); /* in/out: hash storage */
+ ha_storage_t** storage); /*!< in/out: hash storage */
-/***********************************************************************
+/*******************************************************************//**
Frees a hash storage and everything it contains, it cannot be used after
this call.
-This invalidates any pointers previously returned by ha_storage_put().
-*/
+This invalidates any pointers previously returned by ha_storage_put(). */
UNIV_INLINE
void
ha_storage_free(
/*============*/
- ha_storage_t* storage); /* in/out: hash storage */
+ ha_storage_t* storage); /*!< in, own: hash storage */
-/***********************************************************************
-Gets the size of the memory used by a storage. */
+/*******************************************************************//**
+Gets the size of the memory used by a storage.
+@return bytes used */
UNIV_INLINE
ulint
ha_storage_get_size(
/*================*/
- /* out: bytes used */
- const ha_storage_t* storage); /* in: hash storage */
+ const ha_storage_t* storage); /*!< in: hash storage */
#ifndef UNIV_NONINL
#include "ha0storage.ic"
diff --git a/storage/xtradb/include/ha0storage.ic b/storage/xtradb/include/ha0storage.ic
index 7ab43bc00ba..5acbf82f005 100644
--- a/storage/xtradb/include/ha0storage.ic
+++ b/storage/xtradb/include/ha0storage.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ha0storage.ic
Hash storage.
Provides a data structure that stores chunks of data in
its own storage, avoiding duplicates.
@@ -29,31 +30,33 @@ Created September 24, 2007 Vasil Dimov
#include "hash0hash.h"
#include "mem0mem.h"
+/** Hash storage for strings */
struct ha_storage_struct {
- mem_heap_t* heap; /* storage from which memory is
+ mem_heap_t* heap; /*!< memory heap from which memory is
allocated */
- hash_table_t* hash; /* hash table used to avoid
+ hash_table_t* hash; /*!< hash table used to avoid
duplicates */
};
-/* Objects of this type are put in the hash */
+/** Objects of this type are stored in ha_storage_t */
typedef struct ha_storage_node_struct ha_storage_node_t;
+/** Objects of this type are stored in ha_storage_struct */
struct ha_storage_node_struct {
- ulint data_len;/* length of the data */
- const void* data; /* pointer to data */
- ha_storage_node_t* next; /* next node in hash chain */
+ ulint data_len;/*!< length of the data */
+ const void* data; /*!< pointer to data */
+ ha_storage_node_t* next; /*!< next node in hash chain */
};
-/***********************************************************************
+/*******************************************************************//**
Creates a hash storage. If any of the parameters is 0, then a default
-value is used. */
+value is used.
+@return own: hash storage */
UNIV_INLINE
ha_storage_t*
ha_storage_create(
/*==============*/
- /* out, own: hash storage */
- ulint initial_heap_bytes, /* in: initial heap's size */
- ulint initial_hash_cells) /* in: initial number of cells
+ ulint initial_heap_bytes, /*!< in: initial heap's size */
+ ulint initial_hash_cells) /*!< in: initial number of cells
in the hash table */
{
ha_storage_t* storage;
@@ -83,7 +86,7 @@ ha_storage_create(
return(storage);
}
-/***********************************************************************
+/*******************************************************************//**
Empties a hash storage, freeing memory occupied by data chunks.
This invalidates any pointers previously returned by ha_storage_put().
The hash storage is not invalidated itself and can be used again. */
@@ -91,7 +94,7 @@ UNIV_INLINE
void
ha_storage_empty(
/*=============*/
- ha_storage_t** storage) /* in/out: hash storage */
+ ha_storage_t** storage) /*!< in/out: hash storage */
{
ha_storage_t temp_storage;
@@ -108,16 +111,15 @@ ha_storage_empty(
(*storage)->hash = temp_storage.hash;
}
-/***********************************************************************
+/*******************************************************************//**
Frees a hash storage and everything it contains, it cannot be used after
this call.
-This invalidates any pointers previously returned by ha_storage_put().
-*/
+This invalidates any pointers previously returned by ha_storage_put(). */
UNIV_INLINE
void
ha_storage_free(
/*============*/
- ha_storage_t* storage) /* in/out: hash storage */
+ ha_storage_t* storage) /*!< in, own: hash storage */
{
/* order is important because the pointer storage->hash is
within the heap */
@@ -125,14 +127,14 @@ ha_storage_free(
mem_heap_free(storage->heap);
}
-/***********************************************************************
-Gets the size of the memory used by a storage. */
+/*******************************************************************//**
+Gets the size of the memory used by a storage.
+@return bytes used */
UNIV_INLINE
ulint
ha_storage_get_size(
/*================*/
- /* out: bytes used */
- const ha_storage_t* storage) /* in: hash storage */
+ const ha_storage_t* storage) /*!< in: hash storage */
{
ulint ret;
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 116242b32e4..e8789d1638b 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -16,126 +16,144 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*******************************************************************//**
+@file include/ha_prototypes.h
+Prototypes for global functions in ha_innodb.cc that are called by
+InnoDB C code
+
+Created 5/11/2006 Osku Salerma
+************************************************************************/
+
#ifndef HA_INNODB_PROTOTYPES_H
#define HA_INNODB_PROTOTYPES_H
-#ifndef UNIV_HOTBACKUP
-
-#include "univ.i" /* ulint, uint */
+#include "trx0types.h"
#include "m_ctype.h" /* CHARSET_INFO */
-/* Prototypes for global functions in ha_innodb.cc that are called by
-InnoDB's C-code. */
-
-/*************************************************************************
-Wrapper around MySQL's copy_and_convert function, see it for
-documentation. */
+/*********************************************************************//**
+Wrapper around MySQL's copy_and_convert function.
+@return number of bytes copied to 'to' */
UNIV_INTERN
ulint
innobase_convert_string(
/*====================*/
- void* to,
- ulint to_length,
- CHARSET_INFO* to_cs,
- const void* from,
- ulint from_length,
- CHARSET_INFO* from_cs,
- uint* errors);
-
-/***********************************************************************
+ void* to, /*!< out: converted string */
+ ulint to_length, /*!< in: number of bytes reserved
+ for the converted string */
+ CHARSET_INFO* to_cs, /*!< in: character set to convert to */
+ const void* from, /*!< in: string to convert */
+ ulint from_length, /*!< in: number of bytes to convert */
+ CHARSET_INFO* from_cs, /*!< in: character set to convert from */
+ uint* errors); /*!< out: number of errors encountered
+ during the conversion */
+
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
the result to "buf". The result is converted to "system_charset_info".
Not more than "buf_size" bytes are written to "buf".
-The result is always '\0'-terminated (provided buf_size > 0) and the
+The result is always NUL-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating NUL).
+@return number of bytes that were written */
UNIV_INTERN
ulint
innobase_raw_format(
/*================*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- ulint charset_coll, /* in: charset collation */
- char* buf, /* out: output buffer */
- ulint buf_size); /* in: output buffer size
+ ulint charset_coll, /*!< in: charset collation */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size); /*!< in: output buffer size
in bytes */
-
-/*********************************************************************
+
+/*****************************************************************//**
+Invalidates the MySQL query cache for the table. */
+UNIV_INTERN
+void
+innobase_invalidate_query_cache(
+/*============================*/
+ trx_t* trx, /*!< in: transaction which
+ modifies the table */
+ const char* full_name, /*!< in: concatenation of
+ database name, null char NUL,
+ table name, null char NUL;
+ NOTE that in Windows this is
+ always in LOWER CASE! */
+ ulint full_name_len); /*!< in: full name length where
+ also the null chars count */
+
+/*****************************************************************//**
Convert a table or index name to the MySQL system_charset_info (UTF-8)
-and quote it if needed. */
+and quote it if needed.
+@return pointer to the end of buf */
UNIV_INTERN
char*
innobase_convert_name(
/*==================*/
- /* out: pointer to the end of buf */
- char* buf, /* out: buffer for converted identifier */
- ulint buflen, /* in: length of buf, in bytes */
- const char* id, /* in: identifier to convert */
- ulint idlen, /* in: length of id, in bytes */
- void* thd, /* in: MySQL connection thread, or NULL */
- ibool table_id);/* in: TRUE=id is a table or database name;
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool table_id);/*!< in: TRUE=id is a table or database name;
FALSE=id is an index name */
-/**********************************************************************
+/******************************************************************//**
Returns true if the thread is the replication thread on the slave
server. Used in srv_conc_enter_innodb() to determine if the thread
should be allowed to enter InnoDB - the replication thread is treated
differently than other threads. Also used in
-srv_conc_force_exit_innodb(). */
+srv_conc_force_exit_innodb().
+@return true if thd is the replication thread */
UNIV_INTERN
ibool
thd_is_replication_slave_thread(
/*============================*/
- /* out: true if thd is the replication thread */
- void* thd); /* in: thread handle (THD*) */
+ void* thd); /*!< in: thread handle (THD*) */
-/**********************************************************************
+/******************************************************************//**
Returns true if the transaction this thread is processing has edited
non-transactional tables. Used by the deadlock detector when deciding
which transaction to rollback in case of a deadlock - we try to avoid
-rolling back transactions that have edited non-transactional tables. */
+rolling back transactions that have edited non-transactional tables.
+@return true if non-transactional tables have been edited */
UNIV_INTERN
ibool
thd_has_edited_nontrans_tables(
/*===========================*/
- /* out: true if non-transactional tables have
- been edited */
- void* thd); /* in: thread handle (THD*) */
+ void* thd); /*!< in: thread handle (THD*) */
-/*****************************************************************
+/*************************************************************//**
Prints info of a THD object (== user session thread) to the given file. */
UNIV_INTERN
void
innobase_mysql_print_thd(
/*=====================*/
- FILE* f, /* in: output stream */
- void* thd, /* in: pointer to a MySQL THD object */
- uint max_query_len); /* in: max query length to print, or 0 to
+ FILE* f, /*!< in: output stream */
+ void* thd, /*!< in: pointer to a MySQL THD object */
+ uint max_query_len); /*!< in: max query length to print, or 0 to
use the default max length */
-/******************************************************************
+/**************************************************************//**
Converts a MySQL type to an InnoDB type. Note that this function returns
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
-VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'. */
+VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
+@return DATA_BINARY, DATA_VARCHAR, ... */
UNIV_INTERN
ulint
get_innobase_type_from_mysql_type(
/*==============================*/
- /* out: DATA_BINARY,
- DATA_VARCHAR, ... */
- ulint* unsigned_flag, /* out: DATA_UNSIGNED if an
+ ulint* unsigned_flag, /*!< out: DATA_UNSIGNED if an
'unsigned type';
at least ENUM and SET,
and unsigned integer
types are 'unsigned types' */
- const void* field) /* in: MySQL Field */
+ const void* field) /*!< in: MySQL Field */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
If you want to print a thd that is not associated with the current thread,
you must call this function before reserving the InnoDB kernel_mutex, to
protect MySQL from setting thd->query NULL. If you print a thd of the current
@@ -147,7 +165,7 @@ void
innobase_mysql_prepare_print_arbitrary_thd(void);
/*============================================*/
-/*****************************************************************
+/*************************************************************//**
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
In the InnoDB latching order, the mutex sits right above the
kernel_mutex. In debug builds, we assert that the kernel_mutex is
@@ -157,93 +175,109 @@ void
innobase_mysql_end_print_arbitrary_thd(void);
/*========================================*/
-/**********************************************************************
+/******************************************************************//**
Get the variable length bounds of the given character set. */
UNIV_INTERN
void
innobase_get_cset_width(
/*====================*/
- ulint cset, /* in: MySQL charset-collation code */
- ulint* mbminlen, /* out: minimum length of a char (in bytes) */
- ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */
+ ulint cset, /*!< in: MySQL charset-collation code */
+ ulint* mbminlen, /*!< out: minimum length of a char (in bytes) */
+ ulint* mbmaxlen); /*!< out: maximum length of a char (in bytes) */
-/**********************************************************************
-Compares NUL-terminated UTF-8 strings case insensitively. */
+/******************************************************************//**
+Compares NUL-terminated UTF-8 strings case insensitively.
+@return 0 if a=b, <0 if a<b, >1 if a>b */
UNIV_INTERN
int
innobase_strcasecmp(
/*================*/
- /* out: 0 if a=b, <0 if a<b, >1 if a>b */
- const char* a, /* in: first string to compare */
- const char* b); /* in: second string to compare */
+ const char* a, /*!< in: first string to compare */
+ const char* b); /*!< in: second string to compare */
-/**********************************************************************
-Returns true if the thread is executing a SELECT statement. */
+/******************************************************************//**
+Returns true if the thread is executing a SELECT statement.
+@return true if thd is executing SELECT */
ibool
thd_is_select(
/*==========*/
- /* out: true if thd is executing SELECT */
- const void* thd); /* in: thread handle (THD*) */
+ const void* thd); /*!< in: thread handle (THD*) */
-/**********************************************************************
+/******************************************************************//**
Converts an identifier to a table name. */
UNIV_INTERN
void
innobase_convert_from_table_id(
/*===========================*/
- struct charset_info_st* cs, /* in: the 'from' character set */
- char* to, /* out: converted identifier */
- const char* from, /* in: identifier to convert */
- ulint len); /* in: length of 'to', in bytes; should
+ struct charset_info_st* cs, /*!< in: the 'from' character set */
+ char* to, /*!< out: converted identifier */
+ const char* from, /*!< in: identifier to convert */
+ ulint len); /*!< in: length of 'to', in bytes; should
be at least 5 * strlen(to) + 1 */
-/**********************************************************************
+/******************************************************************//**
Converts an identifier to UTF-8. */
UNIV_INTERN
void
innobase_convert_from_id(
/*=====================*/
- struct charset_info_st* cs, /* in: the 'from' character set */
- char* to, /* out: converted identifier */
- const char* from, /* in: identifier to convert */
- ulint len); /* in: length of 'to', in bytes; should
+ struct charset_info_st* cs, /*!< in: the 'from' character set */
+ char* to, /*!< out: converted identifier */
+ const char* from, /*!< in: identifier to convert */
+ ulint len); /*!< in: length of 'to', in bytes; should
be at least 3 * strlen(to) + 1 */
-/**********************************************************************
+/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
void
innobase_casedn_str(
/*================*/
- char* a); /* in/out: string to put in lower case */
+ char* a); /*!< in/out: string to put in lower case */
-/**************************************************************************
-Determines the connection character set. */
+/**********************************************************************//**
+Determines the connection character set.
+@return connection character set */
struct charset_info_st*
innobase_get_charset(
/*=================*/
- /* out: connection character set */
- void* mysql_thd); /* in: MySQL thread handle */
+ void* mysql_thd); /*!< in: MySQL thread handle */
-/**********************************************************************
+/******************************************************************//**
+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
+finds charset information and returns length of prefix_len characters in the
+index field in bytes.
+@return number of bytes occupied by the first n characters */
+UNIV_INTERN
+ulint
+innobase_get_at_most_n_mbchars(
+/*===========================*/
+ ulint charset_id, /*!< in: character set id */
+ ulint prefix_len, /*!< in: prefix length in bytes of the index
+ (this has to be divided by mbmaxlen to get the
+ number of CHARACTERS n in the prefix) */
+ ulint data_len, /*!< in: length of the string in bytes */
+ const char* str); /*!< in: character string */
+
+/******************************************************************//**
Returns true if the thread supports XA,
-global value of innodb_supports_xa if thd is NULL. */
+global value of innodb_supports_xa if thd is NULL.
+@return true if thd supports XA */
ibool
thd_supports_xa(
/*============*/
- /* out: true if thd supports XA */
- void* thd); /* in: thread handle (THD*), or NULL to query
+ void* thd); /*!< in: thread handle (THD*), or NULL to query
the global innodb_supports_xa */
-/**********************************************************************
-Returns the lock wait timeout for the current connection. */
+/******************************************************************//**
+Returns the lock wait timeout for the current connection.
+@return the lock wait timeout, in seconds */
ulong
thd_lock_wait_timeout(
/*==================*/
- /* out: the lock wait timeout, in seconds */
- void* thd); /* in: thread handle (THD*), or NULL to query
+ void* thd); /*!< in: thread handle (THD*), or NULL to query
the global innodb_lock_wait_timeout */
#endif
-#endif
diff --git a/storage/xtradb/include/handler0alter.h b/storage/xtradb/include/handler0alter.h
index 69488b67b2b..985b76f4f50 100644
--- a/storage/xtradb/include/handler0alter.h
+++ b/storage/xtradb/include/handler0alter.h
@@ -16,26 +16,27 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/handler0alter.h
Smart ALTER TABLE
*******************************************************/
-/*****************************************************************
+/*************************************************************//**
Copies an InnoDB record to table->record[0]. */
UNIV_INTERN
void
innobase_rec_to_mysql(
/*==================*/
- 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(
+ 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(
rec, index, ...) */
-/*****************************************************************
+/*************************************************************//**
Resets table->record[0]. */
UNIV_INTERN
void
innobase_rec_reset(
/*===============*/
- TABLE* table); /* in/out: MySQL table */
+ TABLE* table); /*!< in/out: MySQL table */
diff --git a/storage/xtradb/include/hash0hash.h b/storage/xtradb/include/hash0hash.h
index 2b3eea62754..977cb829f35 100644
--- a/storage/xtradb/include/hash0hash.h
+++ b/storage/xtradb/include/hash0hash.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/hash0hash.h
The simple hash table utility
Created 5/20/1997 Heikki Tuuri
@@ -27,7 +28,9 @@ Created 5/20/1997 Heikki Tuuri
#include "univ.i"
#include "mem0mem.h"
-#include "sync0sync.h"
+#ifndef UNIV_HOTBACKUP
+# include "sync0sync.h"
+#endif /* !UNIV_HOTBACKUP */
typedef struct hash_table_struct hash_table_t;
typedef struct hash_cell_struct hash_cell_t;
@@ -37,55 +40,61 @@ typedef void* hash_node_t;
/* Fix Bug #13859: symbol collision between imap/mysql */
#define hash_create hash0_create
-/*****************************************************************
+/*************************************************************//**
Creates a hash table with >= n array cells. The actual number
-of cells is chosen to be a prime number slightly bigger than n. */
+of cells is chosen to be a prime number slightly bigger than n.
+@return own: created table */
UNIV_INTERN
hash_table_t*
hash_create(
/*========*/
- /* out, own: created table */
- ulint n); /* in: number of array cells */
-/*****************************************************************
+ ulint n); /*!< in: number of array cells */
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Creates a mutex array to protect a hash table. */
UNIV_INTERN
void
hash_create_mutexes_func(
/*=====================*/
- hash_table_t* table, /* in: hash table */
+ hash_table_t* table, /*!< in: hash table */
#ifdef UNIV_SYNC_DEBUG
- ulint sync_level, /* in: latching order level of the
+ ulint sync_level, /*!< in: latching order level of the
mutexes: used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes); /* in: number of mutexes */
+ ulint n_mutexes); /*!< in: number of mutexes */
#ifdef UNIV_SYNC_DEBUG
# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,level,n)
#else /* UNIV_SYNC_DEBUG */
# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,n)
#endif /* UNIV_SYNC_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Frees a hash table. */
UNIV_INTERN
void
hash_table_free(
/*============*/
- hash_table_t* table); /* in, own: hash table */
-/******************************************************************
-Calculates the hash value from a folded value. */
+ hash_table_t* table); /*!< in, own: hash table */
+/**************************************************************//**
+Calculates the hash value from a folded value.
+@return hashed value */
UNIV_INLINE
ulint
hash_calc_hash(
/*===========*/
- /* out: hashed value */
- ulint fold, /* in: folded value */
- hash_table_t* table); /* in: hash table */
-/************************************************************************
+ ulint fold, /*!< in: folded value */
+ hash_table_t* table); /*!< in: hash table */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Assert that the mutex for the table in a hash operation is owned. */
-#define HASH_ASSERT_OWNED(TABLE, FOLD) \
+# define HASH_ASSERT_OWNED(TABLE, FOLD) \
ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));
+#else /* !UNIV_HOTBACKUP */
+# define HASH_ASSERT_OWNED(TABLE, FOLD)
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
+/*******************************************************************//**
Inserts a struct to a hash table. */
#define HASH_INSERT(TYPE, NAME, TABLE, FOLD, DATA)\
@@ -121,7 +130,7 @@ do {\
# define HASH_INVALIDATE(DATA, NAME) do {} while (0)
#endif
-/***********************************************************************
+/*******************************************************************//**
Deletes a struct from a hash table. */
#define HASH_DELETE(TYPE, NAME, TABLE, FOLD, DATA)\
@@ -150,18 +159,18 @@ do {\
HASH_INVALIDATE(DATA, NAME);\
} while (0)
-/***********************************************************************
+/*******************************************************************//**
Gets the first struct in a hash chain, NULL if none. */
#define HASH_GET_FIRST(TABLE, HASH_VAL)\
(hash_get_nth_cell(TABLE, HASH_VAL)->node)
-/***********************************************************************
+/*******************************************************************//**
Gets the next struct in a hash chain, NULL if none. */
#define HASH_GET_NEXT(NAME, DATA) ((DATA)->NAME)
-/************************************************************************
+/********************************************************************//**
Looks for a struct in a hash table. */
#define HASH_SEARCH(NAME, TABLE, FOLD, TYPE, DATA, ASSERTION, TEST)\
{\
@@ -182,7 +191,7 @@ Looks for a struct in a hash table. */
}\
}
-/************************************************************************
+/********************************************************************//**
Looks for an item in all hash buckets. */
#define HASH_SEARCH_ALL(NAME, TABLE, TYPE, DATA, ASSERTION, TEST) \
do { \
@@ -208,33 +217,33 @@ do { \
} \
} while (0)
-/****************************************************************
-Gets the nth cell in a hash table. */
+/************************************************************//**
+Gets the nth cell in a hash table.
+@return pointer to cell */
UNIV_INLINE
hash_cell_t*
hash_get_nth_cell(
/*==============*/
- /* out: pointer to cell */
- hash_table_t* table, /* in: hash table */
- ulint n); /* in: cell index */
+ hash_table_t* table, /*!< in: hash table */
+ ulint n); /*!< in: cell index */
-/*****************************************************************
+/*************************************************************//**
Clears a hash table so that all the cells become empty. */
UNIV_INLINE
void
hash_table_clear(
/*=============*/
- hash_table_t* table); /* in/out: hash table */
+ hash_table_t* table); /*!< in/out: hash table */
-/*****************************************************************
-Returns the number of cells in a hash table. */
+/*************************************************************//**
+Returns the number of cells in a hash table.
+@return number of cells */
UNIV_INLINE
ulint
hash_get_n_cells(
/*=============*/
- /* out: number of cells */
- hash_table_t* table); /* in: table */
-/***********************************************************************
+ hash_table_t* table); /*!< in: table */
+/*******************************************************************//**
Deletes a struct which is stored in the heap of the hash table, and compacts
the heap. The fold value must be stored in the struct NODE in a field named
'fold'. */
@@ -293,8 +302,9 @@ do {\
mem_heap_free_top(hash_get_heap(TABLE, fold111), sizeof(TYPE));\
} while (0)
-/********************************************************************
-Move all hash table entries from OLD_TABLE to NEW_TABLE.*/
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
+Move all hash table entries from OLD_TABLE to NEW_TABLE. */
#define HASH_MIGRATE(OLD_TABLE, NEW_TABLE, NODE_TYPE, PTR_NAME, FOLD_FUNC) \
do {\
@@ -318,104 +328,111 @@ do {\
}\
} while (0)
-
-/****************************************************************
-Gets the mutex index for a fold value in a hash table. */
+/************************************************************//**
+Gets the mutex index for a fold value in a hash table.
+@return mutex number */
UNIV_INLINE
ulint
hash_get_mutex_no(
/*==============*/
- /* out: mutex number */
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
-Gets the nth heap in a hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
+Gets the nth heap in a hash table.
+@return mem heap */
UNIV_INLINE
mem_heap_t*
hash_get_nth_heap(
/*==============*/
- /* out: mem heap */
- hash_table_t* table, /* in: hash table */
- ulint i); /* in: index of the heap */
-/****************************************************************
-Gets the heap for a fold value in a hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint i); /*!< in: index of the heap */
+/************************************************************//**
+Gets the heap for a fold value in a hash table.
+@return mem heap */
UNIV_INLINE
mem_heap_t*
hash_get_heap(
/*==========*/
- /* out: mem heap */
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
-Gets the nth mutex in a hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
+Gets the nth mutex in a hash table.
+@return mutex */
UNIV_INLINE
mutex_t*
hash_get_nth_mutex(
/*===============*/
- /* out: mutex */
- hash_table_t* table, /* in: hash table */
- ulint i); /* in: index of the mutex */
-/****************************************************************
-Gets the mutex for a fold value in a hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint i); /*!< in: index of the mutex */
+/************************************************************//**
+Gets the mutex for a fold value in a hash table.
+@return mutex */
UNIV_INLINE
mutex_t*
hash_get_mutex(
/*===========*/
- /* out: mutex */
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
Reserves the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_enter(
/*=============*/
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
Releases the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_exit(
/*============*/
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
Reserves all the mutexes of a hash table, in an ascending order. */
UNIV_INTERN
void
hash_mutex_enter_all(
/*=================*/
- hash_table_t* table); /* in: hash table */
-/****************************************************************
+ hash_table_t* table); /*!< in: hash table */
+/************************************************************//**
Releases all the mutexes of a hash table. */
UNIV_INTERN
void
hash_mutex_exit_all(
/*================*/
- hash_table_t* table); /* in: hash table */
-
+ hash_table_t* table); /*!< in: hash table */
+#else /* !UNIV_HOTBACKUP */
+# define hash_get_heap(table, fold) ((table)->heap)
+# define hash_mutex_enter(table, fold) ((void) 0)
+# define hash_mutex_exit(table, fold) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
struct hash_cell_struct{
- void* node; /* hash chain node, NULL if none */
+ void* node; /*!< hash chain node, NULL if none */
};
/* The hash table structure */
struct hash_table_struct {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
ibool adaptive;/* TRUE if this is the hash table of the
adaptive hash index */
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
ulint n_cells;/* number of cells in the hash table */
- hash_cell_t* array; /* pointer to cell array */
+ hash_cell_t* array; /*!< pointer to cell array */
+#ifndef UNIV_HOTBACKUP
ulint n_mutexes;/* if mutexes != NULL, then the number of
mutexes, must be a power of 2 */
mutex_t* mutexes;/* NULL, or an array of mutexes used to
protect segments of the hash table */
- mem_heap_t** heaps; /* if this is non-NULL, hash chain nodes for
+ mem_heap_t** heaps; /*!< if this is non-NULL, hash chain nodes for
external chaining can be allocated from these
memory heaps; there are then n_mutexes many of
these heaps */
+#endif /* !UNIV_HOTBACKUP */
mem_heap_t* heap;
ulint magic_n;
};
diff --git a/storage/xtradb/include/hash0hash.ic b/storage/xtradb/include/hash0hash.ic
index 792fdcbf4f8..19da2d50701 100644
--- a/storage/xtradb/include/hash0hash.ic
+++ b/storage/xtradb/include/hash0hash.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/hash0hash.ic
The simple hash table utility
Created 5/20/1997 Heikki Tuuri
@@ -24,97 +25,98 @@ Created 5/20/1997 Heikki Tuuri
#include "ut0rnd.h"
-/****************************************************************
-Gets the nth cell in a hash table. */
+/************************************************************//**
+Gets the nth cell in a hash table.
+@return pointer to cell */
UNIV_INLINE
hash_cell_t*
hash_get_nth_cell(
/*==============*/
- /* out: pointer to cell */
- hash_table_t* table, /* in: hash table */
- ulint n) /* in: cell index */
+ hash_table_t* table, /*!< in: hash table */
+ ulint n) /*!< in: cell index */
{
ut_ad(n < table->n_cells);
return(table->array + n);
}
-/*****************************************************************
+/*************************************************************//**
Clears a hash table so that all the cells become empty. */
UNIV_INLINE
void
hash_table_clear(
/*=============*/
- hash_table_t* table) /* in/out: hash table */
+ hash_table_t* table) /*!< in/out: hash table */
{
memset(table->array, 0x0,
table->n_cells * sizeof(*table->array));
}
-/*****************************************************************
-Returns the number of cells in a hash table. */
+/*************************************************************//**
+Returns the number of cells in a hash table.
+@return number of cells */
UNIV_INLINE
ulint
hash_get_n_cells(
/*=============*/
- /* out: number of cells */
- hash_table_t* table) /* in: table */
+ hash_table_t* table) /*!< in: table */
{
return(table->n_cells);
}
-/******************************************************************
-Calculates the hash value from a folded value. */
+/**************************************************************//**
+Calculates the hash value from a folded value.
+@return hashed value */
UNIV_INLINE
ulint
hash_calc_hash(
/*===========*/
- /* out: hashed value */
- ulint fold, /* in: folded value */
- hash_table_t* table) /* in: hash table */
+ ulint fold, /*!< in: folded value */
+ hash_table_t* table) /*!< in: hash table */
{
return(ut_hash_ulint(fold, table->n_cells));
}
-/****************************************************************
-Gets the mutex index for a fold value in a hash table. */
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
+Gets the mutex index for a fold value in a hash table.
+@return mutex number */
UNIV_INLINE
ulint
hash_get_mutex_no(
/*==============*/
- /* out: mutex number */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
ut_ad(ut_is_2pow(table->n_mutexes));
return(ut_2pow_remainder(hash_calc_hash(fold, table),
table->n_mutexes));
}
-/****************************************************************
-Gets the nth heap in a hash table. */
+/************************************************************//**
+Gets the nth heap in a hash table.
+@return mem heap */
UNIV_INLINE
mem_heap_t*
hash_get_nth_heap(
/*==============*/
- /* out: mem heap */
- hash_table_t* table, /* in: hash table */
- ulint i) /* in: index of the heap */
+ hash_table_t* table, /*!< in: hash table */
+ ulint i) /*!< in: index of the heap */
{
ut_ad(i < table->n_mutexes);
return(table->heaps[i]);
}
-/****************************************************************
-Gets the heap for a fold value in a hash table. */
+/************************************************************//**
+Gets the heap for a fold value in a hash table.
+@return mem heap */
UNIV_INLINE
mem_heap_t*
hash_get_heap(
/*==========*/
- /* out: mem heap */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
ulint i;
@@ -127,30 +129,30 @@ hash_get_heap(
return(hash_get_nth_heap(table, i));
}
-/****************************************************************
-Gets the nth mutex in a hash table. */
+/************************************************************//**
+Gets the nth mutex in a hash table.
+@return mutex */
UNIV_INLINE
mutex_t*
hash_get_nth_mutex(
/*===============*/
- /* out: mutex */
- hash_table_t* table, /* in: hash table */
- ulint i) /* in: index of the mutex */
+ hash_table_t* table, /*!< in: hash table */
+ ulint i) /*!< in: index of the mutex */
{
ut_ad(i < table->n_mutexes);
return(table->mutexes + i);
}
-/****************************************************************
-Gets the mutex for a fold value in a hash table. */
+/************************************************************//**
+Gets the mutex for a fold value in a hash table.
+@return mutex */
UNIV_INLINE
mutex_t*
hash_get_mutex(
/*===========*/
- /* out: mutex */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
ulint i;
@@ -158,3 +160,4 @@ hash_get_mutex(
return(hash_get_nth_mutex(table, i));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/ibuf0ibuf.h b/storage/xtradb/include/ibuf0ibuf.h
index 41e2392cc4a..8aa21fb9d95 100644
--- a/storage/xtradb/include/ibuf0ibuf.h
+++ b/storage/xtradb/include/ibuf0ibuf.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ibuf0ibuf.h
Insert buffer
Created 7/19/1997 Heikki Tuuri
@@ -27,12 +28,13 @@ Created 7/19/1997 Heikki Tuuri
#include "univ.i"
-#include "dict0mem.h"
#include "mtr0mtr.h"
-#include "que0types.h"
-#include "ibuf0types.h"
+#include "dict0mem.h"
#include "fsp0fsp.h"
+#ifndef UNIV_HOTBACKUP
+# include "ibuf0types.h"
+
/** Combinations of operations that can be buffered. Because the enum
values are used for indexing innobase_change_buffering_values[], they
should start at 0 and there should not be any gaps. */
@@ -69,29 +71,29 @@ affects the free space. It is unsafe to increment the bits in a
separately committed mini-transaction, because in crash recovery, the
free bits could momentarily be set too high. */
-/**********************************************************************
+/******************************************************************//**
Creates the insert buffer data structure at a database startup and
initializes the data structures for the insert buffer of each tablespace. */
UNIV_INTERN
void
ibuf_init_at_db_start(void);
/*=======================*/
-/*************************************************************************
+/*********************************************************************//**
Reads the biggest tablespace id from the high end of the insert buffer
tree and updates the counter in fil_system. */
UNIV_INTERN
void
ibuf_update_max_tablespace_id(void);
/*===============================*/
-/*************************************************************************
+/*********************************************************************//**
Initializes an ibuf bitmap page. */
UNIV_INTERN
void
ibuf_bitmap_page_init(
/*==================*/
- buf_block_t* block, /* in: bitmap page */
- mtr_t* mtr); /* in: mtr */
-/****************************************************************************
+ buf_block_t* block, /*!< in: bitmap page */
+ mtr_t* mtr); /*!< in: mtr */
+/************************************************************************//**
Resets the free bits of the page in the ibuf bitmap. This is done in a
separate mini-transaction, hence this operation does not restrict
further work to only ibuf bitmap operations, which would result if the
@@ -104,10 +106,10 @@ UNIV_INTERN
void
ibuf_reset_free_bits(
/*=================*/
- buf_block_t* block); /* in: index page; free bits are set to 0
+ buf_block_t* block); /*!< in: index page; free bits are set to 0
if the index is a non-clustered
non-unique, and page level is 0 */
-/****************************************************************************
+/************************************************************************//**
Updates the free bits of an uncompressed page in the ibuf bitmap if
there is not enough free on the page any more. This is done in a
separate mini-transaction, hence this operation does not restrict
@@ -124,18 +126,18 @@ UNIV_INLINE
void
ibuf_update_free_bits_if_full(
/*==========================*/
- buf_block_t* block, /* in: index page to which we have added new
+ buf_block_t* block, /*!< in: index page to which we have added new
records; the free bits are updated if the
index is non-clustered and non-unique and
the page level is 0, and the page becomes
fuller */
- ulint max_ins_size,/* in: value of maximum insert size with
+ ulint max_ins_size,/*!< in: value of maximum insert size with
reorganize before the latest operation
performed to the page */
- ulint increase);/* in: upper limit for the additional space
+ ulint increase);/*!< in: upper limit for the additional space
used in the latest operation, if known, or
ULINT_UNDEFINED */
-/**************************************************************************
+/**********************************************************************//**
Updates the free bits for an uncompressed page to reflect the present
state. Does this in the mtr given, which means that the latching
order rules virtually prevent any further operations for this OS
@@ -147,14 +149,14 @@ UNIV_INTERN
void
ibuf_update_free_bits_low(
/*======================*/
- const buf_block_t* block, /* in: index page */
- ulint max_ins_size, /* in: value of
+ const buf_block_t* block, /*!< in: index page */
+ ulint max_ins_size, /*!< in: value of
maximum insert size
with reorganize before
the latest operation
performed to the page */
- mtr_t* mtr); /* in/out: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in/out: mtr */
+/**********************************************************************//**
Updates the free bits for a compressed page to reflect the present
state. Does this in the mtr given, which means that the latching
order rules virtually prevent any further operations for this OS
@@ -166,9 +168,9 @@ UNIV_INTERN
void
ibuf_update_free_bits_zip(
/*======================*/
- buf_block_t* block, /* in/out: index page */
- mtr_t* mtr); /* in/out: mtr */
-/**************************************************************************
+ buf_block_t* block, /*!< in/out: index page */
+ mtr_t* mtr); /*!< in/out: mtr */
+/**********************************************************************//**
Updates the free bits for the two pages to reflect the present state.
Does this in the mtr given, which means that the latching order rules
virtually prevent any further operations until mtr is committed.
@@ -179,58 +181,60 @@ UNIV_INTERN
void
ibuf_update_free_bits_for_two_pages_low(
/*====================================*/
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- buf_block_t* block1, /* in: index page */
- buf_block_t* block2, /* in: index page */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ buf_block_t* block1, /*!< in: index page */
+ buf_block_t* block2, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
A basic partial test if an insert to the insert buffer could be possible and
recommended. */
UNIV_INLINE
ibool
ibuf_should_try(
/*============*/
- dict_index_t* index, /* in: index where to insert */
- ulint ignore_sec_unique); /* in: if != 0, we should
+ dict_index_t* index, /*!< in: index where to insert */
+ ulint ignore_sec_unique); /*!< in: if != 0, we should
ignore UNIQUE constraint on
a secondary index when we
decide */
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if the current OS thread is performing an insert buffer
-routine. */
+routine.
+
+For instance, a read-ahead of non-ibuf pages is forbidden by threads
+that are executing an insert buffer routine.
+@return TRUE if inside an insert buffer routine */
UNIV_INTERN
ibool
ibuf_inside(void);
/*=============*/
- /* out: TRUE if inside an insert buffer routine: for instance,
- a read-ahead of non-ibuf pages is then forbidden */
-/***************************************************************************
-Checks if a page address is an ibuf bitmap page (level 3 page) address. */
+/***********************************************************************//**
+Checks if a page address is an ibuf bitmap page (level 3 page) address.
+@return TRUE if a bitmap page */
UNIV_INLINE
ibool
ibuf_bitmap_page(
/*=============*/
- /* out: TRUE if a bitmap page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no);/* in: page number */
-/***************************************************************************
+ ulint page_no);/*!< in: page number */
+/***********************************************************************//**
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
-Must not be called when recv_no_ibuf_operations==TRUE. */
+Must not be called when recv_no_ibuf_operations==TRUE.
+@return TRUE if level 2 or level 3 page */
UNIV_INTERN
ibool
ibuf_page(
/*======*/
- /* out: TRUE if level 2 or level 3 page */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number */
- mtr_t* mtr); /* in: mtr which will contain an x-latch to the
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number */
+ mtr_t* mtr); /*!< in: mtr which will contain an x-latch to the
bitmap page if the page is not one of the fixed
address ibuf pages, or NULL, in which case a new
transaction is created. */
-/***************************************************************************
+/***********************************************************************//**
Frees excess pages from the ibuf free list. This function is called when an OS
thread calls fsp services to allocate a new file segment, or a new page to a
file segment, and the thread did not own the fsp latch before this call. */
@@ -238,22 +242,22 @@ UNIV_INTERN
void
ibuf_free_excess_pages(void);
/*========================*/
-/*************************************************************************
+/*********************************************************************//**
Makes an index insert to the insert buffer, instead of directly to the disk
page, if this is possible. Does not do insert if the index is clustered
-or unique. */
+or unique.
+@return TRUE if success */
UNIV_INTERN
ibool
ibuf_insert(
/*========*/
- /* out: TRUE if success */
- const dtuple_t* entry, /* in: index entry to insert */
- dict_index_t* index, /* in: index where to insert */
- ulint space, /* in: space id where to insert */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number where to insert */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ const dtuple_t* entry, /*!< in: index entry to insert */
+ dict_index_t* index, /*!< in: index where to insert */
+ ulint space, /*!< in: space id where to insert */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number where to insert */
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
When an index page is read from a disk to the buffer pool, this function
inserts to the page the possible index entries buffered in the insert buffer.
The entries are deleted from the insert buffer. If the page is not read, but
@@ -264,19 +268,19 @@ UNIV_INTERN
void
ibuf_merge_or_delete_for_page(
/*==========================*/
- buf_block_t* block, /* in: if page has been read from
+ buf_block_t* block, /*!< in: if page has been read from
disk, pointer to the page x-latched,
else NULL */
- ulint space, /* in: space id of the index page */
- ulint page_no,/* in: page number of the index page */
- ulint zip_size,/* in: compressed page size in bytes,
+ ulint space, /*!< in: space id of the index page */
+ ulint page_no,/*!< in: page number of the index page */
+ ulint zip_size,/*!< in: compressed page size in bytes,
or 0 */
- ibool update_ibuf_bitmap);/* in: normally this is set
+ ibool update_ibuf_bitmap);/*!< in: normally this is set
to TRUE, but if we have deleted or are
deleting the tablespace, then we
naturally do not want to update a
non-existent bitmap page */
-/*************************************************************************
+/*********************************************************************//**
Deletes all entries in the insert buffer for a given space id. This is used
in DISCARD TABLESPACE and IMPORT TABLESPACE.
NOTE: this does not update the page free bitmaps in the space. The space will
@@ -285,75 +289,85 @@ UNIV_INTERN
void
ibuf_delete_for_discarded_space(
/*============================*/
- ulint space); /* in: space id */
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+ ulint space); /*!< in: space id */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
UNIV_INTERN
ulint
ibuf_contract(
/*==========*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ibool sync); /* in: TRUE if the caller wants to wait for the
+ ibool sync); /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
UNIV_INTERN
ulint
ibuf_contract_for_n_pages(
/*======================*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ibool sync, /* in: TRUE if the caller wants to wait for the
+ ibool sync, /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
- ulint n_pages);/* in: try to read at least this many pages to
+ ulint n_pages);/*!< in: try to read at least this many pages to
the buffer pool and merge the ibuf contents to
them */
-/*************************************************************************
-Parses a redo log record of an ibuf bitmap page init. */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Parses a redo log record of an ibuf bitmap page init.
+@return end of log record or NULL */
UNIV_INTERN
byte*
ibuf_parse_bitmap_init(
/*===================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: block or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: block or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_IBUF_COUNT_DEBUG
-/**********************************************************************
-Gets the ibuf count for a given page. */
+/******************************************************************//**
+Gets the ibuf count for a given page.
+@return number of entries in the insert buffer currently buffered for
+this page */
UNIV_INTERN
ulint
ibuf_count_get(
/*===========*/
- /* out: number of entries in the insert buffer
- currently buffered for this page */
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no);/*!< in: page number */
#endif
-/**********************************************************************
-Looks if the insert buffer is empty. */
+/******************************************************************//**
+Looks if the insert buffer is empty.
+@return TRUE if empty */
UNIV_INTERN
ibool
ibuf_is_empty(void);
/*===============*/
- /* out: TRUE if empty */
-/**********************************************************************
+/******************************************************************//**
Prints info of ibuf. */
UNIV_INTERN
void
ibuf_print(
/*=======*/
- FILE* file); /* in: file where to print */
+ FILE* file); /*!< in: file where to print */
+/******************************************************************//**
+Closes insert buffer and frees the data structures. */
+UNIV_INTERN
+void
+ibuf_close(void);
+/*============*/
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
+#endif /* !UNIV_HOTBACKUP */
+
/* The ibuf header page currently contains only the file segment header
for the file segment from which the pages for the ibuf tree are allocated */
#define IBUF_HEADER PAGE_DATA
diff --git a/storage/xtradb/include/ibuf0ibuf.ic b/storage/xtradb/include/ibuf0ibuf.ic
index 170e5dba473..15bbe61ab30 100644
--- a/storage/xtradb/include/ibuf0ibuf.ic
+++ b/storage/xtradb/include/ibuf0ibuf.ic
@@ -16,50 +16,52 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ibuf0ibuf.ic
Insert buffer
Created 7/19/1997 Heikki Tuuri
*******************************************************/
-#include "buf0lru.h"
#include "page0page.h"
#include "page0zip.h"
+#ifndef UNIV_HOTBACKUP
+#include "buf0lru.h"
+/** Counter for ibuf_should_try() */
extern ulint ibuf_flush_count;
-/* If this number is n, an index page must contain at least the page size
-per n bytes of free space for ibuf to try to buffer inserts to this page.
-If there is this much of free space, the corresponding bits are set in the
-ibuf bitmap. */
+/** An index page must contain at least UNIV_PAGE_SIZE /
+IBUF_PAGE_SIZE_PER_FREE_SPACE bytes of free space for ibuf to try to
+buffer inserts to this page. If there is this much of free space, the
+corresponding bits are set in the ibuf bitmap. */
#define IBUF_PAGE_SIZE_PER_FREE_SPACE 32
-/* Insert buffer struct */
-
+/** Insert buffer struct */
struct ibuf_struct{
- ulint size; /* current size of the ibuf index
+ ulint size; /*!< current size of the ibuf index
tree, in pages */
- ulint max_size; /* recommended maximum size of the
+ ulint max_size; /*!< recommended maximum size of the
ibuf index tree, in pages */
- ulint seg_size; /* allocated pages of the file
+ ulint seg_size; /*!< allocated pages of the file
segment containing ibuf header and
tree */
- ibool empty; /* after an insert to the ibuf tree
+ ibool empty; /*!< after an insert to the ibuf tree
is performed, this is set to FALSE,
and if a contract operation finds
the tree empty, this is set to
TRUE */
- ulint free_list_len; /* length of the free list */
- ulint height; /* tree height */
- dict_index_t* index; /* insert buffer index */
+ ulint free_list_len; /*!< length of the free list */
+ ulint height; /*!< tree height */
+ dict_index_t* index; /*!< insert buffer index */
- ulint n_inserts; /* number of inserts made to
+ ulint n_inserts; /*!< number of inserts made to
the insert buffer */
- ulint n_merges; /* number of pages merged */
- ulint n_merged_recs; /* number of records merged */
+ ulint n_merges; /*!< number of pages merged */
+ ulint n_merged_recs; /*!< number of records merged */
};
-/****************************************************************************
+/************************************************************************//**
Sets the free bit of the page in the ibuf bitmap. This is done in a separate
mini-transaction, hence this operation does not restrict further work to only
ibuf bitmap operations, which would result if the latch to the bitmap page
@@ -68,29 +70,29 @@ UNIV_INTERN
void
ibuf_set_free_bits_func(
/*====================*/
- buf_block_t* block, /* in: index page of a non-clustered index;
+ buf_block_t* block, /*!< in: index page of a non-clustered index;
free bit is reset if page level is 0 */
#ifdef UNIV_IBUF_DEBUG
- ulint max_val,/* in: ULINT_UNDEFINED or a maximum
+ ulint max_val,/*!< in: ULINT_UNDEFINED or a maximum
value which the bits must have before
setting; this is for debugging */
#endif /* UNIV_IBUF_DEBUG */
- ulint val); /* in: value to set: < 4 */
+ ulint val); /*!< in: value to set: < 4 */
#ifdef UNIV_IBUF_DEBUG
# define ibuf_set_free_bits(b,v,max) ibuf_set_free_bits_func(b,max,v)
#else /* UNIV_IBUF_DEBUG */
# define ibuf_set_free_bits(b,v,max) ibuf_set_free_bits_func(b,v)
#endif /* UNIV_IBUF_DEBUG */
-/**************************************************************************
+/**********************************************************************//**
A basic partial test if an insert to the insert buffer could be possible and
recommended. */
UNIV_INLINE
ibool
ibuf_should_try(
/*============*/
- dict_index_t* index, /* in: index where to insert */
- ulint ignore_sec_unique) /* in: if != 0, we should
+ dict_index_t* index, /*!< in: index where to insert */
+ ulint ignore_sec_unique) /*!< in: if != 0, we should
ignore UNIQUE constraint on
a secondary index when we
decide */
@@ -112,16 +114,16 @@ ibuf_should_try(
return(FALSE);
}
-/***************************************************************************
-Checks if a page address is an ibuf bitmap page address. */
+/***********************************************************************//**
+Checks if a page address is an ibuf bitmap page address.
+@return TRUE if a bitmap page */
UNIV_INLINE
ibool
ibuf_bitmap_page(
/*=============*/
- /* out: TRUE if a bitmap page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no)/* in: page number */
+ ulint page_no)/*!< in: page number */
{
ut_ad(ut_is_2pow(zip_size));
@@ -134,16 +136,16 @@ ibuf_bitmap_page(
== FSP_IBUF_BITMAP_OFFSET));
}
-/*************************************************************************
-Translates the free space on a page to a value in the ibuf bitmap.*/
+/*********************************************************************//**
+Translates the free space on a page to a value in the ibuf bitmap.
+@return value for ibuf bitmap bits */
UNIV_INLINE
ulint
ibuf_index_page_calc_free_bits(
/*===========================*/
- /* out: value for ibuf bitmap bits */
- ulint zip_size, /* in: compressed page size in bytes;
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint max_ins_size) /* in: maximum insert size after reorganize
+ ulint max_ins_size) /*!< in: maximum insert size after reorganize
for the page */
{
ulint n;
@@ -170,17 +172,16 @@ ibuf_index_page_calc_free_bits(
return(n);
}
-/*************************************************************************
-Translates the ibuf free bits to the free space on a page in bytes. */
+/*********************************************************************//**
+Translates the ibuf free bits to the free space on a page in bytes.
+@return maximum insert size after reorganize for the page */
UNIV_INLINE
ulint
ibuf_index_page_calc_free_from_bits(
/*================================*/
- /* out: maximum insert size after reorganize for the
- page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint bits) /* in: value for ibuf bitmap bits */
+ ulint bits) /*!< in: value for ibuf bitmap bits */
{
ut_ad(bits < 4);
ut_ad(ut_is_2pow(zip_size));
@@ -202,16 +203,16 @@ ibuf_index_page_calc_free_from_bits(
return(bits * (UNIV_PAGE_SIZE / IBUF_PAGE_SIZE_PER_FREE_SPACE));
}
-/*************************************************************************
-Translates the free space on a compressed page to a value in the ibuf bitmap.*/
+/*********************************************************************//**
+Translates the free space on a compressed page to a value in the ibuf bitmap.
+@return value for ibuf bitmap bits */
UNIV_INLINE
ulint
ibuf_index_page_calc_free_zip(
/*==========================*/
- /* out: value for ibuf bitmap bits */
ulint zip_size,
- /* in: compressed page size in bytes */
- const buf_block_t* block) /* in: buffer block */
+ /*!< in: compressed page size in bytes */
+ const buf_block_t* block) /*!< in: buffer block */
{
ulint max_ins_size;
const page_zip_des_t* page_zip;
@@ -236,16 +237,16 @@ ibuf_index_page_calc_free_zip(
return(ibuf_index_page_calc_free_bits(zip_size, max_ins_size));
}
-/*************************************************************************
-Translates the free space on a page to a value in the ibuf bitmap.*/
+/*********************************************************************//**
+Translates the free space on a page to a value in the ibuf bitmap.
+@return value for ibuf bitmap bits */
UNIV_INLINE
ulint
ibuf_index_page_calc_free(
/*======================*/
- /* out: value for ibuf bitmap bits */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- const buf_block_t* block) /* in: buffer block */
+ const buf_block_t* block) /*!< in: buffer block */
{
ut_ad(zip_size == buf_block_get_zip_size(block));
@@ -261,7 +262,7 @@ ibuf_index_page_calc_free(
}
}
-/****************************************************************************
+/************************************************************************//**
Updates the free bits of an uncompressed page in the ibuf bitmap if
there is not enough free on the page any more. This is done in a
separate mini-transaction, hence this operation does not restrict
@@ -278,15 +279,15 @@ UNIV_INLINE
void
ibuf_update_free_bits_if_full(
/*==========================*/
- buf_block_t* block, /* in: index page to which we have added new
+ buf_block_t* block, /*!< in: index page to which we have added new
records; the free bits are updated if the
index is non-clustered and non-unique and
the page level is 0, and the page becomes
fuller */
- ulint max_ins_size,/* in: value of maximum insert size with
+ ulint max_ins_size,/*!< in: value of maximum insert size with
reorganize before the latest operation
performed to the page */
- ulint increase)/* in: upper limit for the additional space
+ ulint increase)/*!< in: upper limit for the additional space
used in the latest operation, if known, or
ULINT_UNDEFINED */
{
@@ -323,3 +324,4 @@ ibuf_update_free_bits_if_full(
ibuf_set_free_bits(block, after, before);
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/ibuf0types.h b/storage/xtradb/include/ibuf0types.h
index 264415196a1..55944f879b2 100644
--- a/storage/xtradb/include/ibuf0types.h
+++ b/storage/xtradb/include/ibuf0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ibuf0types.h
Insert buffer global types
Created 7/29/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/lock0iter.h b/storage/xtradb/include/lock0iter.h
index 3cd47bb95d2..25a57c9740c 100644
--- a/storage/xtradb/include/lock0iter.h
+++ b/storage/xtradb/include/lock0iter.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0iter.h
Lock queue iterator type and function prototypes.
Created July 16, 2007 Vasil Dimov
@@ -36,7 +37,7 @@ typedef struct lock_queue_iterator_struct {
ulint bit_no;
} lock_queue_iterator_t;
-/***********************************************************************
+/*******************************************************************//**
Initialize lock queue iterator so that it starts to iterate from
"lock". bit_no specifies the record number within the heap where the
record is stored. It can be undefined (ULINT_UNDEFINED) in two cases:
@@ -49,20 +50,20 @@ UNIV_INTERN
void
lock_queue_iterator_reset(
/*======================*/
- lock_queue_iterator_t* iter, /* out: iterator */
- const lock_t* lock, /* in: lock to start from */
- ulint bit_no);/* in: record number in the
+ lock_queue_iterator_t* iter, /*!< out: iterator */
+ const lock_t* lock, /*!< in: lock to start from */
+ ulint bit_no);/*!< in: record number in the
heap */
-/***********************************************************************
+/*******************************************************************//**
Gets the previous lock in the lock queue, returns NULL if there are no
more locks (i.e. the current lock is the first one). The iterator is
-receded (if not-NULL is returned). */
+receded (if not-NULL is returned).
+@return previous lock or NULL */
const lock_t*
lock_queue_iterator_get_prev(
/*=========================*/
- /* out: previous lock or NULL */
- lock_queue_iterator_t* iter); /* in/out: iterator */
+ lock_queue_iterator_t* iter); /*!< in/out: iterator */
#endif /* lock0iter_h */
diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h
index 2deeb804737..82e4c9bd976 100644
--- a/storage/xtradb/include/lock0lock.h
+++ b/storage/xtradb/include/lock0lock.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0lock.h
The transaction lock system
Created 5/7/1996 Heikki Tuuri
@@ -28,6 +29,7 @@ Created 5/7/1996 Heikki Tuuri
#include "univ.i"
#include "buf0types.h"
#include "trx0types.h"
+#include "mtr0types.h"
#include "rem0types.h"
#include "dict0types.h"
#include "que0types.h"
@@ -42,43 +44,46 @@ extern ibool lock_print_waits;
/* Buffer for storing information about the most recent deadlock error */
extern FILE* lock_latest_err_file;
-/*************************************************************************
-Gets the size of a lock struct. */
+/*********************************************************************//**
+Gets the size of a lock struct.
+@return size in bytes */
UNIV_INTERN
ulint
lock_get_size(void);
/*===============*/
- /* out: size in bytes */
-/*************************************************************************
+/*********************************************************************//**
Creates the lock system at database start. */
UNIV_INTERN
void
lock_sys_create(
/*============*/
- ulint n_cells); /* in: number of slots in lock hash table */
-/*************************************************************************
+ ulint n_cells); /*!< in: number of slots in lock hash table */
+/*********************************************************************//**
+Closes the lock system at database shutdown. */
+UNIV_INTERN
+void
+lock_sys_close(void);
+/*================*/
+/*********************************************************************//**
Checks if some transaction has an implicit x-lock on a record in a clustered
-index. */
+index.
+@return transaction which has the x-lock, or NULL */
UNIV_INLINE
trx_t*
lock_clust_rec_some_has_impl(
/*=========================*/
- /* out: transaction which has the x-lock, or
- NULL */
- const rec_t* rec, /* in: user record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*************************************************************************
-Gets the heap_no of the smallest user record on a page. */
+ const rec_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*********************************************************************//**
+Gets the heap_no of the smallest user record on a page.
+@return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
UNIV_INLINE
ulint
lock_get_min_heap_no(
/*=================*/
- /* out: heap_no of smallest
- user record, or
- PAGE_HEAP_NO_SUPREMUM */
- const buf_block_t* block); /* in: buffer block */
-/*****************************************************************
+ const buf_block_t* block); /*!< in: buffer block */
+/*************************************************************//**
Updates the lock table when we have reorganized a page. NOTE: we copy
also the locks set on the infimum of the page; the infimum may carry
locks if an update of a record is occurring on the page, and its locks
@@ -87,62 +92,62 @@ UNIV_INTERN
void
lock_move_reorganize_page(
/*======================*/
- const buf_block_t* block, /* in: old index page, now
+ const buf_block_t* block, /*!< in: old index page, now
reorganized */
- const buf_block_t* oblock);/* in: copy of the old, not
+ const buf_block_t* oblock);/*!< in: copy of the old, not
reorganized page */
-/*****************************************************************
+/*************************************************************//**
Moves the explicit locks on user records to another page if a record
list end is moved to another page. */
UNIV_INTERN
void
lock_move_rec_list_end(
/*===================*/
- const buf_block_t* new_block, /* in: index page to move to */
- const buf_block_t* block, /* in: index page */
- const rec_t* rec); /* in: record on page: this
+ const buf_block_t* new_block, /*!< in: index page to move to */
+ const buf_block_t* block, /*!< in: index page */
+ const rec_t* rec); /*!< in: record on page: this
is the first record moved */
-/*****************************************************************
+/*************************************************************//**
Moves the explicit locks on user records to another page if a record
list start is moved to another page. */
UNIV_INTERN
void
lock_move_rec_list_start(
/*=====================*/
- const buf_block_t* new_block, /* in: index page to move to */
- const buf_block_t* block, /* in: index page */
- const rec_t* rec, /* in: record on page:
+ const buf_block_t* new_block, /*!< in: index page to move to */
+ const buf_block_t* block, /*!< in: index page */
+ const rec_t* rec, /*!< in: record on page:
this is the first
record NOT copied */
- const rec_t* old_end); /* in: old
+ const rec_t* old_end); /*!< in: old
previous-to-last
record on new_page
before the records
were copied */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is split to the right. */
UNIV_INTERN
void
lock_update_split_right(
/*====================*/
- const buf_block_t* right_block, /* in: right page */
- const buf_block_t* left_block); /* in: left page */
-/*****************************************************************
+ const buf_block_t* right_block, /*!< in: right page */
+ const buf_block_t* left_block); /*!< in: left page */
+/*************************************************************//**
Updates the lock table when a page is merged to the right. */
UNIV_INTERN
void
lock_update_merge_right(
/*====================*/
- const buf_block_t* right_block, /* in: right page to
+ const buf_block_t* right_block, /*!< in: right page to
which merged */
- const rec_t* orig_succ, /* in: original
+ const rec_t* orig_succ, /*!< in: original
successor of infimum
on the right page
before merge */
- const buf_block_t* left_block); /* in: merged index
+ const buf_block_t* left_block); /*!< in: merged index
page which will be
discarded */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when the root page is copied to another in
btr_root_raise_and_insert. Note that we leave lock structs on the
root page, even though they do not make sense on other than leaf
@@ -153,86 +158,86 @@ UNIV_INTERN
void
lock_update_root_raise(
/*===================*/
- const buf_block_t* block, /* in: index page to which copied */
- const buf_block_t* root); /* in: root page */
-/*****************************************************************
+ const buf_block_t* block, /*!< in: index page to which copied */
+ const buf_block_t* root); /*!< in: root page */
+/*************************************************************//**
Updates the lock table when a page is copied to another and the original page
is removed from the chain of leaf pages, except if page is the root! */
UNIV_INTERN
void
lock_update_copy_and_discard(
/*=========================*/
- const buf_block_t* new_block, /* in: index page to
+ const buf_block_t* new_block, /*!< in: index page to
which copied */
- const buf_block_t* block); /* in: index page;
+ const buf_block_t* block); /*!< in: index page;
NOT the root! */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is split to the left. */
UNIV_INTERN
void
lock_update_split_left(
/*===================*/
- const buf_block_t* right_block, /* in: right page */
- const buf_block_t* left_block); /* in: left page */
-/*****************************************************************
+ const buf_block_t* right_block, /*!< in: right page */
+ const buf_block_t* left_block); /*!< in: left page */
+/*************************************************************//**
Updates the lock table when a page is merged to the left. */
UNIV_INTERN
void
lock_update_merge_left(
/*===================*/
- const buf_block_t* left_block, /* in: left page to
+ const buf_block_t* left_block, /*!< in: left page to
which merged */
- const rec_t* orig_pred, /* in: original predecessor
+ const rec_t* orig_pred, /*!< in: original predecessor
of supremum on the left page
before merge */
- const buf_block_t* right_block); /* in: merged index page
+ const buf_block_t* right_block); /*!< in: merged index page
which will be discarded */
-/*****************************************************************
+/*************************************************************//**
Resets the original locks on heir and replaces them with gap type locks
inherited from rec. */
UNIV_INTERN
void
lock_rec_reset_and_inherit_gap_locks(
/*=================================*/
- const buf_block_t* heir_block, /* in: block containing the
+ const buf_block_t* heir_block, /*!< in: block containing the
record which inherits */
- const buf_block_t* block, /* in: block containing the
+ const buf_block_t* block, /*!< in: block containing the
record from which inherited;
does NOT reset the locks on
this record */
- ulint heir_heap_no, /* in: heap_no of the
+ ulint heir_heap_no, /*!< in: heap_no of the
inheriting record */
- ulint heap_no); /* in: heap_no of the
+ ulint heap_no); /*!< in: heap_no of the
donating record */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is discarded. */
UNIV_INTERN
void
lock_update_discard(
/*================*/
- const buf_block_t* heir_block, /* in: index page
+ const buf_block_t* heir_block, /*!< in: index page
which will inherit the locks */
- ulint heir_heap_no, /* in: heap_no of the record
+ ulint heir_heap_no, /*!< in: heap_no of the record
which will inherit the locks */
- const buf_block_t* block); /* in: index page
+ const buf_block_t* block); /*!< in: index page
which will be discarded */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a new user record is inserted. */
UNIV_INTERN
void
lock_update_insert(
/*===============*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec); /* in: the inserted record */
-/*****************************************************************
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec); /*!< in: the inserted record */
+/*************************************************************//**
Updates the lock table when a record is removed. */
UNIV_INTERN
void
lock_update_delete(
/*===============*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec); /* in: the record to be removed */
-/*************************************************************************
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec); /*!< in: the record to be removed */
+/*********************************************************************//**
Stores on the page infimum record the explicit locks of another record.
This function is used to store the lock state of a record when it is
updated and the size of the record changes in the update. The record
@@ -243,159 +248,152 @@ UNIV_INTERN
void
lock_rec_store_on_page_infimum(
/*===========================*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec); /* in: record whose lock state
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec); /*!< in: record whose lock state
is stored on the infimum
record of the same page; lock
bits are reset on the
record */
-/*************************************************************************
+/*********************************************************************//**
Restores the state of explicit lock requests on a single record, where the
state was stored on the infimum of the page. */
UNIV_INTERN
void
lock_rec_restore_from_page_infimum(
/*===============================*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record whose lock state
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record whose lock state
is restored */
- const buf_block_t* donator);/* in: page (rec is not
+ const buf_block_t* donator);/*!< in: page (rec is not
necessarily on this page)
whose infimum stored the lock
state; lock bits are reset on
the infimum */
-/*************************************************************************
-Returns TRUE if there are explicit record locks on a page. */
+/*********************************************************************//**
+Returns TRUE if there are explicit record locks on a page.
+@return TRUE if there are explicit record locks on the page */
UNIV_INTERN
ibool
lock_rec_expl_exist_on_page(
/*========================*/
- /* out: TRUE if there are explicit record locks on
- the page */
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
-/*************************************************************************
+ ulint space, /*!< in: space id */
+ ulint page_no);/*!< in: page number */
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate insert of
a record. If they do, first tests if the query thread should anyway
be suspended for some reason; if not, then puts the transaction and
the query thread to the lock wait state and inserts a waiting request
-for a gap x-lock to the lock queue. */
+for a gap x-lock to the lock queue.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_rec_insert_check_and_lock(
/*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is
set, does nothing */
- rec_t* rec, /* in: record after which to insert */
- buf_block_t* block, /* in/out: buffer block of rec */
- dict_index_t* index, /* in: index */
- que_thr_t* thr, /* in: query thread */
- ibool* inherit);/* out: set to TRUE if the new
+ const rec_t* rec, /*!< in: record after which to insert */
+ buf_block_t* block, /*!< in/out: buffer block of rec */
+ dict_index_t* index, /*!< in: index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+ ibool* inherit);/*!< out: set to TRUE if the new
inserted record maybe should inherit
LOCK_GAP type locks from the successor
record */
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify (update,
delete mark, or delete unmark) of a clustered index record. If they do,
first tests if the query thread should anyway be suspended for some
reason; if not, then puts the transaction and the query thread to the
lock wait state and inserts a waiting request for a record x-lock to the
-lock queue. */
+lock queue.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_modify_check_and_lock(
/*=================================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: record which should be
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ 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) */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify
-(delete mark or delete unmark) of a secondary index record. */
+(delete mark or delete unmark) of a secondary index record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_sec_rec_modify_check_and_lock(
/*===============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- buf_block_t* block, /* in/out: buffer block of rec */
- rec_t* rec, /* in: record which should be
+ buf_block_t* block, /*!< in/out: buffer block of rec */
+ const rec_t* rec, /*!< in: record which should be
modified; NOTE: as this is a secondary
index, we always have to modify the
clustered index record first: see the
comment below */
- dict_index_t* index, /* in: secondary index */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ dict_index_t* index, /*!< in: secondary index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in/out: mini-transaction */
+/*********************************************************************//**
Like the counterpart for a clustered index below, but now we read a
-secondary index record. */
+secondary index record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_sec_rec_read_check_and_lock(
/*=============================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
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) */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: secondary index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
if the query thread should anyway be suspended for some reason; if not, then
puts the transaction and the query thread to the lock wait state and inserts a
waiting request for a record lock to the lock queue. Sets the requested mode
-lock on the record. */
+lock on the record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_read_check_and_lock(
/*===============================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum 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) */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
if the query thread should anyway be suspended for some reason; if not, then
@@ -403,89 +401,73 @@ puts the transaction and the query thread to the lock wait state and inserts a
waiting request for a record lock to the lock queue. Sets the requested mode
lock on the record. This is an alternative version of
lock_clust_rec_read_check_and_lock() that does not require the parameter
-"offsets". */
+"offsets".
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_read_check_and_lock_alt(
/*===================================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
be read or passed over by a
read cursor */
- dict_index_t* index, /* in: clustered index */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: clustered index */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
-Checks that a record is seen in a consistent read. */
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
+Checks that a record is seen in a consistent read.
+@return TRUE if sees, or FALSE if an earlier version of the record
+should be retrieved */
UNIV_INTERN
ibool
lock_clust_rec_cons_read_sees(
/*==========================*/
- /* out: TRUE if sees, or FALSE if an earlier
- version of the record should be retrieved */
- const rec_t* rec, /* in: user record which should be read or
+ 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) */
- read_view_t* view); /* in: consistent read view */
-/*************************************************************************
-Checks that a non-clustered index record is seen in a consistent read. */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ read_view_t* view); /*!< in: consistent read view */
+/*********************************************************************//**
+Checks that a non-clustered index record is seen in a consistent read.
+
+NOTE that a non-clustered index page contains so little information on
+its modifications that also in the case FALSE, the present version of
+rec may be the right, but we must check this from the clustered index
+record.
+
+@return TRUE if certainly sees, or FALSE if an earlier version of the
+clustered index record might be needed */
UNIV_INTERN
ulint
lock_sec_rec_cons_read_sees(
/*========================*/
- /* out: TRUE if certainly
- sees, or FALSE if an earlier
- version of the clustered index
- record might be needed: NOTE
- that a non-clustered index
- page contains so little
- information on its
- modifications that also in the
- case FALSE, the present
- version of rec may be the
- right, but we must check this
- from the clustered index
- record */
- const rec_t* rec, /* in: user record which
+ const rec_t* rec, /*!< in: user record which
should be read or passed over
by a read cursor */
- const read_view_t* view); /* in: consistent read view */
-/*************************************************************************
+ const read_view_t* view); /*!< in: consistent read view */
+/*********************************************************************//**
Locks the specified database table in the mode given. If the lock cannot
-be granted immediately, the query thread is put to wait. */
+be granted immediately, the query thread is put to wait.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_table(
/*=======*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing */
- dict_table_t* table, /* in: database table in dictionary cache */
- enum lock_mode mode, /* in: lock mode */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
-Checks if there are any locks set on the table. */
-UNIV_INTERN
-ibool
-lock_is_on_table(
-/*=============*/
- /* out: TRUE if there are lock(s) */
- dict_table_t* table); /* in: database table in dictionary cache */
-/*****************************************************************
+ dict_table_t* table, /*!< in: database table in dictionary cache */
+ enum lock_mode mode, /*!< in: lock mode */
+ que_thr_t* thr); /*!< in: query thread */
+/*************************************************************//**
Removes a granted record lock of a transaction from the queue and grants
locks to other transactions waiting in the queue if they now are entitled
to a lock. */
@@ -493,37 +475,29 @@ UNIV_INTERN
void
lock_rec_unlock(
/*============*/
- trx_t* trx, /* in: transaction that has
+ trx_t* trx, /*!< in: transaction that has
set a record lock */
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record */
- enum lock_mode lock_mode);/* in: LOCK_S or LOCK_X */
-/*************************************************************************
-Releases a table lock.
-Releases possible other transactions waiting for this lock. */
-UNIV_INTERN
-void
-lock_table_unlock(
-/*==============*/
- lock_t* lock); /* in: lock */
-/*************************************************************************
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record */
+ enum lock_mode lock_mode);/*!< in: LOCK_S or LOCK_X */
+/*********************************************************************//**
Releases transaction locks, and releases possible other transactions waiting
because of these locks. */
UNIV_INTERN
void
lock_release_off_kernel(
/*====================*/
- trx_t* trx); /* in: transaction */
-/*************************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*********************************************************************//**
Cancels a waiting lock request and releases possible other transactions
waiting behind it. */
UNIV_INTERN
void
lock_cancel_waiting_and_release(
/*============================*/
- lock_t* lock); /* in: waiting lock request */
+ lock_t* lock); /*!< in: waiting lock request */
-/*************************************************************************
+/*********************************************************************//**
Removes locks on a table to be dropped or truncated.
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
@@ -532,128 +506,127 @@ UNIV_INTERN
void
lock_remove_all_on_table(
/*=====================*/
- dict_table_t* table, /* in: table to be dropped
+ dict_table_t* table, /*!< in: table to be dropped
or truncated */
- ibool remove_also_table_sx_locks);/* in: also removes
+ ibool remove_also_table_sx_locks);/*!< in: also removes
table S and X locks */
-/*************************************************************************
+/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
-searching for a lock in the hash table. */
+searching for a lock in the hash table.
+@return folded value */
UNIV_INLINE
ulint
lock_rec_fold(
/*==========*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
__attribute__((const));
-/*************************************************************************
+/*********************************************************************//**
Calculates the hash value of a page file address: used in inserting or
-searching for a lock in the hash table. */
+searching for a lock in the hash table.
+@return hashed value */
UNIV_INLINE
ulint
lock_rec_hash(
/*==========*/
- /* out: hashed value */
- ulint space, /* in: space */
- ulint page_no);/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no);/*!< in: page number */
-/**************************************************************************
+/**********************************************************************//**
Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED,
-if none found. */
+if none found.
+@return bit index == heap number of the record, or ULINT_UNDEFINED if
+none found */
UNIV_INTERN
ulint
lock_rec_find_set_bit(
/*==================*/
- /* out: bit index == heap number of
- the record, or ULINT_UNDEFINED if none found */
- const lock_t* lock); /* in: record lock with at least one bit set */
+ const lock_t* lock); /*!< in: record lock with at least one
+ bit set */
-/*************************************************************************
+/*********************************************************************//**
Gets the source table of an ALTER TABLE transaction. The table must be
-covered by an IX or IS table lock. */
+covered by an IX or IS table lock.
+@return the source table of transaction, if it is covered by an IX or
+IS table lock; dest if there is no source table, and NULL if the
+transaction is locking more than two tables or an inconsistency is
+found */
UNIV_INTERN
dict_table_t*
lock_get_src_table(
/*===============*/
- /* out: the source table of transaction,
- if it is covered by an IX or IS table lock;
- dest if there is no source table, and
- NULL if the transaction is locking more than
- two tables or an inconsistency is found */
- trx_t* trx, /* in: transaction */
- dict_table_t* dest, /* in: destination of ALTER TABLE */
- enum lock_mode* mode); /* out: lock mode of the source table */
-/*************************************************************************
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* dest, /*!< in: destination of ALTER TABLE */
+ enum lock_mode* mode); /*!< out: lock mode of the source table */
+/*********************************************************************//**
Determine if the given table is exclusively "owned" by the given
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
-on the table. */
+on the table.
+@return TRUE if table is only locked by trx, with LOCK_IX, and
+possibly LOCK_AUTO_INC */
UNIV_INTERN
ibool
lock_is_table_exclusive(
/*====================*/
- /* out: TRUE if table is only locked by trx,
- with LOCK_IX, and possibly LOCK_AUTO_INC */
- dict_table_t* table, /* in: table */
- trx_t* trx); /* in: transaction */
-/*************************************************************************
-Checks if a lock request lock1 has to wait for request lock2. */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx); /*!< in: transaction */
+/*********************************************************************//**
+Checks if a lock request lock1 has to wait for request lock2.
+@return TRUE if lock1 has to wait for lock2 to be removed */
UNIV_INTERN
ibool
lock_has_to_wait(
/*=============*/
- /* out: TRUE if lock1 has to wait for
- lock2 to be removed */
- const lock_t* lock1, /* in: waiting lock */
- const lock_t* lock2); /* in: another lock; NOTE that it is
+ const lock_t* lock1, /*!< in: waiting lock */
+ const lock_t* lock2); /*!< in: another lock; NOTE that it is
assumed that this has a lock bit set
on the same record as in lock1 if the
locks are record locks */
-/*************************************************************************
-Checks that a transaction id is sensible, i.e., not in the future. */
+/*********************************************************************//**
+Checks that a transaction id is sensible, i.e., not in the future.
+@return TRUE if ok */
UNIV_INTERN
ibool
lock_check_trx_id_sanity(
/*=====================*/
- /* out: TRUE if ok */
- dulint trx_id, /* in: trx id */
- const rec_t* rec, /* in: user record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets, /* in: rec_get_offsets(rec, index) */
- ibool has_kernel_mutex);/* in: TRUE if the caller owns the
+ trx_id_t trx_id, /*!< in: trx id */
+ const rec_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ ibool has_kernel_mutex);/*!< in: TRUE if the caller owns the
kernel mutex */
-/*************************************************************************
+/*********************************************************************//**
Prints info of a table lock. */
UNIV_INTERN
void
lock_table_print(
/*=============*/
- FILE* file, /* in: file where to print */
- const lock_t* lock); /* in: table type lock */
-/*************************************************************************
+ FILE* file, /*!< in: file where to print */
+ const lock_t* lock); /*!< in: table type lock */
+/*********************************************************************//**
Prints info of a record lock. */
UNIV_INTERN
void
lock_rec_print(
/*===========*/
- FILE* file, /* in: file where to print */
- const lock_t* lock); /* in: record type lock */
-/*************************************************************************
+ FILE* file, /*!< in: file where to print */
+ const lock_t* lock); /*!< in: record type lock */
+/*********************************************************************//**
Prints info of locks for all transactions. */
UNIV_INTERN
void
lock_print_info_summary(
/*====================*/
- FILE* file); /* in: file where to print */
-/*************************************************************************
+ FILE* file); /*!< in: file where to print */
+/*********************************************************************//**
Prints info of locks for each transaction. */
UNIV_INTERN
void
lock_print_info_all_transactions(
/*=============================*/
- FILE* file); /* in: file where to print */
-/*************************************************************************
+ FILE* file); /*!< in: file where to print */
+/*********************************************************************//**
Return approximate number or record locks (bits set in the bitmap) for
this transaction. Since delete-marked records may be removed, the
record count will not be precise. */
@@ -661,137 +634,148 @@ UNIV_INTERN
ulint
lock_number_of_rows_locked(
/*=======================*/
- trx_t* trx); /* in: transaction */
-/***********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
+Check if a transaction holds any autoinc locks.
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+ const trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
lock_release_autoinc_locks(
/*=======================*/
- trx_t* trx); /* in/out: transaction */
+ trx_t* trx); /*!< in/out: transaction */
-/***********************************************************************
+/*******************************************************************//**
Gets the type of a lock. Non-inline version for using outside of the
-lock module. */
+lock module.
+@return LOCK_TABLE or LOCK_REC */
UNIV_INTERN
ulint
lock_get_type(
/*==========*/
- /* out: LOCK_TABLE or LOCK_REC */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
-Gets the id of the transaction owning a lock. */
+/*******************************************************************//**
+Gets the id of the transaction owning a lock.
+@return transaction id */
UNIV_INTERN
ullint
lock_get_trx_id(
/*============*/
- /* out: transaction id */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
+/*******************************************************************//**
Gets the mode of a lock in a human readable string.
-The string should not be free()'d or modified. */
-
+The string should not be free()'d or modified.
+@return lock mode */
+UNIV_INTERN
const char*
lock_get_mode_str(
/*==============*/
- /* out: lock mode */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
+/*******************************************************************//**
Gets the type of a lock in a human readable string.
-The string should not be free()'d or modified. */
-
+The string should not be free()'d or modified.
+@return lock type */
+UNIV_INTERN
const char*
lock_get_type_str(
/*==============*/
- /* out: lock type */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
-Gets the id of the table on which the lock is. */
+/*******************************************************************//**
+Gets the id of the table on which the lock is.
+@return id of the table */
UNIV_INTERN
ullint
lock_get_table_id(
/*==============*/
- /* out: id of the table */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
+/*******************************************************************//**
Gets the name of the table on which the lock is.
-The string should not be free()'d or modified. */
-
+The string should not be free()'d or modified.
+@return name of the table */
+UNIV_INTERN
const char*
lock_get_table_name(
/*================*/
- /* out: name of the table */
- const lock_t* lock); /* in: lock */
-
-/***********************************************************************
-For a record lock, gets the index on which the lock is. */
+ const lock_t* lock); /*!< in: lock */
+/*******************************************************************//**
+For a record lock, gets the index on which the lock is.
+@return index */
+UNIV_INTERN
const dict_index_t*
lock_rec_get_index(
/*===============*/
- /* out: index */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
+/*******************************************************************//**
For a record lock, gets the name of the index on which the lock is.
-The string should not be free()'d or modified. */
-
+The string should not be free()'d or modified.
+@return name of the index */
+UNIV_INTERN
const char*
lock_rec_get_index_name(
/*====================*/
- /* out: name of the index */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
-For a record lock, gets the tablespace number on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the tablespace number on which the lock is.
+@return tablespace number */
UNIV_INTERN
ulint
lock_rec_get_space_id(
/*==================*/
- /* out: tablespace number */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
-For a record lock, gets the page number on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the page number on which the lock is.
+@return page number */
UNIV_INTERN
ulint
lock_rec_get_page_no(
/*=================*/
- /* out: page number */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/* Lock modes and types */
-#define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the
+/** Lock modes and types */
+/* @{ */
+#define LOCK_MODE_MASK 0xFUL /*!< mask used to extract mode from the
type_mode field in a lock */
-/* Lock types */
-#define LOCK_TABLE 16 /* these type values should be so high that */
-#define LOCK_REC 32 /* they can be ORed to the lock mode */
-#define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the
+/** Lock types */
+/* @{ */
+#define LOCK_TABLE 16 /*!< table lock */
+#define LOCK_REC 32 /*!< record lock */
+#define LOCK_TYPE_MASK 0xF0UL /*!< mask used to extract lock type from the
type_mode field in a lock */
-/* Waiting lock flag */
-#define LOCK_WAIT 256 /* this wait bit should be so high that
- it can be ORed to the lock mode and type;
- when this bit is set, it means that the
- lock has not yet been granted, it is just
- waiting for its turn in the wait queue */
+#if LOCK_MODE_MASK & LOCK_TYPE_MASK
+# error "LOCK_MODE_MASK & LOCK_TYPE_MASK"
+#endif
+
+#define LOCK_WAIT 256 /*!< Waiting lock flag; when set, it
+ means that the lock has not yet been
+ granted, it is just waiting for its
+ turn in the wait queue */
/* Precise modes */
-#define LOCK_ORDINARY 0 /* this flag denotes an ordinary next-key lock
- in contrast to LOCK_GAP or LOCK_REC_NOT_GAP */
-#define LOCK_GAP 512 /* this gap bit should be so high that
- it can be ORed to the other flags;
- when this bit is set, it means that the
+#define LOCK_ORDINARY 0 /*!< this flag denotes an ordinary
+ next-key lock in contrast to LOCK_GAP
+ or LOCK_REC_NOT_GAP */
+#define LOCK_GAP 512 /*!< when this bit is set, it means that the
lock holds only on the gap before the record;
for instance, an x-lock on the gap does not
give permission to modify the record on which
the bit is set; locks of this type are created
when records are removed from the index chain
of records */
-#define LOCK_REC_NOT_GAP 1024 /* this bit means that the lock is only on
+#define LOCK_REC_NOT_GAP 1024 /*!< this bit means that the lock is only on
the index record and does NOT block inserts
to the gap before the index record; this is
used in the case when we retrieve a record
@@ -799,7 +783,7 @@ lock_rec_get_page_no(
locking plain SELECTs (not part of UPDATE
or DELETE) when the user has set the READ
COMMITTED isolation level */
-#define LOCK_INSERT_INTENTION 2048 /* this bit is set when we place a waiting
+#define LOCK_INSERT_INTENTION 2048 /*!< this bit is set when we place a waiting
gap type record lock request in order to let
an insert of an index record to wait until
there are no conflicting locks by other
@@ -807,27 +791,28 @@ lock_rec_get_page_no(
remains set when the waiting lock is granted,
or if the lock is inherited to a neighboring
record */
+#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK
+# error
+#endif
+#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK
+# error
+#endif
+/* @} */
-/* When lock bits are reset, the following flags are available: */
-#define LOCK_RELEASE_WAIT 1
-#define LOCK_NOT_RELEASE_WAIT 2
-
-/* Lock operation struct */
+/** Lock operation struct */
typedef struct lock_op_struct lock_op_t;
+/** Lock operation struct */
struct lock_op_struct{
- dict_table_t* table; /* table to be locked */
- enum lock_mode mode; /* lock mode */
+ dict_table_t* table; /*!< table to be locked */
+ enum lock_mode mode; /*!< lock mode */
};
-#define LOCK_OP_START 1
-#define LOCK_OP_COMPLETE 2
-
-/* The lock system struct */
+/** The lock system struct */
struct lock_sys_struct{
- hash_table_t* rec_hash; /* hash table of the record locks */
+ hash_table_t* rec_hash; /*!< hash table of the record locks */
};
-/* The lock system */
+/** The lock system */
extern lock_sys_t* lock_sys;
diff --git a/storage/xtradb/include/lock0lock.ic b/storage/xtradb/include/lock0lock.ic
index f978cc70678..014722f51c4 100644
--- a/storage/xtradb/include/lock0lock.ic
+++ b/storage/xtradb/include/lock0lock.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0lock.ic
The transaction lock system
Created 5/7/1996 Heikki Tuuri
@@ -37,49 +38,48 @@ Created 5/7/1996 Heikki Tuuri
#include "read0read.h"
#include "log0recv.h"
-/*************************************************************************
+/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
-searching for a lock in the hash table. */
+searching for a lock in the hash table.
+@return folded value */
UNIV_INLINE
ulint
lock_rec_fold(
/*==========*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
return(ut_fold_ulint_pair(space, page_no));
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the hash value of a page file address: used in inserting or
-searching for a lock in the hash table. */
+searching for a lock in the hash table.
+@return hashed value */
UNIV_INLINE
ulint
lock_rec_hash(
/*==========*/
- /* out: hashed value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
return(hash_calc_hash(lock_rec_fold(space, page_no),
lock_sys->rec_hash));
}
-/*************************************************************************
+/*********************************************************************//**
Checks if some transaction has an implicit x-lock on a record in a clustered
-index. */
+index.
+@return transaction which has the x-lock, or NULL */
UNIV_INLINE
trx_t*
lock_clust_rec_some_has_impl(
/*=========================*/
- /* out: transaction which has the x-lock, or
- NULL */
- const rec_t* rec, /* in: user record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
- dulint trx_id;
+ trx_id_t trx_id;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(dict_index_is_clust(index));
@@ -96,16 +96,14 @@ lock_clust_rec_some_has_impl(
return(NULL);
}
-/*************************************************************************
-Gets the heap_no of the smallest user record on a page. */
+/*********************************************************************//**
+Gets the heap_no of the smallest user record on a page.
+@return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
UNIV_INLINE
ulint
lock_get_min_heap_no(
/*=================*/
- /* out: heap_no of smallest
- user record, or
- PAGE_HEAP_NO_SUPREMUM */
- const buf_block_t* block) /* in: buffer block */
+ const buf_block_t* block) /*!< in: buffer block */
{
const page_t* page = block->frame;
diff --git a/storage/xtradb/include/lock0priv.h b/storage/xtradb/include/lock0priv.h
index 0a0d41e6aaa..287c151b19f 100644
--- a/storage/xtradb/include/lock0priv.h
+++ b/storage/xtradb/include/lock0priv.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0priv.h
Lock module internal structures and methods.
Created July 12, 2007 Vasil Dimov
@@ -38,66 +39,67 @@ those functions in lock/ */
#include "trx0types.h"
#include "ut0lst.h"
-/* A table lock */
+/** A table lock */
typedef struct lock_table_struct lock_table_t;
+/** A table lock */
struct lock_table_struct {
- dict_table_t* table; /* database table in dictionary
+ dict_table_t* table; /*!< database table in dictionary
cache */
UT_LIST_NODE_T(lock_t)
- locks; /* list of locks on the same
+ locks; /*!< list of locks on the same
table */
};
-/* Record lock for a page */
+/** Record lock for a page */
typedef struct lock_rec_struct lock_rec_t;
+/** Record lock for a page */
struct lock_rec_struct {
- ulint space; /* space id */
- ulint page_no; /* page number */
- ulint n_bits; /* number of bits in the lock
+ ulint space; /*!< space id */
+ ulint page_no; /*!< page number */
+ ulint n_bits; /*!< number of bits in the lock
bitmap; NOTE: the lock bitmap is
placed immediately after the
lock struct */
};
-/* Lock struct */
+/** Lock struct */
struct lock_struct {
- trx_t* trx; /* transaction owning the
+ trx_t* trx; /*!< transaction owning the
lock */
UT_LIST_NODE_T(lock_t)
- trx_locks; /* list of the locks of the
+ trx_locks; /*!< list of the locks of the
transaction */
- ulint type_mode; /* lock type, mode, LOCK_GAP or
+ ulint type_mode; /*!< lock type, mode, LOCK_GAP or
LOCK_REC_NOT_GAP,
LOCK_INSERT_INTENTION,
wait flag, ORed */
- hash_node_t hash; /* hash chain node for a record
+ hash_node_t hash; /*!< hash chain node for a record
lock */
- dict_index_t* index; /* index for a record lock */
+ dict_index_t* index; /*!< index for a record lock */
union {
- lock_table_t tab_lock;/* table lock */
- lock_rec_t rec_lock;/* record lock */
- } un_member;
+ lock_table_t tab_lock;/*!< table lock */
+ lock_rec_t rec_lock;/*!< record lock */
+ } un_member; /*!< lock details */
};
-/*************************************************************************
-Gets the type of a lock. */
+/*********************************************************************//**
+Gets the type of a lock.
+@return LOCK_TABLE or LOCK_REC */
UNIV_INLINE
ulint
lock_get_type_low(
/*==============*/
- /* out: LOCK_TABLE or LOCK_REC */
- const lock_t* lock); /* in: lock */
-
-/*************************************************************************
-Gets the previous record lock set on a record. */
+ const lock_t* lock); /*!< in: lock */
+/*********************************************************************//**
+Gets the previous record lock set on a record.
+@return previous lock on the same record, NULL if none exists */
+UNIV_INTERN
const lock_t*
lock_rec_get_prev(
/*==============*/
- /* out: previous lock on the same
- record, NULL if none exists */
- const lock_t* in_lock,/* in: record lock */
- ulint heap_no);/* in: heap number of the record */
+ const lock_t* in_lock,/*!< in: record lock */
+ ulint heap_no);/*!< in: heap number of the record */
#ifndef UNIV_NONINL
#include "lock0priv.ic"
diff --git a/storage/xtradb/include/lock0priv.ic b/storage/xtradb/include/lock0priv.ic
index ae633a4fc61..30447c99848 100644
--- a/storage/xtradb/include/lock0priv.ic
+++ b/storage/xtradb/include/lock0priv.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0priv.ic
Lock module internal inline methods.
Created July 16, 2007 Vasil Dimov
@@ -31,14 +32,14 @@ methods but they are used only in that file. */
#error Do not include lock0priv.ic outside of the lock/ module
#endif
-/*************************************************************************
-Gets the type of a lock. */
+/*********************************************************************//**
+Gets the type of a lock.
+@return LOCK_TABLE or LOCK_REC */
UNIV_INLINE
ulint
lock_get_type_low(
/*==============*/
- /* out: LOCK_TABLE or LOCK_REC */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_ad(lock);
diff --git a/storage/xtradb/include/lock0types.h b/storage/xtradb/include/lock0types.h
index 52631b56532..45f29e90fe9 100644
--- a/storage/xtradb/include/lock0types.h
+++ b/storage/xtradb/include/lock0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0types.h
The transaction lock system global types
Created 5/7/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h
index 2aaf74b4190..135aeb69e2d 100644
--- a/storage/xtradb/include/log0log.h
+++ b/storage/xtradb/include/log0log.h
@@ -15,8 +15,33 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*****************************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Google Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Google, Inc. Those modifications are gratefully acknowledged and are described
+briefly in the InnoDB documentation. The contributions by Google are
+incorporated with their permission, and subject to the conditions contained in
+the file COPYING.Google.
+
+This program is free 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
-/******************************************************
+*****************************************************************************/
+
+/**************************************************//**
+@file include/log0log.h
Database log
Created 12/9/1995 Heikki Tuuri
@@ -27,26 +52,37 @@ Created 12/9/1995 Heikki Tuuri
#include "univ.i"
#include "ut0byte.h"
+#include "ut0lst.h"
+#ifndef UNIV_HOTBACKUP
#include "sync0sync.h"
#include "sync0rw.h"
+#endif /* !UNIV_HOTBACKUP */
+/** Redo log buffer */
typedef struct log_struct log_t;
+/** Redo log group */
typedef struct log_group_struct log_group_t;
#ifdef UNIV_DEBUG
+/** Flag: write to log file? */
extern ibool log_do_write;
+/** Flag: enable debug output when writing to the log? */
extern ibool log_debug_writes;
#else /* UNIV_DEBUG */
+/** Write to log */
# define log_do_write TRUE
#endif /* UNIV_DEBUG */
-/* Wait modes for log_write_up_to */
+/** Wait modes for log_write_up_to @{ */
#define LOG_NO_WAIT 91
#define LOG_WAIT_ONE_GROUP 92
#define LOG_WAIT_ALL_GROUPS 93
+/* @} */
+/** Maximum number of log groups in log_group_struct::checkpoint_buf */
#define LOG_MAX_N_GROUPS 32
-/********************************************************************
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint,
so that we know that the limit has been written to a log checkpoint field
on disk. */
@@ -54,44 +90,44 @@ UNIV_INTERN
void
log_fsp_current_free_limit_set_and_checkpoint(
/*==========================================*/
- ulint limit); /* in: limit to set */
-/***********************************************************************
-Calculates where in log files we find a specified lsn. */
+ ulint limit); /*!< in: limit to set */
+#endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
+Calculates where in log files we find a specified lsn.
+@return log file number */
UNIV_INTERN
ulint
log_calc_where_lsn_is(
/*==================*/
- /* out: log file number */
- ib_int64_t* log_file_offset, /* out: offset in that file
+ ib_int64_t* log_file_offset, /*!< out: offset in that file
(including the header) */
- ib_uint64_t first_header_lsn, /* in: first log file start
+ ib_uint64_t first_header_lsn, /*!< in: first log file start
lsn */
- ib_uint64_t lsn, /* in: lsn whose position to
+ ib_uint64_t lsn, /*!< in: lsn whose position to
determine */
- ulint n_log_files, /* in: total number of log
+ ulint n_log_files, /*!< in: total number of log
files */
- ib_int64_t log_file_size); /* in: log file size
+ ib_int64_t log_file_size); /*!< in: log file size
(including the header) */
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Writes to the log the string given. The log must be released with
-log_release. */
+log_release.
+@return end lsn of the log record, zero if did not succeed */
UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
- /* out: end lsn of the log record,
- zero if did not succeed */
- byte* str, /* in: string */
- ulint len, /* in: string length */
- ib_uint64_t* start_lsn,/* out: start lsn of the log record */
- ibool* success);/* out: TRUE if success */
-/***************************************************************************
+ const void* str, /*!< in: string */
+ ulint len, /*!< in: string length */
+ ib_uint64_t* start_lsn);/*!< out: start lsn of the log record */
+/***********************************************************************//**
Releases the log mutex. */
UNIV_INLINE
void
log_release(void);
/*=============*/
-/***************************************************************************
+/***********************************************************************//**
Checks if there is need for a log buffer flush or a new checkpoint, and does
this if yes. Any database operation should call this when it has modified
more than about 4 pages. NOTE that this function may only be called when the
@@ -100,69 +136,77 @@ UNIV_INLINE
void
log_free_check(void);
/*================*/
-/****************************************************************
+/************************************************************//**
Opens the log for log_write_low. The log must be closed with log_close and
-released with log_release. */
+released with log_release.
+@return start lsn of the log record */
UNIV_INTERN
ib_uint64_t
log_reserve_and_open(
/*=================*/
- /* out: start lsn of the log record */
- ulint len); /* in: length of data to be catenated */
-/****************************************************************
+ ulint len); /*!< in: length of data to be catenated */
+/************************************************************//**
Writes to the log the string given. It is assumed that the caller holds the
log mutex. */
UNIV_INTERN
void
log_write_low(
/*==========*/
- byte* str, /* in: string */
- ulint str_len); /* in: string length */
-/****************************************************************
-Closes the log. */
+ byte* str, /*!< in: string */
+ ulint str_len); /*!< in: string length */
+/************************************************************//**
+Closes the log.
+@return lsn */
UNIV_INTERN
ib_uint64_t
log_close(void);
/*===========*/
- /* out: lsn */
-/****************************************************************
-Gets the current lsn. */
+/************************************************************//**
+Gets the current lsn.
+@return current lsn */
UNIV_INLINE
ib_uint64_t
log_get_lsn(void);
/*=============*/
- /* out: current lsn */
-/**********************************************************
+/****************************************************************
+Gets the log group capacity. It is OK to read the value without
+holding log_sys->mutex because it is constant.
+@return log group capacity */
+UNIV_INLINE
+ulint
+log_get_capacity(void);
+/*==================*/
+/******************************************************//**
Initializes the log. */
UNIV_INTERN
void
log_init(void);
/*==========*/
-/**********************************************************************
+/******************************************************************//**
Inits a log group to the log system. */
UNIV_INTERN
void
log_group_init(
/*===========*/
- ulint id, /* in: group id */
- ulint n_files, /* in: number of log files */
- ulint file_size, /* in: log file size in bytes */
- ulint space_id, /* in: space id of the file space
+ ulint id, /*!< in: group id */
+ ulint n_files, /*!< in: number of log files */
+ ulint file_size, /*!< in: log file size in bytes */
+ ulint space_id, /*!< in: space id of the file space
which contains the log files of this
group */
- ulint archive_space_id); /* in: space id of the file space
+ ulint archive_space_id); /*!< in: space id of the file space
which contains some archived log
files for this group; currently, only
for the first log group this is
used */
-/**********************************************************
+/******************************************************//**
Completes an i/o to a log file. */
UNIV_INTERN
void
log_io_complete(
/*============*/
- log_group_t* group); /* in: log group */
-/**********************************************************
+ log_group_t* group); /*!< in: log group */
+/******************************************************//**
This function is called, e.g., when a transaction wants to commit. It checks
that the log has been written to the log file up to the last log entry written
by the transaction. If there is a flush running, it waits and checks if the
@@ -171,81 +215,80 @@ UNIV_INTERN
void
log_write_up_to(
/*============*/
- ib_uint64_t lsn, /* in: log sequence number up to which
+ ib_uint64_t lsn, /*!< in: log sequence number up to which
the log should be written,
IB_ULONGLONG_MAX if not specified */
- ulint wait, /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
+ ulint wait, /*!< in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
or LOG_WAIT_ALL_GROUPS */
ibool flush_to_disk);
- /* in: TRUE if we want the written log
+ /*!< in: TRUE if we want the written log
also to be flushed to disk */
-/********************************************************************
+/****************************************************************//**
Does a syncronous flush of the log buffer to disk. */
UNIV_INTERN
void
log_buffer_flush_to_disk(void);
/*==========================*/
-/********************************************************************
-Flushes the log buffer. Forces it to disk depending on the value of
-the configuration parameter innodb_flush_log_at_trx_commit. */
+/****************************************************************//**
+This functions writes the log buffer to the log file and if 'flush'
+is set it forces a flush of the log file as well. This is meant to be
+called from background master thread only as it does not wait for
+the write (+ possible flush) to finish. */
UNIV_INTERN
void
-log_buffer_flush_maybe_sync(void);
-/*=============================*/
-/********************************************************************
+log_buffer_sync_in_background(
+/*==========================*/
+ ibool flush); /*<! in: flush the logs to disk */
+/****************************************************************//**
Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool and also may make a new checkpoint. NOTE: this function may only
-be called if the calling thread owns no synchronization objects! */
+be called if the calling thread owns no synchronization objects!
+@return FALSE if there was a flush batch of the same type running,
+which means that we could not start this flush batch */
UNIV_INTERN
ibool
log_preflush_pool_modified_pages(
/*=============================*/
- /* out: FALSE if there was a
- flush batch of the same type
- running, which means that we
- could not start this flush
- batch */
- ib_uint64_t new_oldest, /* in: try to advance
+ ib_uint64_t new_oldest, /*!< in: try to advance
oldest_modified_lsn at least
to this lsn */
- ibool sync); /* in: TRUE if synchronous
+ ibool sync); /*!< in: TRUE if synchronous
operation is desired */
-/**********************************************************
+/******************************************************//**
Makes a checkpoint. Note that this function does not flush dirty
blocks from the buffer pool: it only checks what is lsn of the oldest
modification in the pool, and writes information about the lsn in
-log files. Use log_make_checkpoint_at to flush also the pool. */
+log files. Use log_make_checkpoint_at to flush also the pool.
+@return TRUE if success, FALSE if a checkpoint write was already running */
UNIV_INTERN
ibool
log_checkpoint(
/*===========*/
- /* out: TRUE if success, FALSE if a checkpoint
- write was already running */
- ibool sync, /* in: TRUE if synchronous operation is
+ ibool sync, /*!< in: TRUE if synchronous operation is
desired */
- ibool write_always); /* in: the function normally checks if the
+ ibool write_always); /*!< in: the function normally checks if the
the new checkpoint would have a greater
lsn than the previous one: if not, then no
physical write is done; by setting this
parameter TRUE, a physical write will always be
made to log files */
-/********************************************************************
+/****************************************************************//**
Makes a checkpoint at a given lsn or later. */
UNIV_INTERN
void
log_make_checkpoint_at(
/*===================*/
- ib_uint64_t lsn, /* in: make a checkpoint at this or a
+ ib_uint64_t lsn, /*!< in: make a checkpoint at this or a
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
- ibool write_always); /* in: the function normally checks if
- the the new checkpoint would have a
+ ibool write_always); /*!< in: the function normally checks if
+ the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
by setting this parameter TRUE, a
physical write will always be made to
log files */
-/********************************************************************
+/****************************************************************//**
Makes a checkpoint at the latest lsn and writes it to first page of each
data file in the database, so that we know that the file spaces contain
all modifications up to that lsn. This can only be called at database
@@ -254,97 +297,96 @@ UNIV_INTERN
void
logs_empty_and_mark_files_at_shutdown(void);
/*=======================================*/
-/**********************************************************
+/******************************************************//**
Reads a checkpoint info from a log group header to log_sys->checkpoint_buf. */
UNIV_INTERN
void
log_group_read_checkpoint_info(
/*===========================*/
- log_group_t* group, /* in: log group */
- ulint field); /* in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */
-/***********************************************************************
+ log_group_t* group, /*!< in: log group */
+ ulint field); /*!< in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */
+/*******************************************************************//**
Gets info from a checkpoint about a log group. */
UNIV_INTERN
void
log_checkpoint_get_nth_group_info(
/*==============================*/
- byte* buf, /* in: buffer containing checkpoint info */
- ulint n, /* in: nth slot */
- ulint* file_no,/* out: archived file number */
- ulint* offset);/* out: archived file offset */
-/**********************************************************
+ const byte* buf, /*!< in: buffer containing checkpoint info */
+ ulint n, /*!< in: nth slot */
+ ulint* file_no,/*!< out: archived file number */
+ ulint* offset);/*!< out: archived file offset */
+/******************************************************//**
Writes checkpoint info to groups. */
UNIV_INTERN
void
log_groups_write_checkpoint_info(void);
/*==================================*/
-#ifdef UNIV_HOTBACKUP
-/**********************************************************
-Writes info to a buffer of a log group when log files are created in
-backup restoration. */
-UNIV_INTERN
-void
-log_reset_first_header_and_checkpoint(
-/*==================================*/
- byte* hdr_buf,/* in: buffer which will be written to the
- start of the first log file */
- ib_uint64_t start); /* in: lsn of the start of the first log file;
- we pretend that there is a checkpoint at
- start + LOG_BLOCK_HDR_SIZE */
-#endif /* UNIV_HOTBACKUP */
-/************************************************************************
-Starts an archiving operation. */
+/********************************************************************//**
+Starts an archiving operation.
+@return TRUE if succeed, FALSE if an archiving operation was already running */
UNIV_INTERN
ibool
log_archive_do(
/*===========*/
- /* out: TRUE if succeed, FALSE if an archiving
- operation was already running */
- ibool sync, /* in: TRUE if synchronous operation is desired */
- ulint* n_bytes);/* out: archive log buffer size, 0 if nothing to
+ ibool sync, /*!< in: TRUE if synchronous operation is desired */
+ ulint* n_bytes);/*!< out: archive log buffer size, 0 if nothing to
archive */
-/********************************************************************
+/****************************************************************//**
Writes the log contents to the archive up to the lsn when this function was
called, and stops the archiving. When archiving is started again, the archived
log file numbers start from a number one higher, so that the archiving will
not write again to the archived log files which exist when this function
-returns. */
+returns.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_stop(void);
/*==================*/
- /* out: DB_SUCCESS or DB_ERROR */
-/********************************************************************
-Starts again archiving which has been stopped. */
+/****************************************************************//**
+Starts again archiving which has been stopped.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_start(void);
/*===================*/
- /* out: DB_SUCCESS or DB_ERROR */
-/********************************************************************
-Stop archiving the log so that a gap may occur in the archived log files. */
+/****************************************************************//**
+Stop archiving the log so that a gap may occur in the archived log files.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_noarchivelog(void);
/*==========================*/
- /* out: DB_SUCCESS or DB_ERROR */
-/********************************************************************
-Start archiving the log so that a gap may occur in the archived log files. */
+/****************************************************************//**
+Start archiving the log so that a gap may occur in the archived log files.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_archivelog(void);
/*========================*/
- /* out: DB_SUCCESS or DB_ERROR */
-/**********************************************************
+/******************************************************//**
Generates an archived log file name. */
UNIV_INTERN
void
log_archived_file_name_gen(
/*=======================*/
- char* buf, /* in: buffer where to write */
- ulint id, /* in: group id */
- ulint file_no);/* in: file number */
-/************************************************************************
+ char* buf, /*!< in: buffer where to write */
+ ulint id, /*!< in: group id */
+ ulint file_no);/*!< in: file number */
+#else /* !UNIV_HOTBACKUP */
+/******************************************************//**
+Writes info to a buffer of a log group when log files are created in
+backup restoration. */
+UNIV_INTERN
+void
+log_reset_first_header_and_checkpoint(
+/*==================================*/
+ byte* hdr_buf,/*!< in: buffer which will be written to the
+ start of the first log file */
+ ib_uint64_t start); /*!< in: lsn of the start of the first log file;
+ we pretend that there is a checkpoint at
+ start + LOG_BLOCK_HDR_SIZE */
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Checks that there is enough free space in the log to start a new query step.
Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this
function may only be called if the calling thread owns no synchronization
@@ -353,35 +395,36 @@ UNIV_INTERN
void
log_check_margins(void);
/*===================*/
-/**********************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************//**
Reads a specified log segment to a buffer. */
UNIV_INTERN
void
log_group_read_log_seg(
/*===================*/
- ulint type, /* in: LOG_ARCHIVE or LOG_RECOVER */
- byte* buf, /* in: buffer where to read */
- log_group_t* group, /* in: log group */
- ib_uint64_t start_lsn, /* in: read area start */
- ib_uint64_t end_lsn); /* in: read area end */
-/**********************************************************
+ ulint type, /*!< in: LOG_ARCHIVE or LOG_RECOVER */
+ byte* buf, /*!< in: buffer where to read */
+ log_group_t* group, /*!< in: log group */
+ ib_uint64_t start_lsn, /*!< in: read area start */
+ ib_uint64_t end_lsn); /*!< in: read area end */
+/******************************************************//**
Writes a buffer to a log file group. */
UNIV_INTERN
void
log_group_write_buf(
/*================*/
- log_group_t* group, /* in: log group */
- byte* buf, /* in: buffer */
- ulint len, /* in: buffer len; must be divisible
+ log_group_t* group, /*!< in: log group */
+ byte* buf, /*!< in: buffer */
+ ulint len, /*!< in: buffer len; must be divisible
by OS_FILE_LOG_BLOCK_SIZE */
- ib_uint64_t start_lsn, /* in: start lsn of the buffer; must
+ ib_uint64_t start_lsn, /*!< in: start lsn of the buffer; must
be divisible by
OS_FILE_LOG_BLOCK_SIZE */
- ulint new_data_offset);/* in: start offset of new data in
+ ulint new_data_offset);/*!< in: start offset of new data in
buf: this parameter is used to decide
if we have to write a new log file
header */
-/************************************************************
+/********************************************************//**
Sets the field values in group to correspond to a given lsn. For this function
to work, the values must already be correctly initialized to correspond to
some lsn, for instance, a checkpoint lsn. */
@@ -389,150 +432,158 @@ UNIV_INTERN
void
log_group_set_fields(
/*=================*/
- log_group_t* group, /* in: group */
- ib_uint64_t lsn); /* in: lsn for which the values should be
+ log_group_t* group, /*!< in/out: group */
+ ib_uint64_t lsn); /*!< in: lsn for which the values should be
set */
-/**********************************************************
+/******************************************************//**
Calculates the data capacity of a log group, when the log file headers are not
-included. */
+included.
+@return capacity in bytes */
UNIV_INTERN
ulint
log_group_get_capacity(
/*===================*/
- /* out: capacity in bytes */
- log_group_t* group); /* in: log group */
-/****************************************************************
-Gets a log block flush bit. */
+ const log_group_t* group); /*!< in: log group */
+#endif /* !UNIV_HOTBACKUP */
+/************************************************************//**
+Gets a log block flush bit.
+@return TRUE if this block was the first to be written in a log flush */
UNIV_INLINE
ibool
log_block_get_flush_bit(
/*====================*/
- /* out: TRUE if this block was the first
- to be written in a log flush */
- byte* log_block); /* in: log block */
-/****************************************************************
-Gets a log block number stored in the header. */
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
+Gets a log block number stored in the header.
+@return log block number stored in the block header */
UNIV_INLINE
ulint
log_block_get_hdr_no(
/*=================*/
- /* out: log block number stored in the block
- header */
- byte* log_block); /* in: log block */
-/****************************************************************
-Gets a log block data length. */
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
+Gets a log block data length.
+@return log block data length measured as a byte offset from the block start */
UNIV_INLINE
ulint
log_block_get_data_len(
/*===================*/
- /* out: log block data length measured as a
- byte offset from the block start */
- byte* log_block); /* in: log block */
-/****************************************************************
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
Sets the log block data length. */
UNIV_INLINE
void
log_block_set_data_len(
/*===================*/
- byte* log_block, /* in: log block */
- ulint len); /* in: data length */
-/****************************************************************
-Calculates the checksum for a log block. */
+ 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(
/*====================*/
- /* out: checksum */
- const byte* block); /* in: log block */
-/****************************************************************
-Gets a log block checksum field value. */
+ const byte* block); /*!< in: log block */
+/************************************************************//**
+Gets a log block checksum field value.
+@return checksum */
UNIV_INLINE
ulint
log_block_get_checksum(
/*===================*/
- /* out: checksum */
- const byte* log_block); /* in: log block */
-/****************************************************************
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
Sets a log block checksum field value. */
UNIV_INLINE
void
log_block_set_checksum(
/*===================*/
- byte* log_block, /* in: log block */
- ulint checksum); /* in: checksum */
-/****************************************************************
-Gets a log block first mtr log record group offset. */
+ byte* log_block, /*!< in/out: log block */
+ ulint checksum); /*!< in: checksum */
+/************************************************************//**
+Gets a log block first mtr log record group offset.
+@return first mtr log record group byte offset from the block start, 0
+if none */
UNIV_INLINE
ulint
log_block_get_first_rec_group(
/*==========================*/
- /* out: first mtr log record group byte offset
- from the block start, 0 if none */
- byte* log_block); /* in: log block */
-/****************************************************************
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
Sets the log block first mtr log record group offset. */
UNIV_INLINE
void
log_block_set_first_rec_group(
/*==========================*/
- byte* log_block, /* in: log block */
- ulint offset); /* in: offset, 0 if none */
-/****************************************************************
-Gets a log block checkpoint number field (4 lowest bytes). */
+ byte* log_block, /*!< in/out: log block */
+ ulint offset); /*!< in: offset, 0 if none */
+/************************************************************//**
+Gets a log block checkpoint number field (4 lowest bytes).
+@return checkpoint no (4 lowest bytes) */
UNIV_INLINE
ulint
log_block_get_checkpoint_no(
/*========================*/
- /* out: checkpoint no (4 lowest bytes) */
- byte* log_block); /* in: log block */
-/****************************************************************
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
Initializes a log block in the log buffer. */
UNIV_INLINE
void
log_block_init(
/*===========*/
- byte* log_block, /* in: pointer to the log buffer */
- ib_uint64_t lsn); /* in: lsn within the log block */
-/****************************************************************
+ byte* log_block, /*!< in: pointer to the log buffer */
+ ib_uint64_t lsn); /*!< in: lsn within the log block */
+/************************************************************//**
Initializes a log block in the log buffer in the old, < 3.23.52 format, where
there was no checksum yet. */
UNIV_INLINE
void
log_block_init_in_old_format(
/*=========================*/
- byte* log_block, /* in: pointer to the log buffer */
- ib_uint64_t lsn); /* in: lsn within the log block */
-/****************************************************************
-Converts a lsn to a log block number. */
+ byte* log_block, /*!< in: pointer to the log buffer */
+ ib_uint64_t lsn); /*!< in: lsn within the log block */
+/************************************************************//**
+Converts a lsn to a log block number.
+@return log block number, it is > 0 and <= 1G */
UNIV_INLINE
ulint
log_block_convert_lsn_to_no(
/*========================*/
- /* out: log block number,
- it is > 0 and <= 1G */
- ib_uint64_t lsn); /* in: lsn of a byte within the block */
-/**********************************************************
+ ib_uint64_t lsn); /*!< in: lsn of a byte within the block */
+/******************************************************//**
Prints info of the log. */
UNIV_INTERN
void
log_print(
/*======*/
- FILE* file); /* in: file where to print */
-/**********************************************************
-Peeks the current lsn. */
+ FILE* file); /*!< in: file where to print */
+/******************************************************//**
+Peeks the current lsn.
+@return TRUE if success, FALSE if could not get the log system mutex */
UNIV_INTERN
ibool
log_peek_lsn(
/*=========*/
- /* out: TRUE if success, FALSE if
- could not get the log system mutex */
- ib_uint64_t* lsn); /* out: if returns TRUE, current lsn is here */
-/**************************************************************************
+ ib_uint64_t* lsn); /*!< out: if returns TRUE, current lsn is here */
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
log_refresh_stats(void);
/*===================*/
+/**********************************************************
+Shutdown the log system but do not release all the memory. */
+UNIV_INTERN
+void
+log_shutdown(void);
+/*==============*/
+/**********************************************************
+Free the log system data structures. */
+UNIV_INTERN
+void
+log_mem_free(void);
+/*==============*/
extern log_t* log_sys;
@@ -545,7 +596,7 @@ extern log_t* log_sys;
#define LOG_RECOVER 98887331
/* The counting of lsn's starts from this value: this must be non-zero */
-#define LOG_START_LSN ((ib_uint64_t) (16 * OS_FILE_LOG_BLOCK_SIZE))
+#define LOG_START_LSN ((ib_uint64_t) (16 * OS_FILE_LOG_BLOCK_SIZE))
#define LOG_BUFFER_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE)
#define LOG_ARCHIVE_BUF_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE / 4)
@@ -597,7 +648,7 @@ extern log_t* log_sys;
#define LOG_CHECKPOINT_ARCHIVED_LSN 24
#define LOG_CHECKPOINT_GROUP_ARRAY 32
-/* For each value < LOG_MAX_N_GROUPS the following 8 bytes: */
+/* For each value smaller than LOG_MAX_N_GROUPS the following 8 bytes: */
#define LOG_CHECKPOINT_ARCHIVED_FILE_NO 0
#define LOG_CHECKPOINT_ARCHIVED_OFFSET 4
@@ -665,74 +716,84 @@ extern log_t* log_sys;
#define LOG_GROUP_OK 301
#define LOG_GROUP_CORRUPTED 302
-/* Log group consists of a number of log files, each of the same size; a log
+/** Log group consists of a number of log files, each of the same size; a log
group is implemented as a space in the sense of the module fil0fil. */
-
struct log_group_struct{
/* The following fields are protected by log_sys->mutex */
- ulint id; /* log group id */
- ulint n_files; /* number of files in the group */
- ulint file_size; /* individual log file size in bytes,
+ ulint id; /*!< log group id */
+ ulint n_files; /*!< number of files in the group */
+ ulint file_size; /*!< individual log file size in bytes,
including the log file header */
- ulint space_id; /* file space which implements the log
+ ulint space_id; /*!< file space which implements the log
group */
- ulint state; /* LOG_GROUP_OK or
+ ulint state; /*!< LOG_GROUP_OK or
LOG_GROUP_CORRUPTED */
- ib_uint64_t lsn; /* lsn used to fix coordinates within
+ ib_uint64_t lsn; /*!< lsn used to fix coordinates within
the log group */
- ulint lsn_offset; /* the offset of the above lsn */
- ulint n_pending_writes;/* number of currently pending flush
+ ulint lsn_offset; /*!< the offset of the above lsn */
+ ulint n_pending_writes;/*!< number of currently pending flush
writes for this log group */
- byte** file_header_bufs;/* buffers for each file header in the
- group */
+ byte** file_header_bufs_ptr;/*!< unaligned buffers */
+ byte** file_header_bufs;/*!< buffers for each file
+ header in the group */
+#ifdef UNIV_LOG_ARCHIVE
/*-----------------------------*/
- byte** archive_file_header_bufs;/* buffers for each file
+ byte** archive_file_header_bufs_ptr;/*!< unaligned buffers */
+ byte** archive_file_header_bufs;/*!< buffers for each file
header in the group */
- ulint archive_space_id;/* file space which implements the log
- group archive */
- ulint archived_file_no;/* file number corresponding to
+ ulint archive_space_id;/*!< file space which
+ implements the log group
+ archive */
+ ulint archived_file_no;/*!< file number corresponding to
log_sys->archived_lsn */
- ulint archived_offset;/* file offset corresponding to
+ ulint archived_offset;/*!< file offset corresponding to
log_sys->archived_lsn, 0 if we have
not yet written to the archive file
number archived_file_no */
- ulint next_archived_file_no;/* during an archive write,
+ ulint next_archived_file_no;/*!< during an archive write,
until the write is completed, we
store the next value for
archived_file_no here: the write
completion function then sets the new
value to ..._file_no */
- ulint next_archived_offset; /* like the preceding field */
+ ulint next_archived_offset; /*!< like the preceding field */
+#endif /* UNIV_LOG_ARCHIVE */
/*-----------------------------*/
- ib_uint64_t scanned_lsn; /* used only in recovery: recovery scan
+ ib_uint64_t scanned_lsn; /*!< used only in recovery: recovery scan
succeeded up to this lsn in this log
group */
- byte* checkpoint_buf; /* checkpoint header is written from
+ byte* checkpoint_buf_ptr;/*!< unaligned checkpoint header */
+ byte* checkpoint_buf; /*!< checkpoint header is written from
this buffer to the group */
UT_LIST_NODE_T(log_group_t)
- log_groups; /* list of log groups */
+ log_groups; /*!< list of log groups */
};
+/** Redo log buffer */
struct log_struct{
- byte pad[64]; /* padding to prevent other memory
+ byte pad[64]; /*!< padding to prevent other memory
update hotspots from residing on the
same memory cache line */
- ib_uint64_t lsn; /* log sequence number */
- ulint buf_free; /* first free offset within the log
+ ib_uint64_t lsn; /*!< log sequence number */
+ ulint buf_free; /*!< first free offset within the log
buffer */
- mutex_t mutex; /* mutex protecting the log */
- byte* buf; /* log buffer */
- ulint buf_size; /* log buffer size in bytes */
- ulint max_buf_free; /* recommended maximum value of
+#ifndef UNIV_HOTBACKUP
+ mutex_t mutex; /*!< mutex protecting the log */
+#endif /* !UNIV_HOTBACKUP */
+ byte* buf_ptr; /* unaligned log buffer */
+ byte* buf; /*!< log buffer */
+ ulint buf_size; /*!< log buffer size in bytes */
+ ulint max_buf_free; /*!< recommended maximum value of
buf_free, after which the buffer is
flushed */
- ulint old_buf_free; /* value of buf free when log was
+ ulint old_buf_free; /*!< value of buf free when log was
last time opened; only in the debug
version */
- ib_uint64_t old_lsn; /* value of lsn when log was last time
- opened; only in the debug version */
+ ib_uint64_t old_lsn; /*!< value of lsn when log was
+ last time opened; only in the
+ debug version */
ibool check_flush_or_checkpoint;
- /* this is set to TRUE when there may
+ /*!< this is set to TRUE when there may
be need to flush the log buffer, or
preflush buffer pool pages, or make
a checkpoint; this MUST be TRUE when
@@ -741,11 +802,12 @@ struct log_struct{
peeked at by log_free_check(), which
does not reserve the log mutex */
UT_LIST_BASE_NODE_T(log_group_t)
- log_groups; /* log groups */
+ log_groups; /*!< log groups */
- /* The fields involved in the log buffer flush */
+#ifndef UNIV_HOTBACKUP
+ /** The fields involved in the log buffer flush @{ */
- ulint buf_next_to_write;/* first offset in the log buffer
+ ulint buf_next_to_write;/*!< first offset in the log buffer
where the byte content may not exist
written to file, e.g., the start
offset of a log record catenated
@@ -753,44 +815,46 @@ struct log_struct{
operation is completed to all the log
groups */
ib_uint64_t written_to_some_lsn;
- /* first log sequence number not yet
+ /*!< first log sequence number not yet
written to any log group; for this to
be advanced, it is enough that the
write i/o has been completed for any
one log group */
ib_uint64_t written_to_all_lsn;
- /* first log sequence number not yet
+ /*!< first log sequence number not yet
written to some log group; for this to
be advanced, it is enough that the
write i/o has been completed for all
log groups */
- ib_uint64_t write_lsn; /* end lsn for the current running
+ ib_uint64_t write_lsn; /*!< end lsn for the current running
write */
- ulint write_end_offset;/* the data in buffer has been written
- up to this offset when the current
- write ends: this field will then
- be copied to buf_next_to_write */
- ib_uint64_t current_flush_lsn;/* end lsn for the current running
+ ulint write_end_offset;/*!< the data in buffer has
+ been written up to this offset
+ when the current write ends:
+ this field will then be copied
+ to buf_next_to_write */
+ ib_uint64_t current_flush_lsn;/*!< end lsn for the current running
write + flush operation */
ib_uint64_t flushed_to_disk_lsn;
- /* how far we have written the log
+ /*!< how far we have written the log
AND flushed to disk */
- ulint n_pending_writes;/* number of currently pending flushes
- or writes */
+ ulint n_pending_writes;/*!< number of currently
+ pending flushes or writes */
/* NOTE on the 'flush' in names of the fields below: starting from
4.0.14, we separate the write of the log file and the actual fsync()
or other method to flush it to disk. The names below shhould really
be 'flush_or_write'! */
- os_event_t no_flush_event; /* this event is in the reset state
+ os_event_t no_flush_event; /*!< this event is in the reset state
when a flush or a write is running;
a thread should wait for this without
owning the log mutex, but NOTE that
to set or reset this event, the
thread MUST own the log mutex! */
- ibool one_flushed; /* during a flush, this is first FALSE
- and becomes TRUE when one log group
- has been written or flushed */
- os_event_t one_flushed_event;/* this event is reset when the
+ ibool one_flushed; /*!< during a flush, this is
+ first FALSE and becomes TRUE
+ when one log group has been
+ written or flushed */
+ os_event_t one_flushed_event;/*!< this event is reset when the
flush or write has not yet completed
for any log group; e.g., this means
that a transaction has been committed
@@ -799,99 +863,111 @@ struct log_struct{
but NOTE that to set or reset this
event, the thread MUST own the log
mutex! */
- ulint n_log_ios; /* number of log i/os initiated thus
+ ulint n_log_ios; /*!< number of log i/os initiated thus
far */
- ulint n_log_ios_old; /* number of log i/o's at the
+ ulint n_log_ios_old; /*!< number of log i/o's at the
previous printout */
- time_t last_printout_time;/* when log_print was last time
+ time_t last_printout_time;/*!< when log_print was last time
called */
+ /* @} */
- /* Fields involved in checkpoints */
- ulint log_group_capacity; /* capacity of the log group; if
+ /** Fields involved in checkpoints @{ */
+ ulint log_group_capacity; /*!< capacity of the log group; if
the checkpoint age exceeds this, it is
a serious error because it is possible
we will then overwrite log and spoil
crash recovery */
ulint max_modified_age_async;
- /* when this recommended value for lsn
- - buf_pool_get_oldest_modification()
- is exceeded, we start an asynchronous
- preflush of pool pages */
+ /*!< when this recommended
+ value for lsn -
+ buf_pool_get_oldest_modification()
+ is exceeded, we start an
+ asynchronous preflush of pool pages */
ulint max_modified_age_sync;
- /* when this recommended value for lsn
- - buf_pool_get_oldest_modification()
- is exceeded, we start a synchronous
- preflush of pool pages */
+ /*!< when this recommended
+ value for lsn -
+ buf_pool_get_oldest_modification()
+ is exceeded, we start a
+ synchronous preflush of pool pages */
ulint adm_checkpoint_interval;
- /* administrator-specified checkpoint
+ /*!< administrator-specified checkpoint
interval in terms of log growth in
bytes; the interval actually used by
the database can be smaller */
ulint max_checkpoint_age_async;
- /* when this checkpoint age is exceeded
- we start an asynchronous writing of a
- new checkpoint */
+ /*!< when this checkpoint age
+ is exceeded we start an
+ asynchronous writing of a new
+ checkpoint */
ulint max_checkpoint_age;
- /* this is the maximum allowed value
+ /*!< this is the maximum allowed value
for lsn - last_checkpoint_lsn when a
new query step is started */
ib_uint64_t next_checkpoint_no;
- /* next checkpoint number */
+ /*!< next checkpoint number */
ib_uint64_t last_checkpoint_lsn;
- /* latest checkpoint lsn */
+ /*!< latest checkpoint lsn */
ib_uint64_t next_checkpoint_lsn;
- /* next checkpoint lsn */
+ /*!< next checkpoint lsn */
ulint n_pending_checkpoint_writes;
- /* number of currently pending
+ /*!< number of currently pending
checkpoint writes */
- rw_lock_t checkpoint_lock;/* this latch is x-locked when a
+ rw_lock_t checkpoint_lock;/*!< this latch is x-locked when a
checkpoint write is running; a thread
should wait for this without owning
the log mutex */
- byte* checkpoint_buf; /* checkpoint header is read to this
+#endif /* !UNIV_HOTBACKUP */
+ byte* checkpoint_buf_ptr;/* unaligned checkpoint header */
+ byte* checkpoint_buf; /*!< checkpoint header is read to this
buffer */
+ /* @} */
#ifdef UNIV_LOG_ARCHIVE
- /* Fields involved in archiving */
- ulint archiving_state;/* LOG_ARCH_ON, LOG_ARCH_STOPPING
+ /** Fields involved in archiving @{ */
+ ulint archiving_state;/*!< LOG_ARCH_ON, LOG_ARCH_STOPPING
LOG_ARCH_STOPPED, LOG_ARCH_OFF */
- ib_uint64_t archived_lsn; /* archiving has advanced to this
+ ib_uint64_t archived_lsn; /*!< archiving has advanced to this
lsn */
ulint max_archived_lsn_age_async;
- /* recommended maximum age of
+ /*!< recommended maximum age of
archived_lsn, before we start
asynchronous copying to the archive */
ulint max_archived_lsn_age;
- /* maximum allowed age for
+ /*!< maximum allowed age for
archived_lsn */
- ib_uint64_t next_archived_lsn;/* during an archive write,
+ ib_uint64_t next_archived_lsn;/*!< during an archive write,
until the write is completed, we
store the next value for
archived_lsn here: the write
completion function then sets the new
value to archived_lsn */
- ulint archiving_phase;/* LOG_ARCHIVE_READ or
+ ulint archiving_phase;/*!< LOG_ARCHIVE_READ or
LOG_ARCHIVE_WRITE */
ulint n_pending_archive_ios;
- /* number of currently pending reads
+ /*!< number of currently pending reads
or writes in archiving */
- rw_lock_t archive_lock; /* this latch is x-locked when an
+ rw_lock_t archive_lock; /*!< this latch is x-locked when an
archive write is running; a thread
should wait for this without owning
the log mutex */
- ulint archive_buf_size;/* size of archive_buf */
- byte* archive_buf; /* log segment is written to the
+ ulint archive_buf_size;/*!< size of archive_buf */
+ byte* archive_buf; /*!< log segment is written to the
archive from this buffer */
- os_event_t archiving_on; /* if archiving has been stopped,
+ os_event_t archiving_on; /*!< if archiving has been stopped,
a thread can wait for this event to
become signaled */
+ /* @} */
#endif /* UNIV_LOG_ARCHIVE */
};
+#ifdef UNIV_LOG_ARCHIVE
+/** Archiving state @{ */
#define LOG_ARCH_ON 71
#define LOG_ARCH_STOPPING 72
#define LOG_ARCH_STOPPING2 73
#define LOG_ARCH_STOPPED 74
#define LOG_ARCH_OFF 75
+/* @} */
+#endif /* UNIV_LOG_ARCHIVE */
#ifndef UNIV_NONINL
#include "log0log.ic"
diff --git a/storage/xtradb/include/log0log.ic b/storage/xtradb/include/log0log.ic
index 85eebda4942..36d151a3064 100644
--- a/storage/xtradb/include/log0log.ic
+++ b/storage/xtradb/include/log0log.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/log0log.ic
Database log
Created 12/9/1995 Heikki Tuuri
@@ -26,28 +27,29 @@ Created 12/9/1995 Heikki Tuuri
#include "mach0data.h"
#include "mtr0mtr.h"
-/**********************************************************
+#ifdef UNIV_LOG_DEBUG
+/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
- byte* buf, /* in: pointer to the start of
+ const byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
- ulint len, /* in: segment length in bytes */
- ib_uint64_t buf_start_lsn); /* in: buffer start lsn */
+ ulint len, /*!< in: segment length in bytes */
+ ib_uint64_t buf_start_lsn); /*!< in: buffer start lsn */
+#endif /* UNIV_LOG_DEBUG */
-/****************************************************************
-Gets a log block flush bit. */
+/************************************************************//**
+Gets a log block flush bit.
+@return TRUE if this block was the first to be written in a log flush */
UNIV_INLINE
ibool
log_block_get_flush_bit(
/*====================*/
- /* out: TRUE if this block was the first
- to be written in a log flush */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
if (LOG_BLOCK_FLUSH_BIT_MASK
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)) {
@@ -58,14 +60,14 @@ log_block_get_flush_bit(
return(FALSE);
}
-/****************************************************************
+/************************************************************//**
Sets the log block flush bit. */
UNIV_INLINE
void
log_block_set_flush_bit(
/*====================*/
- byte* log_block, /* in: log block */
- ibool val) /* in: value to set */
+ byte* log_block, /*!< in/out: log block */
+ ibool val) /*!< in: value to set */
{
ulint field;
@@ -80,29 +82,28 @@ log_block_set_flush_bit(
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
}
-/****************************************************************
-Gets a log block number stored in the header. */
+/************************************************************//**
+Gets a log block number stored in the header.
+@return log block number stored in the block header */
UNIV_INLINE
ulint
log_block_get_hdr_no(
/*=================*/
- /* out: log block number stored in the block
- header */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(~LOG_BLOCK_FLUSH_BIT_MASK
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
}
-/****************************************************************
+/************************************************************//**
Sets the log block number stored in the header; NOTE that this must be set
before the flush bit! */
UNIV_INLINE
void
log_block_set_hdr_no(
/*=================*/
- byte* log_block, /* in: log block */
- ulint n) /* in: log block number: must be > 0 and
+ byte* log_block, /*!< in/out: log block */
+ ulint n) /*!< in: log block number: must be > 0 and
< LOG_BLOCK_FLUSH_BIT_MASK */
{
ut_ad(n > 0);
@@ -111,101 +112,99 @@ log_block_set_hdr_no(
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
}
-/****************************************************************
-Gets a log block data length. */
+/************************************************************//**
+Gets a log block data length.
+@return log block data length measured as a byte offset from the block start */
UNIV_INLINE
ulint
log_block_get_data_len(
/*===================*/
- /* out: log block data length measured as a
- byte offset from the block start */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(mach_read_from_2(log_block + LOG_BLOCK_HDR_DATA_LEN));
}
-/****************************************************************
+/************************************************************//**
Sets the log block data length. */
UNIV_INLINE
void
log_block_set_data_len(
/*===================*/
- byte* log_block, /* in: log block */
- ulint len) /* in: data length */
+ byte* log_block, /*!< in/out: log block */
+ ulint len) /*!< in: data length */
{
mach_write_to_2(log_block + LOG_BLOCK_HDR_DATA_LEN, len);
}
-/****************************************************************
-Gets a log block first mtr log record group offset. */
+/************************************************************//**
+Gets a log block first mtr log record group offset.
+@return first mtr log record group byte offset from the block start, 0
+if none */
UNIV_INLINE
ulint
log_block_get_first_rec_group(
/*==========================*/
- /* out: first mtr log record group byte offset
- from the block start, 0 if none */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(mach_read_from_2(log_block + LOG_BLOCK_FIRST_REC_GROUP));
}
-/****************************************************************
+/************************************************************//**
Sets the log block first mtr log record group offset. */
UNIV_INLINE
void
log_block_set_first_rec_group(
/*==========================*/
- byte* log_block, /* in: log block */
- ulint offset) /* in: offset, 0 if none */
+ byte* log_block, /*!< in/out: log block */
+ ulint offset) /*!< in: offset, 0 if none */
{
mach_write_to_2(log_block + LOG_BLOCK_FIRST_REC_GROUP, offset);
}
-/****************************************************************
-Gets a log block checkpoint number field (4 lowest bytes). */
+/************************************************************//**
+Gets a log block checkpoint number field (4 lowest bytes).
+@return checkpoint no (4 lowest bytes) */
UNIV_INLINE
ulint
log_block_get_checkpoint_no(
/*========================*/
- /* out: checkpoint no (4 lowest bytes) */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(mach_read_from_4(log_block + LOG_BLOCK_CHECKPOINT_NO));
}
-/****************************************************************
+/************************************************************//**
Sets a log block checkpoint number field (4 lowest bytes). */
UNIV_INLINE
void
log_block_set_checkpoint_no(
/*========================*/
- byte* log_block, /* in: log block */
- ib_uint64_t no) /* in: checkpoint no */
+ byte* log_block, /*!< in/out: log block */
+ ib_uint64_t no) /*!< in: checkpoint no */
{
mach_write_to_4(log_block + LOG_BLOCK_CHECKPOINT_NO, (ulint) no);
}
-/****************************************************************
-Converts a lsn to a log block number. */
+/************************************************************//**
+Converts a lsn to a log block number.
+@return log block number, it is > 0 and <= 1G */
UNIV_INLINE
ulint
log_block_convert_lsn_to_no(
/*========================*/
- /* out: log block number,
- it is > 0 and <= 1G */
- ib_uint64_t lsn) /* in: lsn of a byte within the block */
+ ib_uint64_t lsn) /*!< in: lsn of a byte within the block */
{
return(((ulint) (lsn / OS_FILE_LOG_BLOCK_SIZE) & 0x3FFFFFFFUL) + 1);
}
-/****************************************************************
-Calculates the checksum for a log block. */
+/************************************************************//**
+Calculates the checksum for a log block.
+@return checksum */
UNIV_INLINE
ulint
log_block_calc_checksum(
/*====================*/
- /* out: checksum */
- const byte* block) /* in: log block */
+ const byte* block) /*!< in: log block */
{
ulint sum;
ulint sh;
@@ -228,41 +227,41 @@ log_block_calc_checksum(
return(sum);
}
-/****************************************************************
-Gets a log block checksum field value. */
+/************************************************************//**
+Gets a log block checksum field value.
+@return checksum */
UNIV_INLINE
ulint
log_block_get_checksum(
/*===================*/
- /* out: checksum */
- const byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
- LOG_BLOCK_CHECKSUM));
}
-/****************************************************************
+/************************************************************//**
Sets a log block checksum field value. */
UNIV_INLINE
void
log_block_set_checksum(
/*===================*/
- byte* log_block, /* in: log block */
- ulint checksum) /* in: checksum */
+ byte* log_block, /*!< in/out: log block */
+ ulint checksum) /*!< in: checksum */
{
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
- LOG_BLOCK_CHECKSUM,
checksum);
}
-/****************************************************************
+/************************************************************//**
Initializes a log block in the log buffer. */
UNIV_INLINE
void
log_block_init(
/*===========*/
- byte* log_block, /* in: pointer to the log buffer */
- ib_uint64_t lsn) /* in: lsn within the log block */
+ byte* log_block, /*!< in: pointer to the log buffer */
+ ib_uint64_t lsn) /*!< in: lsn within the log block */
{
ulint no;
@@ -276,15 +275,15 @@ log_block_init(
log_block_set_first_rec_group(log_block, 0);
}
-/****************************************************************
+/************************************************************//**
Initializes a log block in the log buffer in the old format, where there
was no checksum yet. */
UNIV_INLINE
void
log_block_init_in_old_format(
/*=========================*/
- byte* log_block, /* in: pointer to the log buffer */
- ib_uint64_t lsn) /* in: lsn within the log block */
+ byte* log_block, /*!< in: pointer to the log buffer */
+ ib_uint64_t lsn) /*!< in: lsn within the log block */
{
ulint no;
@@ -299,67 +298,88 @@ log_block_init_in_old_format(
log_block_set_first_rec_group(log_block, 0);
}
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Writes to the log the string given. The log must be released with
-log_release. */
+log_release.
+@return end lsn of the log record, zero if did not succeed */
UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
- /* out: end lsn of the log record,
- zero if did not succeed */
- byte* str, /* in: string */
- ulint len, /* in: string length */
- ib_uint64_t* start_lsn,/* out: start lsn of the log record */
- ibool* success)/* out: TRUE if success */
+ const void* str, /*!< in: string */
+ ulint len, /*!< in: string length */
+ ib_uint64_t* start_lsn)/*!< out: start lsn of the log record */
{
- log_t* log = log_sys;
ulint data_len;
- ib_uint64_t lsn;
-
- *success = TRUE;
+#ifdef UNIV_LOG_LSN_DEBUG
+ /* length of the LSN pseudo-record */
+ ulint lsn_len = 1
+ + mach_get_compressed_size(log_sys->lsn >> 32)
+ + mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
+#endif /* UNIV_LOG_LSN_DEBUG */
- mutex_enter(&(log->mutex));
+ mutex_enter(&log_sys->mutex);
- data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
+ data_len = len
+#ifdef UNIV_LOG_LSN_DEBUG
+ + lsn_len
+#endif /* UNIV_LOG_LSN_DEBUG */
+ + log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
/* The string does not fit within the current log block
or the log block would become full */
- *success = FALSE;
-
- mutex_exit(&(log->mutex));
+ mutex_exit(&log_sys->mutex);
return(0);
}
- *start_lsn = log->lsn;
-
- ut_memcpy(log->buf + log->buf_free, str, len);
+ *start_lsn = log_sys->lsn;
+
+#ifdef UNIV_LOG_LSN_DEBUG
+ {
+ /* Write the LSN pseudo-record. */
+ byte* b = &log_sys->buf[log_sys->buf_free];
+ *b++ = MLOG_LSN | (MLOG_SINGLE_REC_FLAG & *(const byte*) str);
+ /* Write the LSN in two parts,
+ as a pseudo page number and space id. */
+ b += mach_write_compressed(b, log_sys->lsn >> 32);
+ b += mach_write_compressed(b, log_sys->lsn & 0xFFFFFFFFUL);
+ ut_a(b - lsn_len == &log_sys->buf[log_sys->buf_free]);
+
+ memcpy(b, str, len);
+ len += lsn_len;
+ }
+#else /* UNIV_LOG_LSN_DEBUG */
+ memcpy(log_sys->buf + log_sys->buf_free, str, len);
+#endif /* UNIV_LOG_LSN_DEBUG */
- log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
+ log_block_set_data_len((byte*) ut_align_down(log_sys->buf
+ + log_sys->buf_free,
OS_FILE_LOG_BLOCK_SIZE),
data_len);
#ifdef UNIV_LOG_DEBUG
- log->old_buf_free = log->buf_free;
- log->old_lsn = log->lsn;
+ log_sys->old_buf_free = log_sys->buf_free;
+ log_sys->old_lsn = log_sys->lsn;
#endif
- log->buf_free += len;
+ log_sys->buf_free += len;
- ut_ad(log->buf_free <= log->buf_size);
+ ut_ad(log_sys->buf_free <= log_sys->buf_size);
- lsn = log->lsn += len;
+ log_sys->lsn += len;
#ifdef UNIV_LOG_DEBUG
- log_check_log_recs(log->buf + log->old_buf_free,
- log->buf_free - log->old_buf_free, log->old_lsn);
+ log_check_log_recs(log_sys->buf + log_sys->old_buf_free,
+ log_sys->buf_free - log_sys->old_buf_free,
+ log_sys->old_lsn);
#endif
- return(lsn);
+ return(log_sys->lsn);
}
-/***************************************************************************
+/***********************************************************************//**
Releases the log mutex. */
UNIV_INLINE
void
@@ -369,13 +389,13 @@ log_release(void)
mutex_exit(&(log_sys->mutex));
}
-/****************************************************************
-Gets the current lsn. */
+/************************************************************//**
+Gets the current lsn.
+@return current lsn */
UNIV_INLINE
ib_uint64_t
log_get_lsn(void)
/*=============*/
- /* out: current lsn */
{
ib_uint64_t lsn;
@@ -388,7 +408,19 @@ log_get_lsn(void)
return(lsn);
}
-/***************************************************************************
+/****************************************************************
+Gets the log group capacity. It is OK to read the value without
+holding log_sys->mutex because it is constant.
+@return log group capacity */
+UNIV_INLINE
+ulint
+log_get_capacity(void)
+/*==================*/
+{
+ return(log_sys->log_group_capacity);
+}
+
+/***********************************************************************//**
Checks if there is need for a log buffer flush or a new checkpoint, and does
this if yes. Any database operation should call this when it has modified
more than about 4 pages. NOTE that this function may only be called when the
@@ -405,3 +437,4 @@ log_free_check(void)
log_check_margins();
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/log0recv.h b/storage/xtradb/include/log0recv.h
index e3fe9ed330a..ac6b19a3f6a 100644
--- a/storage/xtradb/include/log0recv.h
+++ b/storage/xtradb/include/log0recv.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/log0recv.h
Recovery
Created 9/20/1997 Heikki Tuuri
@@ -34,189 +35,243 @@ Created 9/20/1997 Heikki Tuuri
#ifdef UNIV_HOTBACKUP
extern ibool recv_replay_file_ops;
-/***********************************************************************
-Reads the checkpoint info needed in hot backup. */
+/*******************************************************************//**
+Reads the checkpoint info needed in hot backup.
+@return TRUE if success */
UNIV_INTERN
ibool
recv_read_cp_info_for_backup(
/*=========================*/
- /* out: TRUE if success */
- byte* hdr, /* in: buffer containing the log group
+ const byte* hdr, /*!< in: buffer containing the log group
header */
- ib_uint64_t* lsn, /* out: checkpoint lsn */
- ulint* offset, /* out: checkpoint offset in the log group */
- ulint* fsp_limit,/* out: fsp limit of space 0,
+ ib_uint64_t* lsn, /*!< out: checkpoint lsn */
+ ulint* offset, /*!< out: checkpoint offset in the log group */
+ ulint* fsp_limit,/*!< out: fsp limit of space 0,
1000000000 if the database is running
with < version 3.23.50 of InnoDB */
- ib_uint64_t* cp_no, /* out: checkpoint number */
+ ib_uint64_t* cp_no, /*!< out: checkpoint number */
ib_uint64_t* first_header_lsn);
- /* out: lsn of of the start of the
+ /*!< out: lsn of of the start of the
first log file */
-/***********************************************************************
+/*******************************************************************//**
Scans the log segment and n_bytes_scanned is set to the length of valid
log scanned. */
UNIV_INTERN
void
recv_scan_log_seg_for_backup(
/*=========================*/
- byte* buf, /* in: buffer containing log data */
- ulint buf_len, /* in: data length in that buffer */
- ib_uint64_t* scanned_lsn, /* in/out: lsn of buffer start,
+ byte* buf, /*!< in: buffer containing log data */
+ ulint buf_len, /*!< in: data length in that buffer */
+ ib_uint64_t* scanned_lsn, /*!< in/out: lsn of buffer start,
we return scanned lsn */
ulint* scanned_checkpoint_no,
- /* in/out: 4 lowest bytes of the
+ /*!< in/out: 4 lowest bytes of the
highest scanned checkpoint number so
far */
- ulint* n_bytes_scanned);/* out: how much we were able to
+ ulint* n_bytes_scanned);/*!< out: how much we were able to
scan, smaller than buf_len if log
data ended here */
#endif /* UNIV_HOTBACKUP */
-/***********************************************************************
-Returns TRUE if recovery is currently running. */
+/*******************************************************************//**
+Returns TRUE if recovery is currently running.
+@return recv_recovery_on */
UNIV_INLINE
ibool
recv_recovery_is_on(void);
/*=====================*/
-/***********************************************************************
-Returns TRUE if recovery from backup is currently running. */
+#ifdef UNIV_LOG_ARCHIVE
+/*******************************************************************//**
+Returns TRUE if recovery from backup is currently running.
+@return recv_recovery_from_backup_on */
UNIV_INLINE
ibool
recv_recovery_from_backup_is_on(void);
/*=================================*/
-/****************************************************************************
+#endif /* UNIV_LOG_ARCHIVE */
+/************************************************************************//**
Applies the hashed log records to the page, if the page lsn is less than the
lsn of a log record. This can be called when a buffer page has just been
read in, or also for a page already in the buffer pool. */
UNIV_INTERN
void
-recv_recover_page(
-/*==============*/
- ibool recover_backup,
- /* in: TRUE if we are recovering a backup
- page: then we do not acquire any latches
- since the page was read in outside the
- buffer pool */
+recv_recover_page_func(
+/*===================*/
+#ifndef UNIV_HOTBACKUP
ibool just_read_in,
- /* in: TRUE if the i/o-handler calls this for
- a freshly read page */
- buf_block_t* block); /* in: buffer block */
-/************************************************************
+ /*!< in: TRUE if the i/o handler calls
+ this for a freshly read page */
+#endif /* !UNIV_HOTBACKUP */
+ buf_block_t* block); /*!< in/out: buffer block */
+#ifndef UNIV_HOTBACKUP
+/** Wrapper for recv_recover_page_func().
+Applies the hashed log records to the page, if the page lsn is less than the
+lsn of a log record. This can be called when a buffer page has just been
+read in, or also for a page already in the buffer pool.
+@param jri in: TRUE if just read in (the i/o handler calls this for
+a freshly read page)
+@param block in/out: the buffer block
+*/
+# define recv_recover_page(jri, block) recv_recover_page_func(jri, block)
+#else /* !UNIV_HOTBACKUP */
+/** Wrapper for recv_recover_page_func().
+Applies the hashed log records to the page, if the page lsn is less than the
+lsn of a log record. This can be called when a buffer page has just been
+read in, or also for a page already in the buffer pool.
+@param jri in: TRUE if just read in (the i/o handler calls this for
+a freshly read page)
+@param block in/out: the buffer block
+*/
+# define recv_recover_page(jri, block) recv_recover_page_func(block)
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************//**
Recovers from a checkpoint. When this function returns, the database is able
to start processing of new user transactions, but the function
recv_recovery_from_checkpoint_finish should be called later to complete
-the recovery and free the resources used in it. */
+the recovery and free the resources used in it.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
recv_recovery_from_checkpoint_start_func(
/*=====================================*/
- /* out: error code or DB_SUCCESS */
#ifdef UNIV_LOG_ARCHIVE
- ulint type, /* in: LOG_CHECKPOINT or LOG_ARCHIVE */
- ib_uint64_t limit_lsn, /* in: recover up to this lsn
+ ulint type, /*!< in: LOG_CHECKPOINT or
+ LOG_ARCHIVE */
+ ib_uint64_t limit_lsn, /*!< in: recover up to this lsn
if possible */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t min_flushed_lsn,/* in: min flushed lsn from
+ ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn from
data files */
- ib_uint64_t max_flushed_lsn);/* in: max flushed lsn from
+ ib_uint64_t max_flushed_lsn);/*!< in: max flushed lsn from
data files */
#ifdef UNIV_LOG_ARCHIVE
+/** Wrapper for recv_recovery_from_checkpoint_start_func().
+Recovers from a checkpoint. When this function returns, the database is able
+to start processing of new user transactions, but the function
+recv_recovery_from_checkpoint_finish should be called later to complete
+the recovery and free the resources used in it.
+@param type in: LOG_CHECKPOINT or LOG_ARCHIVE
+@param lim in: recover up to this log sequence number if possible
+@param min in: minimum flushed log sequence number from data files
+@param max in: maximum flushed log sequence number from data files
+@return error code or DB_SUCCESS */
# define recv_recovery_from_checkpoint_start(type,lim,min,max) \
recv_recovery_from_checkpoint_start_func(type,lim,min,max)
#else /* UNIV_LOG_ARCHIVE */
+/** Wrapper for recv_recovery_from_checkpoint_start_func().
+Recovers from a checkpoint. When this function returns, the database is able
+to start processing of new user transactions, but the function
+recv_recovery_from_checkpoint_finish should be called later to complete
+the recovery and free the resources used in it.
+@param type ignored: LOG_CHECKPOINT or LOG_ARCHIVE
+@param lim ignored: recover up to this log sequence number if possible
+@param min in: minimum flushed log sequence number from data files
+@param max in: maximum flushed log sequence number from data files
+@return error code or DB_SUCCESS */
# define recv_recovery_from_checkpoint_start(type,lim,min,max) \
recv_recovery_from_checkpoint_start_func(min,max)
#endif /* UNIV_LOG_ARCHIVE */
-/************************************************************
+/********************************************************//**
Completes recovery from a checkpoint. */
UNIV_INTERN
void
recv_recovery_from_checkpoint_finish(void);
/*======================================*/
-/***********************************************************
-Scans log from a buffer and stores new log data to the parsing buffer. Parses
-and hashes the log records if new data found. */
+/*******************************************************//**
+Scans log from a buffer and stores new log data to the parsing buffer.
+Parses and hashes the log records if new data found. Unless
+UNIV_HOTBACKUP is defined, this function will apply log records
+automatically when the hash table becomes full.
+@return TRUE if limit_lsn has been reached, or not able to scan any
+more in this log group */
UNIV_INTERN
ibool
recv_scan_log_recs(
/*===============*/
- /* out: TRUE if limit_lsn has been
- reached, or not able to scan any more
- in this log group */
- ibool apply_automatically,/* in: TRUE if we want this
- function to apply log records
- automatically when the hash table
- becomes full; in the hot backup tool
- the tool does the applying, not this
- function */
- ulint available_memory,/* in: we let the hash table of recs
+ ulint available_memory,/*!< in: we let the hash table of recs
to grow to this size, at the maximum */
- ibool store_to_hash, /* in: TRUE if the records should be
+ ibool store_to_hash, /*!< in: TRUE if the records should be
stored to the hash table; this is set
to FALSE if just debug checking is
needed */
- byte* buf, /* in: buffer containing a log segment
- or garbage */
- ulint len, /* in: buffer length */
- ib_uint64_t start_lsn, /* in: buffer start lsn */
- ib_uint64_t* contiguous_lsn, /* in/out: it is known that all log
+ const byte* buf, /*!< in: buffer containing a log
+ segment or garbage */
+ ulint len, /*!< in: buffer length */
+ ib_uint64_t start_lsn, /*!< in: buffer start lsn */
+ ib_uint64_t* contiguous_lsn, /*!< in/out: it is known that all log
groups contain contiguous log data up
to this lsn */
- ib_uint64_t* group_scanned_lsn);/* out: scanning succeeded up to
+ ib_uint64_t* group_scanned_lsn);/*!< out: scanning succeeded up to
this lsn */
-/**********************************************************
+/******************************************************//**
Resets the logs. The contents of log files will be lost! */
UNIV_INTERN
void
recv_reset_logs(
/*============*/
- ib_uint64_t lsn, /* in: reset to this lsn
+ ib_uint64_t lsn, /*!< in: reset to this lsn
rounded up to be divisible by
OS_FILE_LOG_BLOCK_SIZE, after
which we add
LOG_BLOCK_HDR_SIZE */
#ifdef UNIV_LOG_ARCHIVE
- ulint arch_log_no, /* in: next archived log file number */
+ ulint arch_log_no, /*!< in: next archived log file number */
#endif /* UNIV_LOG_ARCHIVE */
- ibool new_logs_created);/* in: TRUE if resetting logs
+ ibool new_logs_created);/*!< in: TRUE if resetting logs
is done at the log creation;
FALSE if it is done after
archive recovery */
#ifdef UNIV_HOTBACKUP
-/**********************************************************
+/******************************************************//**
Creates new log files after a backup has been restored. */
UNIV_INTERN
void
recv_reset_log_files_for_backup(
/*============================*/
- const char* log_dir, /* in: log file directory path */
- ulint n_log_files, /* in: number of log files */
- ulint log_file_size, /* in: log file size */
- ib_uint64_t lsn); /* in: new start lsn, must be
+ const char* log_dir, /*!< in: log file directory path */
+ ulint n_log_files, /*!< in: number of log files */
+ ulint log_file_size, /*!< in: log file size */
+ ib_uint64_t lsn); /*!< in: new start lsn, must be
divisible by OS_FILE_LOG_BLOCK_SIZE */
#endif /* UNIV_HOTBACKUP */
-/************************************************************
+/********************************************************//**
Creates the recovery system. */
UNIV_INTERN
void
recv_sys_create(void);
/*=================*/
-/************************************************************
+/**********************************************************//**
+Release recovery system mutexes. */
+UNIV_INTERN
+void
+recv_sys_close(void);
+/*================*/
+/********************************************************//**
+Frees the recovery system memory. */
+UNIV_INTERN
+void
+recv_sys_mem_free(void);
+/*===================*/
+/********************************************************//**
Inits the recovery system for a recovery operation. */
UNIV_INTERN
void
recv_sys_init(
/*==========*/
- ibool recover_from_backup, /* in: TRUE if this is called
- to recover from a hot backup */
- ulint available_memory); /* in: available memory in bytes */
-/***********************************************************************
+ ulint available_memory); /*!< in: available memory in bytes */
+/********************************************************//**
+Reset the state of the recovery system variables. */
+UNIV_INTERN
+void
+recv_sys_var_init(void);
+/*===================*/
+/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
UNIV_INTERN
void
recv_apply_hashed_log_recs(
/*=======================*/
- ibool allow_ibuf); /* in: if TRUE, also ibuf operations are
+ ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are
allowed during the application; if FALSE,
no ibuf operations are allowed, and after
the application all file pages are flushed to
@@ -224,7 +279,7 @@ recv_apply_hashed_log_recs(
alternative means that no new log records
can be generated during the application */
#ifdef UNIV_HOTBACKUP
-/***********************************************************************
+/*******************************************************************//**
Applies log records in the hash table to a backup. */
UNIV_INTERN
void
@@ -232,23 +287,23 @@ recv_apply_log_recs_for_backup(void);
/*================================*/
#endif
#ifdef UNIV_LOG_ARCHIVE
-/************************************************************
-Recovers from archived log files, and also from log files, if they exist. */
+/********************************************************//**
+Recovers from archived log files, and also from log files, if they exist.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
recv_recovery_from_archive_start(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- ib_uint64_t min_flushed_lsn,/* in: min flushed lsn field from the
+ ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn field from the
data files */
- ib_uint64_t limit_lsn, /* in: recover up to this lsn if
+ ib_uint64_t limit_lsn, /*!< in: recover up to this lsn if
possible */
- ulint first_log_no); /* in: number of the first archived
+ ulint first_log_no); /*!< in: number of the first archived
log file to use in the recovery; the
file will be searched from
INNOBASE_LOG_ARCH_DIR specified in
server config file */
-/************************************************************
+/********************************************************//**
Completes recovery from archive. */
UNIV_INTERN
void
@@ -256,133 +311,208 @@ recv_recovery_from_archive_finish(void);
/*===================================*/
#endif /* UNIV_LOG_ARCHIVE */
-/* Block of log record data */
+/** Block of log record data */
typedef struct recv_data_struct recv_data_t;
+/** Block of log record data */
struct recv_data_struct{
- recv_data_t* next; /* pointer to the next block or NULL */
- /* the log record data is stored physically
+ recv_data_t* next; /*!< pointer to the next block or NULL */
+ /*!< the log record data is stored physically
immediately after this struct, max amount
RECV_DATA_BLOCK_SIZE bytes of it */
};
-/* Stored log record struct */
+/** Stored log record struct */
typedef struct recv_struct recv_t;
+/** Stored log record struct */
struct recv_struct{
- byte type; /* log record type */
- ulint len; /* log record body length in bytes */
- recv_data_t* data; /* chain of blocks containing the log record
+ byte type; /*!< log record type */
+ ulint len; /*!< log record body length in bytes */
+ recv_data_t* data; /*!< chain of blocks containing the log record
body */
- ib_uint64_t start_lsn;/* start lsn of the log segment written by
+ ib_uint64_t start_lsn;/*!< start lsn of the log segment written by
the mtr which generated this log record: NOTE
that this is not necessarily the start lsn of
this log record */
- ib_uint64_t end_lsn;/* end lsn of the log segment written by
+ ib_uint64_t end_lsn;/*!< end lsn of the log segment written by
the mtr which generated this log record: NOTE
that this is not necessarily the end lsn of
this log record */
UT_LIST_NODE_T(recv_t)
- rec_list;/* list of log records for this page */
+ rec_list;/*!< list of log records for this page */
+};
+
+/** States of recv_addr_struct */
+enum recv_addr_state {
+ /** not yet processed */
+ RECV_NOT_PROCESSED,
+ /** page is being read */
+ RECV_BEING_READ,
+ /** log records are being applied on the page */
+ RECV_BEING_PROCESSED,
+ /** log records have been applied on the page, or they have
+ been discarded because the tablespace does not exist */
+ RECV_PROCESSED
};
-/* Hashed page file address struct */
+/** Hashed page file address struct */
typedef struct recv_addr_struct recv_addr_t;
+/** Hashed page file address struct */
struct recv_addr_struct{
- ulint state; /* RECV_NOT_PROCESSED, RECV_BEING_PROCESSED,
- or RECV_PROCESSED */
- ulint space; /* space id */
- ulint page_no;/* page number */
+ enum recv_addr_state state;
+ /*!< recovery state of the page */
+ ulint space; /*!< space id */
+ ulint page_no;/*!< page number */
UT_LIST_BASE_NODE_T(recv_t)
- rec_list;/* list of log records for this page */
- hash_node_t addr_hash;
+ rec_list;/*!< list of log records for this page */
+ hash_node_t addr_hash;/*!< hash node in the hash bucket chain */
};
-/* Recovery system data structure */
+/** Recovery system data structure */
typedef struct recv_sys_struct recv_sys_t;
+/** Recovery system data structure */
struct recv_sys_struct{
- mutex_t mutex; /* mutex protecting the fields apply_log_recs,
+#ifndef UNIV_HOTBACKUP
+ mutex_t mutex; /*!< mutex protecting the fields apply_log_recs,
n_addrs, and the state field in each recv_addr
struct */
+#endif /* !UNIV_HOTBACKUP */
ibool apply_log_recs;
- /* this is TRUE when log rec application to
+ /*!< this is TRUE when log rec application to
pages is allowed; this flag tells the
i/o-handler if it should do log record
application */
ibool apply_batch_on;
- /* this is TRUE when a log rec application
+ /*!< this is TRUE when a log rec application
batch is running */
- ib_uint64_t lsn; /* log sequence number */
+ ib_uint64_t lsn; /*!< log sequence number */
ulint last_log_buf_size;
- /* size of the log buffer when the database
+ /*!< size of the log buffer when the database
last time wrote to the log */
byte* last_block;
- /* possible incomplete last recovered log
+ /*!< possible incomplete last recovered log
block */
byte* last_block_buf_start;
- /* the nonaligned start address of the
+ /*!< the nonaligned start address of the
preceding buffer */
- byte* buf; /* buffer for parsing log records */
- ulint len; /* amount of data in buf */
+ byte* buf; /*!< buffer for parsing log records */
+ ulint len; /*!< amount of data in buf */
ib_uint64_t parse_start_lsn;
- /* this is the lsn from which we were able to
+ /*!< this is the lsn from which we were able to
start parsing log records and adding them to
the hash table; zero if a suitable
start point not found yet */
ib_uint64_t scanned_lsn;
- /* the log data has been scanned up to this
+ /*!< the log data has been scanned up to this
lsn */
ulint scanned_checkpoint_no;
- /* the log data has been scanned up to this
+ /*!< the log data has been scanned up to this
checkpoint number (lowest 4 bytes) */
ulint recovered_offset;
- /* start offset of non-parsed log records in
+ /*!< start offset of non-parsed log records in
buf */
ib_uint64_t recovered_lsn;
- /* the log records have been parsed up to
+ /*!< the log records have been parsed up to
this lsn */
- ib_uint64_t limit_lsn;/* recovery should be made at most up to this
- lsn */
+ ib_uint64_t limit_lsn;/*!< recovery should be made at most
+ up to this lsn */
ibool found_corrupt_log;
- /* this is set to TRUE if we during log
+ /*!< this is set to TRUE if we during log
scan find a corrupt log block, or a corrupt
log record, or there is a log parsing
buffer overflow */
#ifdef UNIV_LOG_ARCHIVE
log_group_t* archive_group;
- /* in archive recovery: the log group whose
+ /*!< in archive recovery: the log group whose
archive is read */
#endif /* !UNIV_LOG_ARCHIVE */
- mem_heap_t* heap; /* memory heap of log records and file
+ mem_heap_t* heap; /*!< memory heap of log records and file
addresses*/
- hash_table_t* addr_hash;/* hash table of file addresses of pages */
- ulint n_addrs;/* number of not processed hashed file
+ hash_table_t* addr_hash;/*!< hash table of file addresses of pages */
+ ulint n_addrs;/*!< number of not processed hashed file
addresses in the hash table */
+
+/* If you modified the following defines at original file,
+ You should also modify them. */
+/* defined in os0file.c */
+#define OS_AIO_MERGE_N_CONSECUTIVE 64
+/* defined in log0recv.c */
+#define RECV_READ_AHEAD_AREA 32
+ time_t stats_recv_start_time;
+ ulint stats_recv_turns;
+
+ ulint stats_read_requested_pages;
+ ulint stats_read_in_area[RECV_READ_AHEAD_AREA];
+
+ ulint stats_read_io_pages;
+ ulint stats_read_io_consecutive[OS_AIO_MERGE_N_CONSECUTIVE];
+ ulint stats_write_io_pages;
+ ulint stats_write_io_consecutive[OS_AIO_MERGE_N_CONSECUTIVE];
+
+ ulint stats_doublewrite_check_pages;
+ ulint stats_doublewrite_overwrite_pages;
+
+ ulint stats_recover_pages_with_read;
+ ulint stats_recover_pages_without_read;
+
+ ulint stats_log_recs;
+ ulint stats_log_len_sum;
+
+ ulint stats_applied_log_recs;
+ ulint stats_applied_log_len_sum;
+ ulint stats_pages_already_new;
+
+ ib_uint64_t stats_oldest_modified_lsn;
+ ib_uint64_t stats_newest_modified_lsn;
};
+/** The recovery system */
extern recv_sys_t* recv_sys;
+
+/** TRUE when applying redo log records during crash recovery; FALSE
+otherwise. Note that this is FALSE while a background thread is
+rolling back incomplete transactions. */
extern ibool recv_recovery_on;
+/** If the following is TRUE, the buffer pool file pages must be invalidated
+after recovery and no ibuf operations are allowed; this becomes TRUE if
+the log record hash table becomes too full, and log records must be merged
+to file pages already before the recovery is finished: in this case no
+ibuf operations are allowed, as they could modify the pages read in the
+buffer pool before the pages have been recovered to the up-to-date state.
+
+TRUE means that recovery is running and no operations on the log files
+are allowed yet: the variable name is misleading. */
extern ibool recv_no_ibuf_operations;
+/** TRUE when recv_init_crash_recovery() has been called. */
extern ibool recv_needed_recovery;
+#ifdef UNIV_DEBUG
+/** TRUE if writing to the redo log (mtr_commit) is forbidden.
+Protected by log_sys->mutex. */
+extern ibool recv_no_log_write;
+#endif /* UNIV_DEBUG */
+/** TRUE if buf_page_is_corrupted() should check if the log sequence
+number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
+recv_recovery_from_checkpoint_start_func(). */
extern ibool recv_lsn_checks_on;
#ifdef UNIV_HOTBACKUP
+/** TRUE when the redo log is being backed up */
extern ibool recv_is_making_a_backup;
#endif /* UNIV_HOTBACKUP */
+/** Maximum page number encountered in the redo log */
extern ulint recv_max_parsed_page_no;
-/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
+/** Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
times! */
#define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024)
-/* Size of block reads when the log groups are scanned forward to do a
+/** Size of block reads when the log groups are scanned forward to do a
roll-forward */
#define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE)
-/* States of recv_addr_struct */
-#define RECV_NOT_PROCESSED 71
-#define RECV_BEING_READ 72
-#define RECV_BEING_PROCESSED 73
-#define RECV_PROCESSED 74
-
+/** 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;
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/log0recv.ic b/storage/xtradb/include/log0recv.ic
index e114bede38f..0a8e55b96fa 100644
--- a/storage/xtradb/include/log0recv.ic
+++ b/storage/xtradb/include/log0recv.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/log0recv.ic
Recovery
Created 9/20/1997 Heikki Tuuri
@@ -24,10 +25,9 @@ Created 9/20/1997 Heikki Tuuri
#include "univ.i"
-extern ibool recv_recovery_from_backup_on;
-
-/***********************************************************************
-Returns TRUE if recovery is currently running. */
+/*******************************************************************//**
+Returns TRUE if recovery is currently running.
+@return recv_recovery_on */
UNIV_INLINE
ibool
recv_recovery_is_on(void)
@@ -36,8 +36,13 @@ recv_recovery_is_on(void)
return(UNIV_UNLIKELY(recv_recovery_on));
}
-/***********************************************************************
-Returns TRUE if recovery from backup is currently running. */
+#ifdef UNIV_LOG_ARCHIVE
+/** TRUE when applying redo log records from an archived log file */
+extern ibool recv_recovery_from_backup_on;
+
+/*******************************************************************//**
+Returns TRUE if recovery from backup is currently running.
+@return recv_recovery_from_backup_on */
UNIV_INLINE
ibool
recv_recovery_from_backup_is_on(void)
@@ -45,4 +50,4 @@ recv_recovery_from_backup_is_on(void)
{
return(recv_recovery_from_backup_on);
}
-
+#endif /* UNIV_LOG_ARCHIVE */
diff --git a/storage/xtradb/include/mach0data.h b/storage/xtradb/include/mach0data.h
index 78b48af0836..44ee3df22ce 100644
--- a/storage/xtradb/include/mach0data.h
+++ b/storage/xtradb/include/mach0data.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/mach0data.h
Utilities for converting data from the database file
to the machine format.
@@ -34,363 +35,364 @@ in the same format: ascii, big-endian, ... .
All data in the files MUST be accessed using the functions in this
module. */
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in one byte. */
UNIV_INLINE
void
mach_write_to_1(
/*============*/
- byte* b, /* in: pointer to byte where to store */
- ulint n); /* in: ulint integer to be stored, >= 0, < 256 */
-/************************************************************
-The following function is used to fetch data from one byte. */
+ byte* b, /*!< in: pointer to byte where to store */
+ ulint n); /*!< in: ulint integer to be stored, >= 0, < 256 */
+/********************************************************//**
+The following function is used to fetch data from one byte.
+@return ulint integer, >= 0, < 256 */
UNIV_INLINE
ulint
mach_read_from_1(
/*=============*/
- /* out: ulint integer, >= 0, < 256 */
- const byte* b) /* in: pointer to byte */
+ const byte* b) /*!< in: pointer to byte */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in two consecutive
bytes. We store the most significant byte to the lower address. */
UNIV_INLINE
void
mach_write_to_2(
/*============*/
- byte* b, /* in: pointer to two bytes where to store */
- ulint n); /* in: ulint integer to be stored, >= 0, < 64k */
-/************************************************************
+ byte* b, /*!< in: pointer to two bytes where to store */
+ ulint n); /*!< in: ulint integer to be stored, >= 0, < 64k */
+/********************************************************//**
The following function is used to fetch data from two consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer, >= 0, < 64k */
UNIV_INLINE
ulint
mach_read_from_2(
/*=============*/
- /* out: ulint integer, >= 0, < 64k */
- const byte* b) /* in: pointer to two bytes */
+ const byte* b) /*!< in: pointer to two bytes */
__attribute__((nonnull, pure));
-/************************************************************
+/********************************************************//**
The following function is used to convert a 16-bit data item
to the canonical format, for fast bytewise equality test
-against memory. */
+against memory.
+@return 16-bit integer in canonical format */
UNIV_INLINE
uint16
mach_encode_2(
/*==========*/
- /* out: 16-bit integer in canonical format */
- ulint n) /* in: integer in machine-dependent format */
+ ulint n) /*!< in: integer in machine-dependent format */
__attribute__((const));
-/************************************************************
+/********************************************************//**
The following function is used to convert a 16-bit data item
from the canonical format, for fast bytewise equality test
-against memory. */
+against memory.
+@return integer in machine-dependent format */
UNIV_INLINE
ulint
mach_decode_2(
/*==========*/
- /* out: integer in machine-dependent format */
- uint16 n) /* in: 16-bit integer in canonical format */
+ uint16 n) /*!< in: 16-bit integer in canonical format */
__attribute__((const));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 3 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_3(
/*============*/
- byte* b, /* in: pointer to 3 bytes where to store */
- ulint n); /* in: ulint integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to 3 bytes where to store */
+ ulint n); /*!< in: ulint integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 3 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_3(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to 3 bytes */
+ const byte* b) /*!< in: pointer to 3 bytes */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in four consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_4(
/*============*/
- byte* b, /* in: pointer to four bytes where to store */
- ulint n); /* in: ulint integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to four bytes where to store */
+ ulint n); /*!< in: ulint integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 4 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_4(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to four bytes */
+ const byte* b) /*!< in: pointer to four bytes */
__attribute__((nonnull, pure));
-/*************************************************************
-Writes a ulint in a compressed form (1..5 bytes). */
+/*********************************************************//**
+Writes a ulint in a compressed form (1..5 bytes).
+@return stored size in bytes */
UNIV_INLINE
ulint
mach_write_compressed(
/*==================*/
- /* out: stored size in bytes */
- byte* b, /* in: pointer to memory where to store */
- ulint n); /* in: ulint integer to be stored */
-/*************************************************************
-Returns the size of an ulint when written in the compressed form. */
+ byte* b, /*!< in: pointer to memory where to store */
+ ulint n); /*!< in: ulint integer to be stored */
+/*********************************************************//**
+Returns the size of an ulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_get_compressed_size(
/*=====================*/
- /* out: compressed size in bytes */
- ulint n) /* in: ulint integer to be stored */
+ ulint n) /*!< in: ulint integer to be stored */
__attribute__((const));
-/*************************************************************
-Reads a ulint in a compressed form. */
+/*********************************************************//**
+Reads a ulint in a compressed form.
+@return read integer */
UNIV_INLINE
ulint
mach_read_compressed(
/*=================*/
- /* out: read integer */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 6 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_6(
/*============*/
- byte* b, /* in: pointer to 6 bytes where to store */
- dulint n); /* in: dulint integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to 6 bytes where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 6 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_6(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 6 bytes */
+ const byte* b) /*!< in: pointer to 6 bytes */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 7 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_7(
/*============*/
- byte* b, /* in: pointer to 7 bytes where to store */
- dulint n); /* in: dulint integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to 7 bytes where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 7 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_7(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 7 bytes */
+ const byte* b) /*!< in: pointer to 7 bytes */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_8(
/*============*/
- byte* b, /* in: pointer to 8 bytes where to store */
- dulint n); /* in: dulint integer to be stored */
-/***********************************************************
+ byte* b, /*!< in: pointer to 8 bytes where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_ull(
/*===========*/
- byte* b, /* in: pointer to 8 bytes where to store */
- ib_uint64_t n); /* in: 64-bit integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to 8 bytes where to store */
+ ib_uint64_t n); /*!< in: 64-bit integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 8 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_8(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 8 bytes */
+ const byte* b) /*!< in: pointer to 8 bytes */
__attribute__((nonnull, pure));
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 8 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return 64-bit integer */
UNIV_INLINE
ib_uint64_t
mach_read_ull(
/*==========*/
- /* out: 64-bit integer */
- const byte* b) /* in: pointer to 8 bytes */
+ const byte* b) /*!< in: pointer to 8 bytes */
__attribute__((nonnull, pure));
-/*************************************************************
-Writes a dulint in a compressed form (5..9 bytes). */
+/*********************************************************//**
+Writes a dulint in a compressed form (5..9 bytes).
+@return size in bytes */
UNIV_INLINE
ulint
mach_dulint_write_compressed(
/*=========================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n); /* in: dulint integer to be stored */
-/*************************************************************
-Returns the size of a dulint when written in the compressed form. */
+ byte* b, /*!< in: pointer to memory where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/*********************************************************//**
+Returns the size of a dulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_dulint_get_compressed_size(
/*============================*/
- /* out: compressed size in bytes */
- dulint n); /* in: dulint integer to be stored */
-/*************************************************************
-Reads a dulint in a compressed form. */
+ dulint n); /*!< in: dulint integer to be stored */
+/*********************************************************//**
+Reads a dulint in a compressed form.
+@return read dulint */
UNIV_INLINE
dulint
mach_dulint_read_compressed(
/*========================*/
- /* out: read dulint */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
-Writes a dulint in a compressed form (1..11 bytes). */
+/*********************************************************//**
+Writes a dulint in a compressed form (1..11 bytes).
+@return size in bytes */
UNIV_INLINE
ulint
mach_dulint_write_much_compressed(
/*==============================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n); /* in: dulint integer to be stored */
-/*************************************************************
-Returns the size of a dulint when written in the compressed form. */
+ byte* b, /*!< in: pointer to memory where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/*********************************************************//**
+Returns the size of a dulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_dulint_get_much_compressed_size(
/*=================================*/
- /* out: compressed size in bytes */
- dulint n) /* in: dulint integer to be stored */
+ dulint n) /*!< in: dulint integer to be stored */
__attribute__((const));
-/*************************************************************
-Reads a dulint in a compressed form. */
+/*********************************************************//**
+Reads a dulint in a compressed form.
+@return read dulint */
UNIV_INLINE
dulint
mach_dulint_read_much_compressed(
/*=============================*/
- /* out: read dulint */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
-Reads a ulint in a compressed form if the log record fully contains it. */
+/*********************************************************//**
+Reads a ulint in a compressed form if the log record fully contains it.
+@return pointer to end of the stored field, NULL if not complete */
UNIV_INTERN
byte*
mach_parse_compressed(
/*==================*/
- /* out: pointer to end of the stored field, NULL if
- not complete */
- byte* ptr, /* in: pointer to buffer from where to read */
- byte* end_ptr,/* in: pointer to end of the buffer */
- ulint* val); /* out: read value */
-/*************************************************************
-Reads a dulint in a compressed form if the log record fully contains it. */
+ byte* ptr, /*!< in: pointer to buffer from where to read */
+ byte* end_ptr,/*!< in: pointer to end of the buffer */
+ ulint* val); /*!< out: read value */
+/*********************************************************//**
+Reads a dulint in a compressed form if the log record fully contains it.
+@return pointer to end of the stored field, NULL if not complete */
UNIV_INTERN
byte*
mach_dulint_parse_compressed(
/*=========================*/
- /* out: pointer to end of the stored field, NULL if
- not complete */
- byte* ptr, /* in: pointer to buffer from where to read */
- byte* end_ptr,/* in: pointer to end of the buffer */
- dulint* val); /* out: read value */
-/*************************************************************
-Reads a double. It is stored in a little-endian format. */
+ byte* ptr, /*!< in: pointer to buffer from where to read */
+ byte* end_ptr,/*!< in: pointer to end of the buffer */
+ dulint* val); /*!< out: read value */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************//**
+Reads a double. It is stored in a little-endian format.
+@return double read */
UNIV_INLINE
double
mach_double_read(
/*=============*/
- /* out: double read */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
+/*********************************************************//**
Writes a double. It is stored in a little-endian format. */
UNIV_INLINE
void
mach_double_write(
/*==============*/
- byte* b, /* in: pointer to memory where to write */
- double d); /* in: double */
-/*************************************************************
-Reads a float. It is stored in a little-endian format. */
+ byte* b, /*!< in: pointer to memory where to write */
+ double d); /*!< in: double */
+/*********************************************************//**
+Reads a float. It is stored in a little-endian format.
+@return float read */
UNIV_INLINE
float
mach_float_read(
/*============*/
- /* out: float read */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
+/*********************************************************//**
Writes a float. It is stored in a little-endian format. */
UNIV_INLINE
void
mach_float_write(
/*=============*/
- byte* b, /* in: pointer to memory where to write */
- float d); /* in: float */
-/*************************************************************
-Reads a ulint stored in the little-endian format. */
+ byte* b, /*!< in: pointer to memory where to write */
+ float d); /*!< in: float */
+/*********************************************************//**
+Reads a ulint stored in the little-endian format.
+@return unsigned long int */
UNIV_INLINE
ulint
mach_read_from_n_little_endian(
/*===========================*/
- /* out: unsigned long int */
- const byte* buf, /* in: from where to read */
- ulint buf_size) /* in: from how many bytes to read */
+ const byte* buf, /*!< in: from where to read */
+ ulint buf_size) /*!< in: from how many bytes to read */
__attribute__((nonnull, pure));
-/*************************************************************
+/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
void
mach_write_to_n_little_endian(
/*==========================*/
- byte* dest, /* in: where to write */
- ulint dest_size, /* in: into how many bytes to write */
- ulint n); /* in: unsigned long int to write */
-/*************************************************************
-Reads a ulint stored in the little-endian format. */
+ byte* dest, /*!< in: where to write */
+ ulint dest_size, /*!< in: into how many bytes to write */
+ ulint n); /*!< in: unsigned long int to write */
+/*********************************************************//**
+Reads a ulint stored in the little-endian format.
+@return unsigned long int */
UNIV_INLINE
ulint
mach_read_from_2_little_endian(
/*===========================*/
- /* out: unsigned long int */
- const byte* buf) /* in: from where to read */
+ const byte* buf) /*!< in: from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
+/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
void
mach_write_to_2_little_endian(
/*==========================*/
- byte* dest, /* in: where to write */
- ulint n); /* in: unsigned long int to write */
+ byte* dest, /*!< in: where to write */
+ ulint n); /*!< in: unsigned long int to write */
-/*************************************************************
+/*********************************************************//**
Convert integral type from storage byte order (big endian) to
-host byte order. */
+host byte order.
+@return integer value */
UNIV_INLINE
ullint
mach_read_int_type(
/*===============*/
- /* out: integer value */
- const byte* src, /* in: where to read from */
- ulint len, /* in: length of src */
- ibool unsigned_type); /* in: signed or unsigned flag */
+ const byte* src, /*!< in: where to read from */
+ ulint len, /*!< in: length of src */
+ ibool unsigned_type); /*!< in: signed or unsigned flag */
+#endif /* !UNIV_HOTBACKUP */
+
#ifndef UNIV_NONINL
#include "mach0data.ic"
#endif
diff --git a/storage/xtradb/include/mach0data.ic b/storage/xtradb/include/mach0data.ic
index 5dda9aece2f..ef20356bd31 100644
--- a/storage/xtradb/include/mach0data.ic
+++ b/storage/xtradb/include/mach0data.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/mach0data.ic
Utilities for converting data from the database file
to the machine format.
@@ -25,14 +26,14 @@ Created 11/28/1995 Heikki Tuuri
#include "ut0mem.h"
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in one byte. */
UNIV_INLINE
void
mach_write_to_1(
/*============*/
- byte* b, /* in: pointer to byte where to store */
- ulint n) /* in: ulint integer to be stored, >= 0, < 256 */
+ byte* b, /*!< in: pointer to byte where to store */
+ ulint n) /*!< in: ulint integer to be stored, >= 0, < 256 */
{
ut_ad(b);
ut_ad(n <= 0xFFUL);
@@ -40,28 +41,28 @@ mach_write_to_1(
b[0] = (byte)n;
}
-/************************************************************
-The following function is used to fetch data from one byte. */
+/********************************************************//**
+The following function is used to fetch data from one byte.
+@return ulint integer, >= 0, < 256 */
UNIV_INLINE
ulint
mach_read_from_1(
/*=============*/
- /* out: ulint integer, >= 0, < 256 */
- const byte* b) /* in: pointer to byte */
+ const byte* b) /*!< in: pointer to byte */
{
ut_ad(b);
return((ulint)(b[0]));
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in two consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_2(
/*============*/
- byte* b, /* in: pointer to two bytes where to store */
- ulint n) /* in: ulint integer to be stored */
+ byte* b, /*!< in: pointer to two bytes where to store */
+ ulint n) /*!< in: ulint integer to be stored */
{
ut_ad(b);
ut_ad(n <= 0xFFFFUL);
@@ -70,15 +71,15 @@ mach_write_to_2(
b[1] = (byte)(n);
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 2 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_2(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to 2 bytes */
+ const byte* b) /*!< in: pointer to 2 bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 8)
@@ -86,46 +87,46 @@ mach_read_from_2(
);
}
-/************************************************************
+/********************************************************//**
The following function is used to convert a 16-bit data item
to the canonical format, for fast bytewise equality test
-against memory. */
+against memory.
+@return 16-bit integer in canonical format */
UNIV_INLINE
uint16
mach_encode_2(
/*==========*/
- /* out: 16-bit integer in canonical format */
- ulint n) /* in: integer in machine-dependent format */
+ ulint n) /*!< in: integer in machine-dependent format */
{
uint16 ret;
ut_ad(2 == sizeof ret);
mach_write_to_2((byte*) &ret, n);
return(ret);
}
-/************************************************************
+/********************************************************//**
The following function is used to convert a 16-bit data item
from the canonical format, for fast bytewise equality test
-against memory. */
+against memory.
+@return integer in machine-dependent format */
UNIV_INLINE
ulint
mach_decode_2(
/*==========*/
- /* out: integer in machine-dependent format */
- uint16 n) /* in: 16-bit integer in canonical format */
+ uint16 n) /*!< in: 16-bit integer in canonical format */
{
ut_ad(2 == sizeof n);
return(mach_read_from_2((const byte*) &n));
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 3 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_3(
/*============*/
- byte* b, /* in: pointer to 3 bytes where to store */
- ulint n) /* in: ulint integer to be stored */
+ byte* b, /*!< in: pointer to 3 bytes where to store */
+ ulint n) /*!< in: ulint integer to be stored */
{
ut_ad(b);
ut_ad(n <= 0xFFFFFFUL);
@@ -135,15 +136,15 @@ mach_write_to_3(
b[2] = (byte)(n);
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 3 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_3(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to 3 bytes */
+ const byte* b) /*!< in: pointer to 3 bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 16)
@@ -152,15 +153,15 @@ mach_read_from_3(
);
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in four consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_4(
/*============*/
- byte* b, /* in: pointer to four bytes where to store */
- ulint n) /* in: ulint integer to be stored */
+ byte* b, /*!< in: pointer to four bytes where to store */
+ ulint n) /*!< in: ulint integer to be stored */
{
ut_ad(b);
@@ -170,15 +171,15 @@ mach_write_to_4(
b[3] = (byte)n;
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 4 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_4(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to four bytes */
+ const byte* b) /*!< in: pointer to four bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 24)
@@ -188,20 +189,20 @@ mach_read_from_4(
);
}
-/*************************************************************
+/*********************************************************//**
Writes a ulint in a compressed form where the first byte codes the
length of the stored ulint. We look at the most significant bits of
the byte. If the most significant bit is zero, it means 1-byte storage,
else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,
it means 3-byte storage, else if 4th is 0, it means 4-byte storage,
-else the storage is 5-byte. */
+else the storage is 5-byte.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_write_compressed(
/*==================*/
- /* out: compressed size in bytes */
- byte* b, /* in: pointer to memory where to store */
- ulint n) /* in: ulint integer (< 2^32) to be stored */
+ byte* b, /*!< in: pointer to memory where to store */
+ ulint n) /*!< in: ulint integer (< 2^32) to be stored */
{
ut_ad(b);
@@ -224,14 +225,14 @@ mach_write_compressed(
}
}
-/*************************************************************
-Returns the size of a ulint when written in the compressed form. */
+/*********************************************************//**
+Returns the size of a ulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_get_compressed_size(
/*=====================*/
- /* out: compressed size in bytes */
- ulint n) /* in: ulint integer (< 2^32) to be stored */
+ ulint n) /*!< in: ulint integer (< 2^32) to be stored */
{
if (n < 0x80UL) {
return(1);
@@ -246,14 +247,14 @@ mach_get_compressed_size(
}
}
-/*************************************************************
-Reads a ulint in a compressed form. */
+/*********************************************************//**
+Reads a ulint in a compressed form.
+@return read integer (< 2^32) */
UNIV_INLINE
ulint
mach_read_compressed(
/*=================*/
- /* out: read integer (< 2^32) */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
ulint flag;
@@ -275,15 +276,15 @@ mach_read_compressed(
}
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_8(
/*============*/
- byte* b, /* in: pointer to 8 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to 8 bytes where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ut_ad(b);
@@ -291,15 +292,15 @@ mach_write_to_8(
mach_write_to_4(b + 4, ut_dulint_get_low(n));
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_ull(
/*===========*/
- byte* b, /* in: pointer to 8 bytes where to store */
- ib_uint64_t n) /* in: 64-bit integer to be stored */
+ byte* b, /*!< in: pointer to 8 bytes where to store */
+ ib_uint64_t n) /*!< in: 64-bit integer to be stored */
{
ut_ad(b);
@@ -307,15 +308,15 @@ mach_write_ull(
mach_write_to_4(b + 4, (ulint) n);
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 8 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_8(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 8 bytes */
+ const byte* b) /*!< in: pointer to 8 bytes */
{
ulint high;
ulint low;
@@ -328,15 +329,15 @@ mach_read_from_8(
return(ut_dulint_create(high, low));
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 8 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return 64-bit integer */
UNIV_INLINE
ib_uint64_t
mach_read_ull(
/*==========*/
- /* out: 64-bit integer */
- const byte* b) /* in: pointer to 8 bytes */
+ const byte* b) /*!< in: pointer to 8 bytes */
{
ib_uint64_t ull;
@@ -346,15 +347,15 @@ mach_read_ull(
return(ull);
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 7 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_7(
/*============*/
- byte* b, /* in: pointer to 7 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to 7 bytes where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ut_ad(b);
@@ -362,15 +363,15 @@ mach_write_to_7(
mach_write_to_4(b + 3, ut_dulint_get_low(n));
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 7 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_7(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 7 bytes */
+ const byte* b) /*!< in: pointer to 7 bytes */
{
ulint high;
ulint low;
@@ -383,15 +384,15 @@ mach_read_from_7(
return(ut_dulint_create(high, low));
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 6 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_6(
/*============*/
- byte* b, /* in: pointer to 6 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to 6 bytes where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ut_ad(b);
@@ -399,15 +400,15 @@ mach_write_to_6(
mach_write_to_4(b + 2, ut_dulint_get_low(n));
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 6 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_6(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 6 bytes */
+ const byte* b) /*!< in: pointer to 6 bytes */
{
ulint high;
ulint low;
@@ -420,15 +421,15 @@ mach_read_from_6(
return(ut_dulint_create(high, low));
}
-/*************************************************************
-Writes a dulint in a compressed form (5..9 bytes). */
+/*********************************************************//**
+Writes a dulint in a compressed form (5..9 bytes).
+@return size in bytes */
UNIV_INLINE
ulint
mach_dulint_write_compressed(
/*=========================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to memory where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ulint size;
@@ -440,26 +441,26 @@ mach_dulint_write_compressed(
return(size + 4);
}
-/*************************************************************
-Returns the size of a dulint when written in the compressed form. */
+/*********************************************************//**
+Returns the size of a dulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_dulint_get_compressed_size(
/*============================*/
- /* out: compressed size in bytes */
- dulint n) /* in: dulint integer to be stored */
+ dulint n) /*!< in: dulint integer to be stored */
{
return(4 + mach_get_compressed_size(ut_dulint_get_high(n)));
}
-/*************************************************************
-Reads a dulint in a compressed form. */
+/*********************************************************//**
+Reads a dulint in a compressed form.
+@return read dulint */
UNIV_INLINE
dulint
mach_dulint_read_compressed(
/*========================*/
- /* out: read dulint */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
ulint high;
ulint low;
@@ -476,15 +477,15 @@ mach_dulint_read_compressed(
return(ut_dulint_create(high, low));
}
-/*************************************************************
-Writes a dulint in a compressed form (1..11 bytes). */
+/*********************************************************//**
+Writes a dulint in a compressed form (1..11 bytes).
+@return size in bytes */
UNIV_INLINE
ulint
mach_dulint_write_much_compressed(
/*==============================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to memory where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ulint size;
@@ -502,14 +503,14 @@ mach_dulint_write_much_compressed(
return(size);
}
-/*************************************************************
-Returns the size of a dulint when written in the compressed form. */
+/*********************************************************//**
+Returns the size of a dulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_dulint_get_much_compressed_size(
/*=================================*/
- /* out: compressed size in bytes */
- dulint n) /* in: dulint integer to be stored */
+ dulint n) /*!< in: dulint integer to be stored */
{
if (0 == ut_dulint_get_high(n)) {
return(mach_get_compressed_size(ut_dulint_get_low(n)));
@@ -519,14 +520,14 @@ mach_dulint_get_much_compressed_size(
+ mach_get_compressed_size(ut_dulint_get_low(n)));
}
-/*************************************************************
-Reads a dulint in a compressed form. */
+/*********************************************************//**
+Reads a dulint in a compressed form.
+@return read dulint */
UNIV_INLINE
dulint
mach_dulint_read_much_compressed(
/*=============================*/
- /* out: read dulint */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
ulint high;
ulint low;
@@ -547,15 +548,15 @@ mach_dulint_read_much_compressed(
return(ut_dulint_create(high, low));
}
-
-/*************************************************************
-Reads a double. It is stored in a little-endian format. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************//**
+Reads a double. It is stored in a little-endian format.
+@return double read */
UNIV_INLINE
double
mach_double_read(
/*=============*/
- /* out: double read */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
double d;
ulint i;
@@ -574,14 +575,14 @@ mach_double_read(
return(d);
}
-/*************************************************************
+/*********************************************************//**
Writes a double. It is stored in a little-endian format. */
UNIV_INLINE
void
mach_double_write(
/*==============*/
- byte* b, /* in: pointer to memory where to write */
- double d) /* in: double */
+ byte* b, /*!< in: pointer to memory where to write */
+ double d) /*!< in: double */
{
ulint i;
byte* ptr;
@@ -597,14 +598,14 @@ mach_double_write(
}
}
-/*************************************************************
-Reads a float. It is stored in a little-endian format. */
+/*********************************************************//**
+Reads a float. It is stored in a little-endian format.
+@return float read */
UNIV_INLINE
float
mach_float_read(
/*============*/
- /* out: float read */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
float d;
ulint i;
@@ -623,14 +624,14 @@ mach_float_read(
return(d);
}
-/*************************************************************
+/*********************************************************//**
Writes a float. It is stored in a little-endian format. */
UNIV_INLINE
void
mach_float_write(
/*=============*/
- byte* b, /* in: pointer to memory where to write */
- float d) /* in: float */
+ byte* b, /*!< in: pointer to memory where to write */
+ float d) /*!< in: float */
{
ulint i;
byte* ptr;
@@ -646,15 +647,15 @@ mach_float_write(
}
}
-/*************************************************************
-Reads a ulint stored in the little-endian format. */
+/*********************************************************//**
+Reads a ulint stored in the little-endian format.
+@return unsigned long int */
UNIV_INLINE
ulint
mach_read_from_n_little_endian(
/*===========================*/
- /* out: unsigned long int */
- const byte* buf, /* in: from where to read */
- ulint buf_size) /* in: from how many bytes to read */
+ const byte* buf, /*!< in: from where to read */
+ ulint buf_size) /*!< in: from how many bytes to read */
{
ulint n = 0;
const byte* ptr;
@@ -679,15 +680,15 @@ mach_read_from_n_little_endian(
return(n);
}
-/*************************************************************
+/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
void
mach_write_to_n_little_endian(
/*==========================*/
- byte* dest, /* in: where to write */
- ulint dest_size, /* in: into how many bytes to write */
- ulint n) /* in: unsigned long int to write */
+ byte* dest, /*!< in: where to write */
+ ulint dest_size, /*!< in: into how many bytes to write */
+ ulint n) /*!< in: unsigned long int to write */
{
byte* end;
@@ -711,26 +712,26 @@ mach_write_to_n_little_endian(
ut_ad(n == 0);
}
-/*************************************************************
-Reads a ulint stored in the little-endian format. */
+/*********************************************************//**
+Reads a ulint stored in the little-endian format.
+@return unsigned long int */
UNIV_INLINE
ulint
mach_read_from_2_little_endian(
/*===========================*/
- /* out: unsigned long int */
- const byte* buf) /* in: from where to read */
+ const byte* buf) /*!< in: from where to read */
{
return((ulint)(*buf) + ((ulint)(*(buf + 1))) * 256);
}
-/*************************************************************
+/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
void
mach_write_to_2_little_endian(
/*==========================*/
- byte* dest, /* in: where to write */
- ulint n) /* in: unsigned long int to write */
+ byte* dest, /*!< in: where to write */
+ ulint n) /*!< in: unsigned long int to write */
{
ut_ad(n < 256 * 256);
@@ -742,17 +743,17 @@ mach_write_to_2_little_endian(
*dest = (byte)(n & 0xFFUL);
}
-/*************************************************************
+/*********************************************************//**
Convert integral type from storage byte order (big endian) to
-host byte order. */
+host byte order.
+@return integer value */
UNIV_INLINE
ullint
mach_read_int_type(
/*===============*/
- /* out: integer value */
- const byte* src, /* in: where to read from */
- ulint len, /* in: length of src */
- ibool unsigned_type) /* in: signed or unsigned flag */
+ const byte* src, /*!< in: where to read from */
+ ulint len, /*!< in: length of src */
+ ibool unsigned_type) /*!< in: signed or unsigned flag */
{
/* XXX this can be optimized on big-endian machines */
@@ -782,3 +783,4 @@ mach_read_int_type(
return(ret);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/mem0dbg.h b/storage/xtradb/include/mem0dbg.h
index 0568a595d06..a064af5c678 100644
--- a/storage/xtradb/include/mem0dbg.h
+++ b/storage/xtradb/include/mem0dbg.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mem0dbg.h
The memory management: the debug code. This is not a compilation module,
but is included in mem0mem.* !
@@ -47,7 +48,7 @@ check fields at the both ends of the field. */
#endif
#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
-/*******************************************************************
+/***************************************************************//**
Checks a memory heap for consistency and prints the contents if requested.
Outputs the sum of sizes of buffers given to the user (only in
the debug version), the physical size of the heap and the number of
@@ -57,83 +58,83 @@ UNIV_INTERN
void
mem_heap_validate_or_print(
/*=======================*/
- mem_heap_t* heap, /* in: memory heap */
- byte* top, /* in: calculate and validate only until
+ mem_heap_t* heap, /*!< in: memory heap */
+ byte* top, /*!< in: calculate and validate only until
this top pointer in the heap is reached,
if this pointer is NULL, ignored */
- ibool print, /* in: if TRUE, prints the contents
+ ibool print, /*!< in: if TRUE, prints the contents
of the heap; works only in
the debug version */
- ibool* error, /* out: TRUE if error */
- ulint* us_size,/* out: allocated memory
+ ibool* error, /*!< out: TRUE if error */
+ ulint* us_size,/*!< out: allocated memory
(for the user) in the heap,
if a NULL pointer is passed as this
argument, it is ignored; in the
non-debug version this is always -1 */
- ulint* ph_size,/* out: physical size of the heap,
+ ulint* ph_size,/*!< out: physical size of the heap,
if a NULL pointer is passed as this
argument, it is ignored */
- ulint* n_blocks); /* out: number of blocks in the heap,
+ ulint* n_blocks); /*!< out: number of blocks in the heap,
if a NULL pointer is passed as this
argument, it is ignored */
-/******************************************************************
-Validates the contents of a memory heap. */
+/**************************************************************//**
+Validates the contents of a memory heap.
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_heap_validate(
/*==============*/
- /* out: TRUE if ok */
- mem_heap_t* heap); /* in: memory heap */
+ mem_heap_t* heap); /*!< in: memory heap */
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG
-/******************************************************************
-Checks that an object is a memory heap (or a block of it) */
+/**************************************************************//**
+Checks that an object is a memory heap (or a block of it)
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_heap_check(
/*===========*/
- /* out: TRUE if ok */
- mem_heap_t* heap); /* in: memory heap */
+ mem_heap_t* heap); /*!< in: memory heap */
#endif /* UNIV_DEBUG */
#ifdef UNIV_MEM_DEBUG
-/*********************************************************************
-TRUE if no memory is currently allocated. */
+/*****************************************************************//**
+TRUE if no memory is currently allocated.
+@return TRUE if no heaps exist */
UNIV_INTERN
ibool
mem_all_freed(void);
/*===============*/
- /* out: TRUE if no heaps exist */
-/*********************************************************************
-Validates the dynamic memory */
+/*****************************************************************//**
+Validates the dynamic memory
+@return TRUE if error */
UNIV_INTERN
ibool
mem_validate_no_assert(void);
/*=========================*/
- /* out: TRUE if error */
-/****************************************************************
-Validates the dynamic memory */
+/************************************************************//**
+Validates the dynamic memory
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_validate(void);
/*===============*/
- /* out: TRUE if ok */
#endif /* UNIV_MEM_DEBUG */
-/****************************************************************
+/************************************************************//**
Tries to find neigboring memory allocation blocks and dumps to stderr
the neighborhood of a given pointer. */
UNIV_INTERN
void
mem_analyze_corruption(
/*===================*/
- void* ptr); /* in: pointer to place of possible corruption */
-/*********************************************************************
+ void* ptr); /*!< in: pointer to place of possible corruption */
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated memory
heaps or buffers. Can only be used in the debug version. */
UNIV_INTERN
void
mem_print_info(void);
/*================*/
-/*********************************************************************
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated memory
heaps or buffers since the last ..._print_info or..._print_new_info. */
UNIV_INTERN
diff --git a/storage/xtradb/include/mem0dbg.ic b/storage/xtradb/include/mem0dbg.ic
index bf695fee785..cb9245411dc 100644
--- a/storage/xtradb/include/mem0dbg.ic
+++ b/storage/xtradb/include/mem0dbg.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/mem0dbg.ic
The memory management: the debug code. This is not an independent
compilation module but is included in mem0mem.*.
@@ -24,44 +25,46 @@ Created 6/8/1994 Heikki Tuuri
*************************************************************************/
#ifdef UNIV_MEM_DEBUG
+# ifndef UNIV_HOTBACKUP
extern mutex_t mem_hash_mutex;
+# endif /* !UNIV_HOTBACKUP */
extern ulint mem_current_allocated_memory;
-/**********************************************************************
+/******************************************************************//**
Initializes an allocated memory field in the debug version. */
UNIV_INTERN
void
mem_field_init(
/*===========*/
- byte* buf, /* in: memory field */
- ulint n); /* in: how many bytes the user requested */
-/**********************************************************************
+ byte* buf, /*!< in: memory field */
+ ulint n); /*!< in: how many bytes the user requested */
+/******************************************************************//**
Erases an allocated memory field in the debug version. */
UNIV_INTERN
void
mem_field_erase(
/*============*/
- byte* buf, /* in: memory field */
- ulint n); /* in: how many bytes the user requested */
-/*******************************************************************
+ byte* buf, /*!< in: memory field */
+ ulint n); /*!< in: how many bytes the user requested */
+/***************************************************************//**
Initializes a buffer to a random combination of hex BA and BE.
Used to initialize allocated memory. */
UNIV_INTERN
void
mem_init_buf(
/*=========*/
- byte* buf, /* in: pointer to buffer */
- ulint n); /* in: length of buffer */
-/*******************************************************************
+ byte* buf, /*!< in: pointer to buffer */
+ ulint n); /*!< in: length of buffer */
+/***************************************************************//**
Initializes a buffer to a random combination of hex DE and AD.
-Used to erase freed memory.*/
+Used to erase freed memory. */
UNIV_INTERN
void
mem_erase_buf(
/*==========*/
- byte* buf, /* in: pointer to buffer */
- ulint n); /* in: length of buffer */
-/*******************************************************************
+ byte* buf, /*!< in: pointer to buffer */
+ ulint n); /*!< in: length of buffer */
+/***************************************************************//**
Inserts a created memory heap to the hash table of
current allocated memory heaps.
Initializes the hash table when first called. */
@@ -69,10 +72,10 @@ UNIV_INTERN
void
mem_hash_insert(
/*============*/
- mem_heap_t* heap, /* in: the created heap */
- const char* file_name, /* in: file name of creation */
- ulint line); /* in: line where created */
-/*******************************************************************
+ mem_heap_t* heap, /*!< in: the created heap */
+ const char* file_name, /*!< in: file name of creation */
+ ulint line); /*!< in: line where created */
+/***************************************************************//**
Removes a memory heap (which is going to be freed by the caller)
from the list of live memory heaps. Returns the size of the heap
in terms of how much memory in bytes was allocated for the user of
@@ -84,9 +87,9 @@ UNIV_INTERN
void
mem_hash_remove(
/*============*/
- mem_heap_t* heap, /* in: the heap to be freed */
- const char* file_name, /* in: file name of freeing */
- ulint line); /* in: line where freed */
+ mem_heap_t* heap, /*!< in: the heap to be freed */
+ const char* file_name, /*!< in: file name of freeing */
+ ulint line); /*!< in: line where freed */
void
diff --git a/storage/xtradb/include/mem0mem.h b/storage/xtradb/include/mem0mem.h
index c20e7815001..98f8748e529 100644
--- a/storage/xtradb/include/mem0mem.h
+++ b/storage/xtradb/include/mem0mem.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mem0mem.h
The memory management
Created 6/9/1994 Heikki Tuuri
@@ -28,9 +29,10 @@ Created 6/9/1994 Heikki Tuuri
#include "univ.i"
#include "ut0mem.h"
#include "ut0byte.h"
-#include "ut0ut.h"
#include "ut0rnd.h"
-#include "sync0sync.h"
+#ifndef UNIV_HOTBACKUP
+# include "sync0sync.h"
+#endif /* UNIV_HOTBACKUP */
#include "ut0lst.h"
#include "mach0data.h"
@@ -73,26 +75,33 @@ allocations of small buffers. */
is the maximum size for a single allocated buffer: */
#define MEM_MAX_ALLOC_IN_BUF (UNIV_PAGE_SIZE - 200)
-/**********************************************************************
+/******************************************************************//**
Initializes the memory system. */
UNIV_INTERN
void
mem_init(
/*=====*/
- ulint size); /* in: common pool size in bytes */
-/******************************************************************
+ ulint size); /*!< in: common pool size in bytes */
+/******************************************************************//**
+Closes the memory system. */
+UNIV_INTERN
+void
+mem_close(void);
+/*===========*/
+
+/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
#define mem_heap_create(N) mem_heap_create_func(\
(N), MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
#define mem_heap_create_in_buffer(N) mem_heap_create_func(\
(N), MEM_HEAP_BUFFER, __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
@@ -100,31 +109,30 @@ heap creation. */
(N), MEM_HEAP_BTR_SEARCH | MEM_HEAP_BUFFER,\
__FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap freeing. */
#define mem_heap_free(heap) mem_heap_free_func(\
(heap), __FILE__, __LINE__)
-/*********************************************************************
+/*****************************************************************//**
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap. For debugging purposes, takes also the file name and line as
-arguments. */
+arguments.
+@return own: memory heap, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
mem_heap_t*
mem_heap_create_func(
/*=================*/
- /* out, own: memory heap, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- ulint n, /* in: desired start block size,
+ ulint n, /*!< in: desired start block size,
this means that a single user buffer
of size n will fit in the block,
0 creates a default size block */
- ulint type, /* in: heap type */
- const char* file_name, /* in: file name where created */
- ulint line); /* in: line where created */
-/*********************************************************************
+ ulint type, /*!< in: heap type */
+ const char* file_name, /*!< in: file name where created */
+ ulint line); /*!< in: line where created */
+/*****************************************************************//**
NOTE: Use the corresponding macro instead of this function. Frees the space
occupied by a memory heap. In the debug version erases the heap memory
blocks. */
@@ -132,42 +140,41 @@ UNIV_INLINE
void
mem_heap_free_func(
/*===============*/
- mem_heap_t* heap, /* in, own: heap to be freed */
- const char* file_name, /* in: file name where freed */
- ulint line); /* in: line where freed */
-/*******************************************************************
-Allocates and zero-fills n bytes of memory from a memory heap. */
+ mem_heap_t* heap, /*!< in, own: heap to be freed */
+ const char* file_name, /*!< in: file name where freed */
+ ulint line); /*!< in: line where freed */
+/***************************************************************//**
+Allocates and zero-fills n bytes of memory from a memory heap.
+@return allocated, zero-filled storage */
UNIV_INLINE
void*
mem_heap_zalloc(
/*============*/
- /* out: allocated, zero-filled storage */
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: number of bytes; if the heap is allowed
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */
-/*******************************************************************
-Allocates n bytes of memory from a memory heap. */
+/***************************************************************//**
+Allocates n bytes of memory from a memory heap.
+@return allocated storage, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
void*
mem_heap_alloc(
/*===========*/
- /* out: allocated storage, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: number of bytes; if the heap is allowed
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */
-/*********************************************************************
-Returns a pointer to the heap top. */
+/*****************************************************************//**
+Returns a pointer to the heap top.
+@return pointer to the heap top */
UNIV_INLINE
byte*
mem_heap_get_heap_top(
/*==================*/
- /* out: pointer to the heap top */
- mem_heap_t* heap); /* in: memory heap */
-/*********************************************************************
+ mem_heap_t* heap); /*!< in: memory heap */
+/*****************************************************************//**
Frees the space in a memory heap exceeding the pointer given. The
pointer must have been acquired from mem_heap_get_heap_top. The first
memory block of the heap is not freed. */
@@ -175,42 +182,42 @@ UNIV_INLINE
void
mem_heap_free_heap_top(
/*===================*/
- mem_heap_t* heap, /* in: heap from which to free */
- byte* old_top);/* in: pointer to old top of heap */
-/*********************************************************************
+ mem_heap_t* heap, /*!< in: heap from which to free */
+ byte* old_top);/*!< in: pointer to old top of heap */
+/*****************************************************************//**
Empties a memory heap. The first memory block of the heap is not freed. */
UNIV_INLINE
void
mem_heap_empty(
/*===========*/
- mem_heap_t* heap); /* in: heap to empty */
-/*********************************************************************
+ mem_heap_t* heap); /*!< in: heap to empty */
+/*****************************************************************//**
Returns a pointer to the topmost element in a memory heap.
-The size of the element must be given. */
+The size of the element must be given.
+@return pointer to the topmost element */
UNIV_INLINE
void*
mem_heap_get_top(
/*=============*/
- /* out: pointer to the topmost element */
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: size of the topmost element */
-/*********************************************************************
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: size of the topmost element */
+/*****************************************************************//**
Frees the topmost element in a memory heap.
The size of the element must be given. */
UNIV_INLINE
void
mem_heap_free_top(
/*==============*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: size of the topmost element */
-/*********************************************************************
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: size of the topmost element */
+/*****************************************************************//**
Returns the space in bytes occupied by a memory heap. */
UNIV_INLINE
ulint
mem_heap_get_size(
/*==============*/
- mem_heap_t* heap); /* in: heap */
-/******************************************************************
+ mem_heap_t* heap); /*!< in: heap */
+/**************************************************************//**
Use this macro instead of the corresponding function!
Macro for memory buffer allocation */
@@ -218,28 +225,28 @@ Macro for memory buffer allocation */
#define mem_alloc(N) mem_alloc_func((N), NULL, __FILE__, __LINE__)
#define mem_alloc2(N,S) mem_alloc_func((N), (S), __FILE__, __LINE__)
-/*******************************************************************
+/***************************************************************//**
NOTE: Use the corresponding macro instead of this function.
Allocates a single buffer of memory from the dynamic memory of
the C compiler. Is like malloc of C. The buffer must be freed
-with mem_free. */
+with mem_free.
+@return own: free storage */
UNIV_INLINE
void*
mem_alloc_func(
/*===========*/
- /* out, own: free storage */
- ulint n, /* in: requested size in bytes */
- ulint* size, /* out: allocated size in bytes,
+ ulint n, /*!< in: requested size in bytes */
+ ulint* size, /*!< out: allocated size in bytes,
or NULL */
- const char* file_name, /* in: file name where created */
- ulint line); /* in: line where created */
+ const char* file_name, /*!< in: file name where created */
+ ulint line); /*!< in: line where created */
-/******************************************************************
+/**************************************************************//**
Use this macro instead of the corresponding function!
Macro for memory buffer freeing */
#define mem_free(PTR) mem_free_func((PTR), __FILE__, __LINE__)
-/*******************************************************************
+/***************************************************************//**
NOTE: Use the corresponding macro instead of this function.
Frees a single buffer of storage from
the dynamic memory of C compiler. Similar to free of C. */
@@ -247,103 +254,87 @@ UNIV_INLINE
void
mem_free_func(
/*==========*/
- void* ptr, /* in, own: buffer to be freed */
- const char* file_name, /* in: file name where created */
- ulint line /* in: line where created */
-);
+ void* ptr, /*!< in, own: buffer to be freed */
+ const char* file_name, /*!< in: file name where created */
+ ulint line); /*!< in: line where created */
-/**************************************************************************
-Duplicates a NUL-terminated string. */
+/**********************************************************************//**
+Duplicates a NUL-terminated string.
+@return own: a copy of the string, must be deallocated with mem_free */
UNIV_INLINE
char*
mem_strdup(
/*=======*/
- /* out, own: a copy of the string,
- must be deallocated with mem_free */
- const char* str); /* in: string to be copied */
-/**************************************************************************
-Makes a NUL-terminated copy of a nonterminated string. */
+ const char* str); /*!< in: string to be copied */
+/**********************************************************************//**
+Makes a NUL-terminated copy of a nonterminated string.
+@return own: a copy of the string, must be deallocated with mem_free */
UNIV_INLINE
char*
mem_strdupl(
/*========*/
- /* out, own: a copy of the string,
- must be deallocated with mem_free */
- const char* str, /* in: string to be copied */
- ulint len); /* in: length of str, in bytes */
+ const char* str, /*!< in: string to be copied */
+ ulint len); /*!< in: length of str, in bytes */
-/**************************************************************************
-Duplicates a NUL-terminated string, allocated from a memory heap. */
+/**********************************************************************//**
+Duplicates a NUL-terminated string, allocated from a memory heap.
+@return own: a copy of the string */
UNIV_INTERN
char*
mem_heap_strdup(
/*============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str); /* in: string to be copied */
-/**************************************************************************
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* str); /*!< in: string to be copied */
+/**********************************************************************//**
Makes a NUL-terminated copy of a nonterminated string,
-allocated from a memory heap. */
+allocated from a memory heap.
+@return own: a copy of the string */
UNIV_INLINE
char*
mem_heap_strdupl(
/*=============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str, /* in: string to be copied */
- ulint len); /* in: length of str, in bytes */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* str, /*!< in: string to be copied */
+ ulint len); /*!< in: length of str, in bytes */
-/**************************************************************************
-Concatenate two strings and return the result, using a memory heap. */
+/**********************************************************************//**
+Concatenate two strings and return the result, using a memory heap.
+@return own: the result */
UNIV_INTERN
char*
mem_heap_strcat(
/*============*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* s1, /* in: string 1 */
- const char* s2); /* in: string 2 */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* s1, /*!< in: string 1 */
+ const char* s2); /*!< in: string 2 */
-/**************************************************************************
-Duplicate a block of data, allocated from a memory heap. */
+/**********************************************************************//**
+Duplicate a block of data, allocated from a memory heap.
+@return own: a copy of the data */
UNIV_INTERN
void*
mem_heap_dup(
/*=========*/
- /* out, own: a copy of the data */
- mem_heap_t* heap, /* in: memory heap where copy is allocated */
- const void* data, /* in: data to be copied */
- ulint len); /* in: length of data, in bytes */
+ mem_heap_t* heap, /*!< in: memory heap where copy is allocated */
+ const void* data, /*!< in: data to be copied */
+ ulint len); /*!< in: length of data, in bytes */
-/**************************************************************************
-Concatenate two memory blocks and return the result, using a memory heap. */
-UNIV_INTERN
-void*
-mem_heap_cat(
-/*=========*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where result is allocated */
- const void* b1, /* in: block 1 */
- ulint len1, /* in: length of b1, in bytes */
- const void* b2, /* in: block 2 */
- ulint len2); /* in: length of b2, in bytes */
-
-/********************************************************************
+/****************************************************************//**
A simple (s)printf replacement that dynamically allocates the space for the
formatted string from the given heap. This supports a very limited set of
the printf syntax: types 's' and 'u' and length modifier 'l' (which is
-required for the 'u' type). */
+required for the 'u' type).
+@return heap-allocated formatted string */
UNIV_INTERN
char*
mem_heap_printf(
/*============*/
- /* out: heap-allocated formatted string */
- mem_heap_t* heap, /* in: memory heap */
- const char* format, /* in: format string */
+ mem_heap_t* heap, /*!< in: memory heap */
+ const char* format, /*!< in: format string */
...) __attribute__ ((format (printf, 2, 3)));
#ifdef MEM_PERIODIC_CHECK
-/**********************************************************************
+/******************************************************************//**
Goes through the list of all allocated mem blocks, checks their magic
numbers, and reports possible corruption. */
UNIV_INTERN
@@ -359,7 +350,7 @@ mem_validate_all_blocks(void);
struct mem_block_info_struct {
ulint magic_n;/* magic number for debugging */
char file_name[8];/* file name where the mem heap was created */
- ulint line; /* line number where the mem heap was created */
+ ulint line; /*!< line number where the mem heap was created */
UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the
the list this is the base node of the list of blocks;
in subsequent blocks this is undefined */
@@ -367,13 +358,14 @@ struct mem_block_info_struct {
and prev in the list. The first block allocated
to the heap is also the first block in this list,
though it also contains the base node of the list. */
- ulint len; /* physical length of this block in bytes */
- ulint type; /* type of heap: MEM_HEAP_DYNAMIC, or
+ ulint len; /*!< physical length of this block in bytes */
+ ulint type; /*!< type of heap: MEM_HEAP_DYNAMIC, or
MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */
- ulint free; /* offset in bytes of the first free position for
+ ulint free; /*!< offset in bytes of the first free position for
user data in the block */
- ulint start; /* the value of the struct field 'free' at the
+ ulint start; /*!< the value of the struct field 'free' at the
creation of the block */
+#ifndef UNIV_HOTBACKUP
void* free_block;
/* if the MEM_HEAP_BTR_SEARCH bit is set in type,
and this is the heap root, this can contain an
@@ -384,6 +376,7 @@ struct mem_block_info_struct {
/* if this block has been allocated from the buffer
pool, this contains the buf_block_t handle;
otherwise, this is NULL */
+#endif /* !UNIV_HOTBACKUP */
#ifdef MEM_PERIODIC_CHECK
UT_LIST_NODE_T(mem_block_t) mem_block_list;
/* List of all mem blocks allocated; protected
diff --git a/storage/xtradb/include/mem0mem.ic b/storage/xtradb/include/mem0mem.ic
index 04b4234904a..e7080d8c508 100644
--- a/storage/xtradb/include/mem0mem.ic
+++ b/storage/xtradb/include/mem0mem.ic
@@ -16,58 +16,60 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/mem0mem.ic
The memory management
Created 6/8/1994 Heikki Tuuri
*************************************************************************/
#include "mem0dbg.ic"
-
-#include "mem0pool.h"
-
-/*******************************************************************
-Creates a memory heap block where data can be allocated. */
+#ifndef UNIV_HOTBACKUP
+# include "mem0pool.h"
+#endif /* !UNIV_HOTBACKUP */
+
+/***************************************************************//**
+Creates a memory heap block where data can be allocated.
+@return own: memory heap block, NULL if did not succeed (only possible
+for MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INTERN
mem_block_t*
mem_heap_create_block(
/*==================*/
- /* out, own: memory heap block, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap or NULL if first block
+ mem_heap_t* heap, /*!< in: memory heap or NULL if first block
should be created */
- ulint n, /* in: number of bytes needed for user data */
- ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC or
+ ulint n, /*!< in: number of bytes needed for user data */
+ ulint type, /*!< in: type of heap: MEM_HEAP_DYNAMIC or
MEM_HEAP_BUFFER */
- const char* file_name,/* in: file name where created */
- ulint line); /* in: line where created */
-/**********************************************************************
+ const char* file_name,/*!< in: file name where created */
+ ulint line); /*!< in: line where created */
+/******************************************************************//**
Frees a block from a memory heap. */
UNIV_INTERN
void
mem_heap_block_free(
/*================*/
- mem_heap_t* heap, /* in: heap */
- mem_block_t* block); /* in: block to free */
-/**********************************************************************
+ mem_heap_t* heap, /*!< in: heap */
+ mem_block_t* block); /*!< in: block to free */
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
Frees the free_block field from a memory heap. */
UNIV_INTERN
void
mem_heap_free_block_free(
/*=====================*/
- mem_heap_t* heap); /* in: heap */
-/*******************************************************************
-Adds a new block to a memory heap. */
+ mem_heap_t* heap); /*!< in: heap */
+#endif /* !UNIV_HOTBACKUP */
+/***************************************************************//**
+Adds a new block to a memory heap.
+@return created block, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INTERN
mem_block_t*
mem_heap_add_block(
/*===============*/
- /* out: created block, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: number of bytes user needs */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: number of bytes user needs */
UNIV_INLINE
void
@@ -135,15 +137,15 @@ mem_block_get_start(mem_block_t* block)
return(block->start);
}
-/*******************************************************************
-Allocates and zero-fills n bytes of memory from a memory heap. */
+/***************************************************************//**
+Allocates and zero-fills n bytes of memory from a memory heap.
+@return allocated, zero-filled storage */
UNIV_INLINE
void*
mem_heap_zalloc(
/*============*/
- /* out: allocated, zero-filled storage */
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: number of bytes; if the heap is allowed
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */
{
@@ -152,17 +154,16 @@ mem_heap_zalloc(
return(memset(mem_heap_alloc(heap, n), 0, n));
}
-/*******************************************************************
-Allocates n bytes of memory from a memory heap. */
+/***************************************************************//**
+Allocates n bytes of memory from a memory heap.
+@return allocated storage, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
void*
mem_heap_alloc(
/*===========*/
- /* out: allocated storage, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: number of bytes; if the heap is allowed
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */
{
@@ -216,14 +217,14 @@ mem_heap_alloc(
return(buf);
}
-/*********************************************************************
-Returns a pointer to the heap top. */
+/*****************************************************************//**
+Returns a pointer to the heap top.
+@return pointer to the heap top */
UNIV_INLINE
byte*
mem_heap_get_heap_top(
/*==================*/
- /* out: pointer to the heap top */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
mem_block_t* block;
byte* buf;
@@ -237,7 +238,7 @@ mem_heap_get_heap_top(
return(buf);
}
-/*********************************************************************
+/*****************************************************************//**
Frees the space in a memory heap exceeding the pointer given. The
pointer must have been acquired from mem_heap_get_heap_top. The first
memory block of the heap is not freed. */
@@ -245,8 +246,8 @@ UNIV_INLINE
void
mem_heap_free_heap_top(
/*===================*/
- mem_heap_t* heap, /* in: heap from which to free */
- byte* old_top)/* in: pointer to old top of heap */
+ mem_heap_t* heap, /*!< in: heap from which to free */
+ byte* old_top)/*!< in: pointer to old top of heap */
{
mem_block_t* block;
mem_block_t* prev_block;
@@ -321,31 +322,32 @@ mem_heap_free_heap_top(
}
}
-/*********************************************************************
+/*****************************************************************//**
Empties a memory heap. The first memory block of the heap is not freed. */
UNIV_INLINE
void
mem_heap_empty(
/*===========*/
- mem_heap_t* heap) /* in: heap to empty */
+ mem_heap_t* heap) /*!< in: heap to empty */
{
mem_heap_free_heap_top(heap, (byte*)heap + mem_block_get_start(heap));
-
+#ifndef UNIV_HOTBACKUP
if (heap->free_block) {
mem_heap_free_block_free(heap);
}
+#endif /* !UNIV_HOTBACKUP */
}
-/*********************************************************************
+/*****************************************************************//**
Returns a pointer to the topmost element in a memory heap. The size of the
-element must be given. */
+element must be given.
+@return pointer to the topmost element */
UNIV_INLINE
void*
mem_heap_get_top(
/*=============*/
- /* out: pointer to the topmost element */
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: size of the topmost element */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: size of the topmost element */
{
mem_block_t* block;
void* buf;
@@ -371,15 +373,15 @@ mem_heap_get_top(
return(buf);
}
-/*********************************************************************
+/*****************************************************************//**
Frees the topmost element in a memory heap. The size of the element must be
given. */
UNIV_INLINE
void
mem_heap_free_top(
/*==============*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: size of the topmost element */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: size of the topmost element */
{
mem_block_t* block;
@@ -414,24 +416,23 @@ mem_heap_free_top(
}
}
-/*********************************************************************
+/*****************************************************************//**
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap. For debugging purposes, takes also the file name and line as
-argument. */
+argument.
+@return own: memory heap, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
mem_heap_t*
mem_heap_create_func(
/*=================*/
- /* out, own: memory heap, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- ulint n, /* in: desired start block size,
+ ulint n, /*!< in: desired start block size,
this means that a single user buffer
of size n will fit in the block,
0 creates a default size block */
- ulint type, /* in: heap type */
- const char* file_name, /* in: file name where created */
- ulint line) /* in: line where created */
+ ulint type, /*!< in: heap type */
+ const char* file_name, /*!< in: file name where created */
+ ulint line) /*!< in: line where created */
{
mem_block_t* block;
@@ -460,7 +461,7 @@ mem_heap_create_func(
return(block);
}
-/*********************************************************************
+/*****************************************************************//**
NOTE: Use the corresponding macro instead of this function. Frees the space
occupied by a memory heap. In the debug version erases the heap memory
blocks. */
@@ -468,9 +469,9 @@ UNIV_INLINE
void
mem_heap_free_func(
/*===============*/
- mem_heap_t* heap, /* in, own: heap to be freed */
+ mem_heap_t* heap, /*!< in, own: heap to be freed */
const char* file_name __attribute__((unused)),
- /* in: file name where freed */
+ /*!< in: file name where freed */
ulint line __attribute__((unused)))
{
mem_block_t* block;
@@ -488,10 +489,11 @@ mem_heap_free_func(
mem_hash_remove(heap, file_name, line);
#endif
-
+#ifndef UNIV_HOTBACKUP
if (heap->free_block) {
mem_heap_free_block_free(heap);
}
+#endif /* !UNIV_HOTBACKUP */
while (block != NULL) {
/* Store the contents of info before freeing current block
@@ -505,21 +507,21 @@ mem_heap_free_func(
}
}
-/*******************************************************************
+/***************************************************************//**
NOTE: Use the corresponding macro instead of this function.
Allocates a single buffer of memory from the dynamic memory of
the C compiler. Is like malloc of C. The buffer must be freed
-with mem_free. */
+with mem_free.
+@return own: free storage */
UNIV_INLINE
void*
mem_alloc_func(
/*===========*/
- /* out, own: free storage */
- ulint n, /* in: desired number of bytes */
- ulint* size, /* out: allocated size in bytes,
+ ulint n, /*!< in: desired number of bytes */
+ ulint* size, /*!< out: allocated size in bytes,
or NULL */
- const char* file_name, /* in: file name where created */
- ulint line) /* in: line where created */
+ const char* file_name, /*!< in: file name where created */
+ ulint line) /*!< in: line where created */
{
mem_heap_t* heap;
void* buf;
@@ -550,7 +552,7 @@ mem_alloc_func(
return(buf);
}
-/*******************************************************************
+/***************************************************************//**
NOTE: Use the corresponding macro instead of this function. Frees a single
buffer of storage from the dynamic memory of the C compiler. Similar to the
free of C. */
@@ -558,10 +560,9 @@ UNIV_INLINE
void
mem_free_func(
/*==========*/
- void* ptr, /* in, own: buffer to be freed */
- const char* file_name, /* in: file name where created */
- ulint line /* in: line where created */
- )
+ void* ptr, /*!< in, own: buffer to be freed */
+ const char* file_name, /*!< in: file name where created */
+ ulint line) /*!< in: line where created */
{
mem_heap_t* heap;
@@ -570,13 +571,13 @@ mem_free_func(
mem_heap_free_func(heap, file_name, line);
}
-/*********************************************************************
+/*****************************************************************//**
Returns the space in bytes occupied by a memory heap. */
UNIV_INLINE
ulint
mem_heap_get_size(
/*==============*/
- mem_heap_t* heap) /* in: heap */
+ mem_heap_t* heap) /*!< in: heap */
{
mem_block_t* block;
ulint size = 0;
@@ -590,55 +591,54 @@ mem_heap_get_size(
size += mem_block_get_len(block);
block = UT_LIST_GET_NEXT(list, block);
}
-
+#ifndef UNIV_HOTBACKUP
if (heap->free_block) {
size += UNIV_PAGE_SIZE;
}
+#endif /* !UNIV_HOTBACKUP */
return(size);
}
-/**************************************************************************
-Duplicates a NUL-terminated string. */
+/**********************************************************************//**
+Duplicates a NUL-terminated string.
+@return own: a copy of the string, must be deallocated with mem_free */
UNIV_INLINE
char*
mem_strdup(
/*=======*/
- /* out, own: a copy of the string,
- must be deallocated with mem_free */
- const char* str) /* in: string to be copied */
+ const char* str) /*!< in: string to be copied */
{
ulint len = strlen(str) + 1;
return((char*) memcpy(mem_alloc(len), str, len));
}
-/**************************************************************************
-Makes a NUL-terminated copy of a nonterminated string. */
+/**********************************************************************//**
+Makes a NUL-terminated copy of a nonterminated string.
+@return own: a copy of the string, must be deallocated with mem_free */
UNIV_INLINE
char*
mem_strdupl(
/*========*/
- /* out, own: a copy of the string,
- must be deallocated with mem_free */
- const char* str, /* in: string to be copied */
- ulint len) /* in: length of str, in bytes */
+ const char* str, /*!< in: string to be copied */
+ ulint len) /*!< in: length of str, in bytes */
{
char* s = (char*) mem_alloc(len + 1);
s[len] = 0;
return((char*) memcpy(s, str, len));
}
-/**************************************************************************
+/**********************************************************************//**
Makes a NUL-terminated copy of a nonterminated string,
-allocated from a memory heap. */
+allocated from a memory heap.
+@return own: a copy of the string */
UNIV_INLINE
char*
mem_heap_strdupl(
/*=============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str, /* in: string to be copied */
- ulint len) /* in: length of str, in bytes */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* str, /*!< in: string to be copied */
+ ulint len) /*!< in: length of str, in bytes */
{
char* s = (char*) mem_heap_alloc(heap, len + 1);
s[len] = 0;
diff --git a/storage/xtradb/include/mem0pool.h b/storage/xtradb/include/mem0pool.h
index 7e51b07bfe0..5e93bf88a47 100644
--- a/storage/xtradb/include/mem0pool.h
+++ b/storage/xtradb/include/mem0pool.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mem0pool.h
The lowest-level memory management
Created 6/9/1994 Heikki Tuuri
@@ -29,94 +30,103 @@ Created 6/9/1994 Heikki Tuuri
#include "os0file.h"
#include "ut0lst.h"
+/** Memory area header */
typedef struct mem_area_struct mem_area_t;
+/** Memory pool */
typedef struct mem_pool_struct mem_pool_t;
-/* The common memory pool */
+/** The common memory pool */
extern mem_pool_t* mem_comm_pool;
-/* Memory area header */
+/** Memory area header */
struct mem_area_struct{
- ulint size_and_free; /* memory area size is obtained by
+ ulint size_and_free; /*!< memory area size is obtained by
anding with ~MEM_AREA_FREE; area in
a free list if ANDing with
MEM_AREA_FREE results in nonzero */
UT_LIST_NODE_T(mem_area_t)
- free_list; /* free list node */
+ free_list; /*!< free list node */
};
-/* Each memory area takes this many extra bytes for control information */
+/** Each memory area takes this many extra bytes for control information */
#define MEM_AREA_EXTRA_SIZE (ut_calc_align(sizeof(struct mem_area_struct),\
UNIV_MEM_ALIGNMENT))
-/************************************************************************
-Creates a memory pool. */
+/********************************************************************//**
+Creates a memory pool.
+@return memory pool */
UNIV_INTERN
mem_pool_t*
mem_pool_create(
/*============*/
- /* out: memory pool */
- ulint size); /* in: pool size in bytes */
-/************************************************************************
+ ulint size); /*!< in: pool size in bytes */
+/********************************************************************//**
+Frees a memory pool. */
+UNIV_INTERN
+void
+mem_pool_free(
+/*==========*/
+ mem_pool_t* pool); /*!< in, own: memory pool */
+/********************************************************************//**
Allocates memory from a pool. NOTE: This low-level function should only be
-used in mem0mem.*! */
+used in mem0mem.*!
+@return own: allocated memory buffer */
UNIV_INTERN
void*
mem_area_alloc(
/*===========*/
- /* out, own: allocated memory buffer */
- ulint* psize, /* in: requested size in bytes; for optimum
+ ulint* psize, /*!< in: requested size in bytes; for optimum
space usage, the size should be a power of 2
minus MEM_AREA_EXTRA_SIZE;
out: allocated size in bytes (greater than
or equal to the requested size) */
- mem_pool_t* pool); /* in: memory pool */
-/************************************************************************
+ mem_pool_t* pool); /*!< in: memory pool */
+/********************************************************************//**
Frees memory to a pool. */
UNIV_INTERN
void
mem_area_free(
/*==========*/
- void* ptr, /* in, own: pointer to allocated memory
+ void* ptr, /*!< in, own: pointer to allocated memory
buffer */
- mem_pool_t* pool); /* in: memory pool */
-/************************************************************************
-Returns the amount of reserved memory. */
+ mem_pool_t* pool); /*!< in: memory pool */
+/********************************************************************//**
+Returns the amount of reserved memory.
+@return reserved mmeory in bytes */
UNIV_INTERN
ulint
mem_pool_get_reserved(
/*==================*/
- /* out: reserved mmeory in bytes */
- mem_pool_t* pool); /* in: memory pool */
-/************************************************************************
+ mem_pool_t* pool); /*!< in: memory pool */
+/********************************************************************//**
Reserves the mem pool mutex. */
UNIV_INTERN
void
mem_pool_mutex_enter(void);
/*======================*/
-/************************************************************************
+/********************************************************************//**
Releases the mem pool mutex. */
UNIV_INTERN
void
mem_pool_mutex_exit(void);
/*=====================*/
-/************************************************************************
-Validates a memory pool. */
+/********************************************************************//**
+Validates a memory pool.
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_pool_validate(
/*==============*/
- /* out: TRUE if ok */
- mem_pool_t* pool); /* in: memory pool */
-/************************************************************************
+ mem_pool_t* pool); /*!< in: memory pool */
+/********************************************************************//**
Prints info of a memory pool. */
UNIV_INTERN
void
mem_pool_print_info(
/*================*/
- FILE* outfile,/* in: output file to write to */
- mem_pool_t* pool); /* in: memory pool */
+ FILE* outfile,/*!< in: output file to write to */
+ mem_pool_t* pool); /*!< in: memory pool */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/mem0pool.ic b/storage/xtradb/include/mem0pool.ic
index 4cc65e754ce..b891dd6dea0 100644
--- a/storage/xtradb/include/mem0pool.ic
+++ b/storage/xtradb/include/mem0pool.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/mem0pool.ic
The lowest-level memory management
Created 6/8/1994 Heikki Tuuri
diff --git a/storage/xtradb/include/mtr0log.h b/storage/xtradb/include/mtr0log.h
index 44374cdf1a4..6322af2a569 100644
--- a/storage/xtradb/include/mtr0log.h
+++ b/storage/xtradb/include/mtr0log.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0log.h
Mini-transaction logging routines
Created 12/7/1995 Heikki Tuuri
@@ -29,216 +30,218 @@ Created 12/7/1995 Heikki Tuuri
#include "mtr0mtr.h"
#include "dict0types.h"
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Writes 1 - 4 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_ulint(
/*=============*/
- byte* ptr, /* in: pointer where to write */
- ulint val, /* in: value to write */
- byte type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
+ byte* ptr, /*!< in: pointer where to write */
+ ulint val, /*!< in: value to write */
+ byte type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
Writes 8 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_dulint(
/*==============*/
- byte* ptr, /* in: pointer where to write */
- dulint val, /* in: value to write */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
+ byte* ptr, /*!< in: pointer where to write */
+ dulint val, /*!< in: value to write */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
Writes a string to a file page buffered in the buffer pool. Writes the
corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_string(
/*==============*/
- byte* ptr, /* in: pointer where to write */
- const byte* str, /* in: string to write */
- ulint len, /* in: string length */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
+ byte* ptr, /*!< in: pointer where to write */
+ const byte* str, /*!< in: string to write */
+ ulint len, /*!< in: string length */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
Logs a write of a string to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_log_string(
/*============*/
- byte* ptr, /* in: pointer written to */
- ulint len, /* in: string length */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
+ byte* ptr, /*!< in: pointer written to */
+ ulint len, /*!< in: string length */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
Writes initial part of a log record consisting of one-byte item
type and four-byte space and page numbers. */
UNIV_INTERN
void
mlog_write_initial_log_record(
/*==========================*/
- const byte* ptr, /* in: pointer to (inside) a buffer
+ const byte* ptr, /*!< in: pointer to (inside) a buffer
frame holding the file page where
modification is made */
- byte type, /* in: log item type: MLOG_1BYTE, ... */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
-Writes a log record about an .ibd file create/delete/rename. */
+ byte type, /*!< in: log item type: MLOG_1BYTE, ... */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
+Writes a log record about an .ibd file create/delete/rename.
+@return new value of log_ptr */
UNIV_INLINE
byte*
mlog_write_initial_log_record_for_file_op(
/*======================================*/
- /* out: new value of log_ptr */
- ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
+ ulint type, /*!< in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
- ulint space_id,/* in: space id, if applicable */
- ulint page_no,/* in: page number (not relevant currently) */
- byte* log_ptr,/* in: pointer to mtr log which has been opened */
- mtr_t* mtr); /* in: mtr */
-/************************************************************
+ ulint space_id,/*!< in: space id, if applicable */
+ ulint page_no,/*!< in: page number (not relevant currently) */
+ byte* log_ptr,/*!< in: pointer to mtr log which has been opened */
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************//**
Catenates 1 - 4 bytes to the mtr log. */
UNIV_INLINE
void
mlog_catenate_ulint(
/*================*/
- mtr_t* mtr, /* in: mtr */
- ulint val, /* in: value to write */
- ulint type); /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
-/************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ ulint val, /*!< in: value to write */
+ ulint type); /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+/********************************************************//**
Catenates n bytes to the mtr log. */
UNIV_INTERN
void
mlog_catenate_string(
/*=================*/
- mtr_t* mtr, /* in: mtr */
- const byte* str, /* in: string to write */
- ulint len); /* in: string length */
-/************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* str, /*!< in: string to write */
+ ulint len); /*!< in: string length */
+/********************************************************//**
Catenates a compressed ulint to mlog. */
UNIV_INLINE
void
mlog_catenate_ulint_compressed(
/*===========================*/
- mtr_t* mtr, /* in: mtr */
- ulint val); /* in: value to write */
-/************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ ulint val); /*!< in: value to write */
+/********************************************************//**
Catenates a compressed dulint to mlog. */
UNIV_INLINE
void
mlog_catenate_dulint_compressed(
/*============================*/
- mtr_t* mtr, /* in: mtr */
- dulint val); /* in: value to write */
-/************************************************************
-Opens a buffer to mlog. It must be closed with mlog_close. */
+ mtr_t* mtr, /*!< in: mtr */
+ dulint val); /*!< in: value to write */
+/********************************************************//**
+Opens a buffer to mlog. It must be closed with mlog_close.
+@return buffer, NULL if log mode MTR_LOG_NONE */
UNIV_INLINE
byte*
mlog_open(
/*======*/
- /* out: buffer, NULL if log mode MTR_LOG_NONE */
- mtr_t* mtr, /* in: mtr */
- ulint size); /* in: buffer size in bytes; MUST be
+ mtr_t* mtr, /*!< in: mtr */
+ ulint size); /*!< in: buffer size in bytes; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
-/************************************************************
+/********************************************************//**
Closes a buffer opened to mlog. */
UNIV_INLINE
void
mlog_close(
/*=======*/
- mtr_t* mtr, /* in: mtr */
- byte* ptr); /* in: buffer space from ptr up was not used */
-/************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ byte* ptr); /*!< in: buffer space from ptr up was not used */
+/********************************************************//**
Writes the initial part of a log record (3..11 bytes).
If the implementation of this function is changed, all
-size parameters to mlog_open() should be adjusted accordingly! */
+size parameters to mlog_open() should be adjusted accordingly!
+@return new value of log_ptr */
UNIV_INLINE
byte*
mlog_write_initial_log_record_fast(
/*===============================*/
- /* out: new value of log_ptr */
- const byte* ptr, /* in: pointer to (inside) a buffer
+ const byte* ptr, /*!< in: pointer to (inside) a buffer
frame holding the file page where
modification is made */
- byte type, /* in: log item type: MLOG_1BYTE, ... */
- byte* log_ptr,/* in: pointer to mtr log which has
+ byte type, /*!< in: log item type: MLOG_1BYTE, ... */
+ byte* log_ptr,/*!< in: pointer to mtr log which has
been opened */
- mtr_t* mtr); /* in: mtr */
-/************************************************************
-Parses an initial log record written by mlog_write_initial_log_record. */
+ mtr_t* mtr); /*!< in: mtr */
+#else /* !UNIV_HOTBACKUP */
+# define mlog_write_initial_log_record(ptr,type,mtr) ((void) 0)
+# define mlog_write_initial_log_record_fast(ptr,type,log_ptr,mtr) ((byte *) 0)
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************//**
+Parses an initial log record written by mlog_write_initial_log_record.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_initial_log_record(
/*==========================*/
- /* out: parsed record end, NULL if not a complete
- record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* type, /* out: log record type: MLOG_1BYTE, ... */
- ulint* space, /* out: space id */
- ulint* page_no);/* out: page number */
-/************************************************************
-Parses a log record written by mlog_write_ulint or mlog_write_dulint. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* type, /*!< out: log record type: MLOG_1BYTE, ... */
+ ulint* space, /*!< out: space id */
+ ulint* page_no);/*!< out: page number */
+/********************************************************//**
+Parses a log record written by mlog_write_ulint or mlog_write_dulint.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_nbytes(
/*==============*/
- /* out: parsed record end, NULL if not a complete
- record */
- ulint type, /* in: log record type: MLOG_1BYTE, ... */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* page, /* in: page where to apply the log record, or NULL */
- void* page_zip);/* in/out: compressed page, or NULL */
-/************************************************************
-Parses a log record written by mlog_write_string. */
+ ulint type, /*!< in: log record type: MLOG_1BYTE, ... */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* page, /*!< in: page where to apply the log record, or NULL */
+ void* page_zip);/*!< in/out: compressed page, or NULL */
+/********************************************************//**
+Parses a log record written by mlog_write_string.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_string(
/*==============*/
- /* out: parsed record end, NULL if not a complete
- record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* page, /* in: page where to apply the log record, or NULL */
- void* page_zip);/* in/out: compressed page, or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* page, /*!< in: page where to apply the log record, or NULL */
+ void* page_zip);/*!< in/out: compressed page, or NULL */
-
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Opens a buffer for mlog, writes the initial log record and,
if needed, the field lengths of an index. Reserves space
for further log entries. The log entry must be closed with
-mtr_close(). */
+mtr_close().
+@return buffer, NULL if log mode MTR_LOG_NONE */
UNIV_INTERN
byte*
mlog_open_and_write_index(
/*======================*/
- /* out: buffer, NULL if log mode
- MTR_LOG_NONE */
- mtr_t* mtr, /* in: mtr */
- byte* rec, /* in: index record or page */
- dict_index_t* index, /* in: record descriptor */
- byte type, /* in: log item type */
- ulint size); /* in: requested buffer size in bytes
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* rec, /*!< in: index record or page */
+ dict_index_t* index, /*!< in: record descriptor */
+ byte type, /*!< in: log item type */
+ ulint size); /*!< in: requested buffer size in bytes
(if 0, calls mlog_close() and returns NULL) */
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Parses a log record written by mlog_open_and_write_index. */
+/********************************************************//**
+Parses a log record written by mlog_open_and_write_index.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_index(
/*=============*/
- /* out: parsed record end,
- NULL if not a complete record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- /* out: new value of log_ptr */
- ibool comp, /* in: TRUE=compact record format */
- dict_index_t** index); /* out, own: dummy index */
+ byte* ptr, /*!< in: buffer */
+ const byte* end_ptr,/*!< in: buffer end */
+ ibool comp, /*!< in: TRUE=compact record format */
+ dict_index_t** index); /*!< out, own: dummy index */
+#ifndef UNIV_HOTBACKUP
/* Insert, update, and maybe other functions may use this value to define an
extra mlog buffer size for variable size data */
#define MLOG_BUF_MARGIN 256
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "mtr0log.ic"
diff --git a/storage/xtradb/include/mtr0log.ic b/storage/xtradb/include/mtr0log.ic
index 5f05befb9cc..5c24c38b337 100644
--- a/storage/xtradb/include/mtr0log.ic
+++ b/storage/xtradb/include/mtr0log.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0log.ic
Mini-transaction logging routines
Created 12/7/1995 Heikki Tuuri
@@ -25,16 +26,18 @@ Created 12/7/1995 Heikki Tuuri
#include "mach0data.h"
#include "ut0lst.h"
#include "buf0buf.h"
+#include "fsp0types.h"
+#include "trx0sys.h"
-/************************************************************
-Opens a buffer to mlog. It must be closed with mlog_close. */
+/********************************************************//**
+Opens a buffer to mlog. It must be closed with mlog_close.
+@return buffer, NULL if log mode MTR_LOG_NONE */
UNIV_INLINE
byte*
mlog_open(
/*======*/
- /* out: buffer, NULL if log mode MTR_LOG_NONE */
- mtr_t* mtr, /* in: mtr */
- ulint size) /* in: buffer size in bytes; MUST be
+ mtr_t* mtr, /*!< in: mtr */
+ ulint size) /*!< in: buffer size in bytes; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
{
dyn_array_t* mlog;
@@ -51,14 +54,14 @@ mlog_open(
return(dyn_array_open(mlog, size));
}
-/************************************************************
+/********************************************************//**
Closes a buffer opened to mlog. */
UNIV_INLINE
void
mlog_close(
/*=======*/
- mtr_t* mtr, /* in: mtr */
- byte* ptr) /* in: buffer space from ptr up was not used */
+ mtr_t* mtr, /*!< in: mtr */
+ byte* ptr) /*!< in: buffer space from ptr up was not used */
{
dyn_array_t* mlog;
@@ -69,15 +72,16 @@ mlog_close(
dyn_array_close(mlog, ptr);
}
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Catenates 1 - 4 bytes to the mtr log. The value is not compressed. */
UNIV_INLINE
void
mlog_catenate_ulint(
/*================*/
- mtr_t* mtr, /* in: mtr */
- ulint val, /* in: value to write */
- ulint type) /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint val, /*!< in: value to write */
+ ulint type) /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
{
dyn_array_t* mlog;
byte* ptr;
@@ -113,14 +117,14 @@ mlog_catenate_ulint(
}
}
-/************************************************************
+/********************************************************//**
Catenates a compressed ulint to mlog. */
UNIV_INLINE
void
mlog_catenate_ulint_compressed(
/*===========================*/
- mtr_t* mtr, /* in: mtr */
- ulint val) /* in: value to write */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint val) /*!< in: value to write */
{
byte* log_ptr;
@@ -137,14 +141,14 @@ mlog_catenate_ulint_compressed(
mlog_close(mtr, log_ptr);
}
-/************************************************************
+/********************************************************//**
Catenates a compressed dulint to mlog. */
UNIV_INLINE
void
mlog_catenate_dulint_compressed(
/*============================*/
- mtr_t* mtr, /* in: mtr */
- dulint val) /* in: value to write */
+ mtr_t* mtr, /*!< in: mtr */
+ dulint val) /*!< in: value to write */
{
byte* log_ptr;
@@ -161,22 +165,22 @@ mlog_catenate_dulint_compressed(
mlog_close(mtr, log_ptr);
}
-/************************************************************
+/********************************************************//**
Writes the initial part of a log record (3..11 bytes).
If the implementation of this function is changed, all
-size parameters to mlog_open() should be adjusted accordingly! */
+size parameters to mlog_open() should be adjusted accordingly!
+@return new value of log_ptr */
UNIV_INLINE
byte*
mlog_write_initial_log_record_fast(
/*===============================*/
- /* out: new value of log_ptr */
- const byte* ptr, /* in: pointer to (inside) a buffer
+ const byte* ptr, /*!< in: pointer to (inside) a buffer
frame holding the file page where
modification is made */
- byte type, /* in: log item type: MLOG_1BYTE, ... */
- byte* log_ptr,/* in: pointer to mtr log which has
+ byte type, /*!< in: log item type: MLOG_1BYTE, ... */
+ byte* log_ptr,/*!< in: pointer to mtr log which has
been opened */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
#ifdef UNIV_DEBUG
buf_block_t* block;
@@ -193,6 +197,28 @@ mlog_write_initial_log_record_fast(
space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
+ /* check whether the page is in the doublewrite buffer;
+ the doublewrite buffer is located in pages
+ FSP_EXTENT_SIZE, ..., 3 * FSP_EXTENT_SIZE - 1 in the
+ system tablespace */
+ if (space == TRX_SYS_SPACE
+ && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
+ if (trx_doublewrite_buf_is_being_created) {
+ /* Do nothing: we only come to this branch in an
+ InnoDB database creation. We do not redo log
+ anything for the doublewrite buffer pages. */
+ return(log_ptr);
+ } else {
+ fprintf(stderr,
+ "Error: trying to redo log a record of type "
+ "%d on page %lu of space %lu in the "
+ "doublewrite buffer, continuing anyway.\n"
+ "Please post a bug report to "
+ "bugs.mysql.com.\n",
+ type, offset, space);
+ }
+ }
+
mach_write_to_1(log_ptr, type);
log_ptr++;
log_ptr += mach_write_compressed(log_ptr, space);
@@ -218,19 +244,19 @@ mlog_write_initial_log_record_fast(
return(log_ptr);
}
-/************************************************************
-Writes a log record about an .ibd file create/delete/rename. */
+/********************************************************//**
+Writes a log record about an .ibd file create/delete/rename.
+@return new value of log_ptr */
UNIV_INLINE
byte*
mlog_write_initial_log_record_for_file_op(
/*======================================*/
- /* out: new value of log_ptr */
- ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
+ ulint type, /*!< in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
- ulint space_id,/* in: space id, if applicable */
- ulint page_no,/* in: page number (not relevant currently) */
- byte* log_ptr,/* in: pointer to mtr log which has been opened */
- mtr_t* mtr) /* in: mtr */
+ ulint space_id,/*!< in: space id, if applicable */
+ ulint page_no,/*!< in: page number (not relevant currently) */
+ byte* log_ptr,/*!< in: pointer to mtr log which has been opened */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(log_ptr);
@@ -245,3 +271,4 @@ mlog_write_initial_log_record_for_file_op(
return(log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index a29f6c73141..bc3f1951be9 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0mtr.h
Mini-transaction buffer
Created 11/26/1995 Heikki Tuuri
@@ -53,139 +54,166 @@ first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
#define MTR_MEMO_S_LOCK 55
#define MTR_MEMO_X_LOCK 56
-/* Log item types: we have made them to be of the type 'byte'
-for the compiler to warn if val and type parameters are switched
-in a call to mlog_write_ulint. NOTE! For 1 - 8 bytes, the
-flag value must give the length also! */
-#define MLOG_SINGLE_REC_FLAG 128 /* if the mtr contains only
+/** @name Log item types
+The log items are declared 'byte' so that the compiler can warn if val
+and type parameters are switched in a call to mlog_write_ulint. NOTE!
+For 1 - 8 bytes, the flag value must give the length also! @{ */
+#define MLOG_SINGLE_REC_FLAG 128 /*!< if the mtr contains only
one log record for one page,
i.e., write_initial_log_record
has been called only once,
this flag is ORed to the type
of that first log record */
-#define MLOG_1BYTE (1) /* one byte is written */
-#define MLOG_2BYTES (2) /* 2 bytes ... */
-#define MLOG_4BYTES (4) /* 4 bytes ... */
-#define MLOG_8BYTES (8) /* 8 bytes ... */
-#define MLOG_REC_INSERT ((byte)9) /* record insert */
-#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /* mark clustered index record
+#define MLOG_1BYTE (1) /*!< one byte is written */
+#define MLOG_2BYTES (2) /*!< 2 bytes ... */
+#define MLOG_4BYTES (4) /*!< 4 bytes ... */
+#define MLOG_8BYTES (8) /*!< 8 bytes ... */
+#define MLOG_REC_INSERT ((byte)9) /*!< record insert */
+#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /*!< mark clustered index record
deleted */
-#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /* mark secondary index record
+#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /*!< mark secondary index record
deleted */
-#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /* update of a record,
+#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /*!< update of a record,
preserves record field sizes */
-#define MLOG_REC_DELETE ((byte)14) /* delete a record from a
+#define MLOG_REC_DELETE ((byte)14) /*!< delete a record from a
page */
-#define MLOG_LIST_END_DELETE ((byte)15) /* delete record list end on
+#define MLOG_LIST_END_DELETE ((byte)15) /*!< delete record list end on
index page */
-#define MLOG_LIST_START_DELETE ((byte)16) /* delete record list start on
+#define MLOG_LIST_START_DELETE ((byte)16) /*!< delete record list start on
index page */
-#define MLOG_LIST_END_COPY_CREATED ((byte)17) /* copy record list end to a
+#define MLOG_LIST_END_COPY_CREATED ((byte)17) /*!< copy record list end to a
new created index page */
-#define MLOG_PAGE_REORGANIZE ((byte)18) /* reorganize an index page */
-#define MLOG_PAGE_CREATE ((byte)19) /* create an index page */
-#define MLOG_UNDO_INSERT ((byte)20) /* insert entry in an undo
+#define MLOG_PAGE_REORGANIZE ((byte)18) /*!< reorganize an
+ index page in
+ ROW_FORMAT=REDUNDANT */
+#define MLOG_PAGE_CREATE ((byte)19) /*!< create an index page */
+#define MLOG_UNDO_INSERT ((byte)20) /*!< insert entry in an undo
log */
-#define MLOG_UNDO_ERASE_END ((byte)21) /* erase an undo log
+#define MLOG_UNDO_ERASE_END ((byte)21) /*!< erase an undo log
page end */
-#define MLOG_UNDO_INIT ((byte)22) /* initialize a page in an
+#define MLOG_UNDO_INIT ((byte)22) /*!< initialize a page in an
undo log */
-#define MLOG_UNDO_HDR_DISCARD ((byte)23) /* discard an update undo log
+#define MLOG_UNDO_HDR_DISCARD ((byte)23) /*!< discard an update undo log
header */
-#define MLOG_UNDO_HDR_REUSE ((byte)24) /* reuse an insert undo log
+#define MLOG_UNDO_HDR_REUSE ((byte)24) /*!< reuse an insert undo log
header */
-#define MLOG_UNDO_HDR_CREATE ((byte)25) /* create an undo log header */
-#define MLOG_REC_MIN_MARK ((byte)26) /* mark an index record as the
- predefined minimum record */
-#define MLOG_IBUF_BITMAP_INIT ((byte)27) /* initialize an ibuf bitmap
- page */
+#define MLOG_UNDO_HDR_CREATE ((byte)25) /*!< create an undo
+ log header */
+#define MLOG_REC_MIN_MARK ((byte)26) /*!< mark an index
+ record as the
+ predefined minimum
+ record */
+#define MLOG_IBUF_BITMAP_INIT ((byte)27) /*!< initialize an
+ ibuf bitmap page */
/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */
-#define MLOG_INIT_FILE_PAGE ((byte)29) /* this means that a file page
- is taken into use and the prior
- contents of the page should be
- ignored: in recovery we must
- not trust the lsn values stored
- to the file page */
-#define MLOG_WRITE_STRING ((byte)30) /* write a string to a page */
-#define MLOG_MULTI_REC_END ((byte)31) /* if a single mtr writes
- log records for several pages,
+#ifdef UNIV_LOG_LSN_DEBUG
+# define MLOG_LSN ((byte)28) /* current LSN */
+#endif
+#define MLOG_INIT_FILE_PAGE ((byte)29) /*!< this means that a
+ file page is taken
+ into use and the prior
+ contents of the page
+ should be ignored: in
+ recovery we must not
+ trust the lsn values
+ stored to the file
+ page */
+#define MLOG_WRITE_STRING ((byte)30) /*!< write a string to
+ a page */
+#define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes
+ several log records,
this log record ends the
sequence of these records */
-#define MLOG_DUMMY_RECORD ((byte)32) /* dummy log record used to
+#define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to
pad a log block full */
-#define MLOG_FILE_CREATE ((byte)33) /* log record about an .ibd
+#define MLOG_FILE_CREATE ((byte)33) /*!< log record about an .ibd
file creation */
-#define MLOG_FILE_RENAME ((byte)34) /* log record about an .ibd
+#define MLOG_FILE_RENAME ((byte)34) /*!< log record about an .ibd
file rename */
-#define MLOG_FILE_DELETE ((byte)35) /* log record about an .ibd
+#define MLOG_FILE_DELETE ((byte)35) /*!< log record about an .ibd
file deletion */
-#define MLOG_COMP_REC_MIN_MARK ((byte)36) /* mark a compact index record
- as the predefined minimum
+#define MLOG_COMP_REC_MIN_MARK ((byte)36) /*!< mark a compact
+ index record as the
+ predefined minimum
record */
-#define MLOG_COMP_PAGE_CREATE ((byte)37) /* create a compact
+#define MLOG_COMP_PAGE_CREATE ((byte)37) /*!< create a compact
index page */
-#define MLOG_COMP_REC_INSERT ((byte)38) /* compact record insert */
+#define MLOG_COMP_REC_INSERT ((byte)38) /*!< compact record insert */
#define MLOG_COMP_REC_CLUST_DELETE_MARK ((byte)39)
- /* mark compact clustered index
- record deleted */
-#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/* mark compact secondary index
- record deleted; this log
- record type is redundant, as
- MLOG_REC_SEC_DELETE_MARK is
- independent of the record
- format. */
-#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/* update of a compact record,
- preserves record field sizes */
-#define MLOG_COMP_REC_DELETE ((byte)42) /* delete a compact record
+ /*!< mark compact
+ clustered index record
+ deleted */
+#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/*!< mark compact
+ secondary index record
+ deleted; this log
+ record type is
+ redundant, as
+ MLOG_REC_SEC_DELETE_MARK
+ is independent of the
+ record format. */
+#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/*!< update of a
+ compact record,
+ preserves record field
+ sizes */
+#define MLOG_COMP_REC_DELETE ((byte)42) /*!< delete a compact record
from a page */
-#define MLOG_COMP_LIST_END_DELETE ((byte)43) /* delete compact record list
+#define MLOG_COMP_LIST_END_DELETE ((byte)43) /*!< delete compact record list
end on index page */
-#define MLOG_COMP_LIST_START_DELETE ((byte)44) /* delete compact record list
+#define MLOG_COMP_LIST_START_DELETE ((byte)44) /*!< delete compact record list
start on index page */
#define MLOG_COMP_LIST_END_COPY_CREATED ((byte)45)
- /* copy compact record list end
- to a new created index page */
-#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /* reorganize an index page */
-#define MLOG_FILE_CREATE2 ((byte)47) /* log record about creating
+ /*!< copy compact
+ record list end to a
+ new created index
+ page */
+#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /*!< reorganize an index page */
+#define MLOG_FILE_CREATE2 ((byte)47) /*!< log record about creating
an .ibd file, with format */
-#define MLOG_ZIP_WRITE_NODE_PTR ((byte)48) /* write the node pointer of
+#define MLOG_ZIP_WRITE_NODE_PTR ((byte)48) /*!< write the node pointer of
a record on a compressed
non-leaf B-tree page */
-#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)49) /* write the BLOB pointer
+#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)49) /*!< write the BLOB pointer
of an externally stored column
on a compressed page */
-#define MLOG_ZIP_WRITE_HEADER ((byte)50) /* write to compressed page
+#define MLOG_ZIP_WRITE_HEADER ((byte)50) /*!< write to compressed page
header */
-#define MLOG_ZIP_PAGE_COMPRESS ((byte)51) /* compress an index page */
-#define MLOG_BIGGEST_TYPE ((byte)51) /* biggest value (used in
- asserts) */
+#define MLOG_ZIP_PAGE_COMPRESS ((byte)51) /*!< compress an index page */
+#define MLOG_BIGGEST_TYPE ((byte)51) /*!< biggest value (used in
+ assertions) */
+/* @} */
+
+/** @name Flags for MLOG_FILE operations
+(stored in the page number parameter, called log_flags in the
+functions). The page number parameter was originally written as 0. @{ */
+#define MLOG_FILE_FLAG_TEMP 1 /*!< identifies TEMPORARY TABLE in
+ MLOG_FILE_CREATE, MLOG_FILE_CREATE2 */
+/* @} */
-/*******************************************************************
+/***************************************************************//**
Starts a mini-transaction and creates a mini-transaction handle
-and buffer in the memory buffer given by the caller. */
+and buffer in the memory buffer given by the caller.
+@return mtr buffer which also acts as the mtr handle */
UNIV_INLINE
mtr_t*
mtr_start(
/*======*/
- /* out: mtr buffer which also acts as
- the mtr handle */
- mtr_t* mtr); /* in: memory buffer for the mtr buffer */
-/*******************************************************************
+ mtr_t* mtr); /*!< in: memory buffer for the mtr buffer */
+/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
void
mtr_commit(
/*=======*/
- mtr_t* mtr); /* in: mini-transaction */
-/**************************************************************
-Sets and returns a savepoint in mtr. */
+ mtr_t* mtr); /*!< in: mini-transaction */
+/**********************************************************//**
+Sets and returns a savepoint in mtr.
+@return savepoint */
UNIV_INLINE
ulint
mtr_set_savepoint(
/*==============*/
- /* out: savepoint */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************//**
Releases the latches stored in an mtr memo down to a savepoint.
NOTE! The mtr must not have made changes to buffer pages after the
savepoint, as these can be handled only by mtr_commit. */
@@ -193,161 +221,172 @@ UNIV_INTERN
void
mtr_rollback_to_savepoint(
/*======================*/
- mtr_t* mtr, /* in: mtr */
- ulint savepoint); /* in: savepoint */
-/**************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ ulint savepoint); /*!< in: savepoint */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Releases the (index tree) s-latch stored in an mtr memo after a
savepoint. */
UNIV_INLINE
void
mtr_release_s_latch_at_savepoint(
/*=============================*/
- mtr_t* mtr, /* in: mtr */
- ulint savepoint, /* in: savepoint */
- rw_lock_t* lock); /* in: latch to release */
-/*******************************************************************
-Gets the logging mode of a mini-transaction. */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint savepoint, /*!< in: savepoint */
+ rw_lock_t* lock); /*!< in: latch to release */
+#else /* !UNIV_HOTBACKUP */
+# define mtr_release_s_latch_at_savepoint(mtr,savepoint,lock) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
+/***************************************************************//**
+Gets the logging mode of a mini-transaction.
+@return logging mode: MTR_LOG_NONE, ... */
UNIV_INLINE
ulint
mtr_get_log_mode(
/*=============*/
- /* out: logging mode: MTR_LOG_NONE, ... */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
-Changes the logging mode of a mini-transaction. */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
+Changes the logging mode of a mini-transaction.
+@return old mode */
UNIV_INLINE
ulint
mtr_set_log_mode(
/*=============*/
- /* out: old mode */
- mtr_t* mtr, /* in: mtr */
- ulint mode); /* in: logging mode: MTR_LOG_NONE, ... */
-/************************************************************
-Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint mode); /*!< in: logging mode: MTR_LOG_NONE, ... */
+/********************************************************//**
+Reads 1 - 4 bytes from a file page buffered in the buffer pool.
+@return value read */
UNIV_INTERN
ulint
mtr_read_ulint(
/*===========*/
- /* out: value read */
- const byte* ptr, /* in: pointer from where to read */
- ulint type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
-Reads 8 bytes from a file page buffered in the buffer pool. */
+ const byte* ptr, /*!< in: pointer from where to read */
+ ulint type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
+Reads 8 bytes from a file page buffered in the buffer pool.
+@return value read */
UNIV_INTERN
dulint
mtr_read_dulint(
/*============*/
- /* out: value read */
- const byte* ptr, /* in: pointer from where to read */
- mtr_t* mtr); /* in: mini-transaction handle */
-/*************************************************************************
+ const byte* ptr, /*!< in: pointer from where to read */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
This macro locks an rw-lock in s-mode. */
#define mtr_s_lock(B, MTR) mtr_s_lock_func((B), __FILE__, __LINE__,\
(MTR))
-/*************************************************************************
+/*********************************************************************//**
This macro locks an rw-lock in x-mode. */
#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), __FILE__, __LINE__,\
(MTR))
-/*************************************************************************
+/*********************************************************************//**
NOTE! Use the macro above!
Locks a lock in s-mode. */
UNIV_INLINE
void
mtr_s_lock_func(
/*============*/
- rw_lock_t* lock, /* in: rw-lock */
- const char* file, /* in: file name */
- ulint line, /* in: line number */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************************
+ rw_lock_t* lock, /*!< in: rw-lock */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line number */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************************//**
NOTE! Use the macro above!
Locks a lock in x-mode. */
UNIV_INLINE
void
mtr_x_lock_func(
/*============*/
- rw_lock_t* lock, /* in: rw-lock */
- const char* file, /* in: file name */
- ulint line, /* in: line number */
- mtr_t* mtr); /* in: mtr */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line number */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************
+/***************************************************//**
Releases an object in the memo stack. */
UNIV_INTERN
void
mtr_memo_release(
/*=============*/
- mtr_t* mtr, /* in: mtr */
- void* object, /* in: object */
- ulint type); /* in: object type: MTR_MEMO_S_LOCK, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ void* object, /*!< in: object */
+ ulint type); /*!< in: object type: MTR_MEMO_S_LOCK, ... */
#ifdef UNIV_DEBUG
-/**************************************************************
-Checks if memo contains the given item. */
+# ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Checks if memo contains the given item.
+@return TRUE if contains */
UNIV_INLINE
ibool
mtr_memo_contains(
/*==============*/
- /* out: TRUE if contains */
- mtr_t* mtr, /* in: mtr */
- const void* object, /* in: object to search */
- ulint type); /* in: type of object */
+ mtr_t* mtr, /*!< in: mtr */
+ const void* object, /*!< in: object to search */
+ ulint type); /*!< in: type of object */
-/**************************************************************
-Checks if memo contains the given page. */
+/**********************************************************//**
+Checks if memo contains the given page.
+@return TRUE if contains */
UNIV_INTERN
ibool
mtr_memo_contains_page(
/*===================*/
- /* out: TRUE if contains */
- mtr_t* mtr, /* in: mtr */
- const byte* ptr, /* in: pointer to buffer frame */
- ulint type); /* in: type of object */
-/*************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* ptr, /*!< in: pointer to buffer frame */
+ ulint type); /*!< in: type of object */
+/*********************************************************//**
Prints info of an mtr handle. */
UNIV_INTERN
void
mtr_print(
/*======*/
- mtr_t* mtr); /* in: mtr */
+ mtr_t* mtr); /*!< in: mtr */
+# else /* !UNIV_HOTBACKUP */
+# define mtr_memo_contains(mtr, object, type) TRUE
+# define mtr_memo_contains_page(mtr, ptr, type) TRUE
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
/*######################################################################*/
#define MTR_BUF_MEMO_SIZE 200 /* number of slots in memo */
-/*******************************************************************
-Returns the log object of a mini-transaction buffer. */
+/***************************************************************//**
+Returns the log object of a mini-transaction buffer.
+@return log */
UNIV_INLINE
dyn_array_t*
mtr_get_log(
/*========*/
- /* out: log */
- mtr_t* mtr); /* in: mini-transaction */
-/*******************************************************
+ mtr_t* mtr); /*!< in: mini-transaction */
+/***************************************************//**
Pushes an object to an mtr memo stack. */
UNIV_INLINE
void
mtr_memo_push(
/*==========*/
- mtr_t* mtr, /* in: mtr */
- void* object, /* in: object */
- ulint type); /* in: object type: MTR_MEMO_S_LOCK, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ void* object, /*!< in: object */
+ ulint type); /*!< in: object type: MTR_MEMO_S_LOCK, ... */
/* Type definition of a mini-transaction memo stack slot. */
typedef struct mtr_memo_slot_struct mtr_memo_slot_t;
struct mtr_memo_slot_struct{
- ulint type; /* type of the stored object (MTR_MEMO_S_LOCK, ...) */
- void* object; /* pointer to the object */
+ ulint type; /*!< type of the stored object (MTR_MEMO_S_LOCK, ...) */
+ void* object; /*!< pointer to the object */
};
/* Mini-transaction handle and buffer */
struct mtr_struct{
#ifdef UNIV_DEBUG
- ulint state; /* MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */
+ ulint state; /*!< MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */
#endif
- dyn_array_t memo; /* memo stack for locks etc. */
- dyn_array_t log; /* mini-transaction log */
+ dyn_array_t memo; /*!< memo stack for locks etc. */
+ dyn_array_t log; /*!< mini-transaction log */
ibool modifications;
/* TRUE if the mtr made modifications to
buffer pool pages */
diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic
index 7d6d99917b7..310c7c4117f 100644
--- a/storage/xtradb/include/mtr0mtr.ic
+++ b/storage/xtradb/include/mtr0mtr.ic
@@ -16,26 +16,28 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0mtr.ic
Mini-transaction buffer
Created 11/26/1995 Heikki Tuuri
*******************************************************/
-#include "sync0sync.h"
-#include "sync0rw.h"
+#ifndef UNIV_HOTBACKUP
+# include "sync0sync.h"
+# include "sync0rw.h"
+#endif /* !UNIV_HOTBACKUP */
#include "mach0data.h"
-/*******************************************************************
+/***************************************************************//**
Starts a mini-transaction and creates a mini-transaction handle
-and a buffer in the memory buffer given by the caller. */
+and a buffer in the memory buffer given by the caller.
+@return mtr buffer which also acts as the mtr handle */
UNIV_INLINE
mtr_t*
mtr_start(
/*======*/
- /* out: mtr buffer which also acts as
- the mtr handle */
- mtr_t* mtr) /* in: memory buffer for the mtr buffer */
+ mtr_t* mtr) /*!< in: memory buffer for the mtr buffer */
{
dyn_array_create(&(mtr->memo));
dyn_array_create(&(mtr->log));
@@ -50,15 +52,15 @@ mtr_start(
return(mtr);
}
-/*******************************************************
+/***************************************************//**
Pushes an object to an mtr memo stack. */
UNIV_INLINE
void
mtr_memo_push(
/*==========*/
- mtr_t* mtr, /* in: mtr */
- void* object, /* in: object */
- ulint type) /* in: object type: MTR_MEMO_S_LOCK, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ void* object, /*!< in: object */
+ ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */
{
dyn_array_t* memo;
mtr_memo_slot_t* slot;
@@ -77,14 +79,14 @@ mtr_memo_push(
slot->type = type;
}
-/**************************************************************
-Sets and returns a savepoint in mtr. */
+/**********************************************************//**
+Sets and returns a savepoint in mtr.
+@return savepoint */
UNIV_INLINE
ulint
mtr_set_savepoint(
/*==============*/
- /* out: savepoint */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dyn_array_t* memo;
@@ -96,16 +98,17 @@ mtr_set_savepoint(
return(dyn_array_get_data_size(memo));
}
-/**************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Releases the (index tree) s-latch stored in an mtr memo after a
savepoint. */
UNIV_INLINE
void
mtr_release_s_latch_at_savepoint(
/*=============================*/
- mtr_t* mtr, /* in: mtr */
- ulint savepoint, /* in: savepoint */
- rw_lock_t* lock) /* in: latch to release */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint savepoint, /*!< in: savepoint */
+ rw_lock_t* lock) /*!< in: latch to release */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -128,17 +131,17 @@ mtr_release_s_latch_at_savepoint(
slot->object = NULL;
}
-#ifdef UNIV_DEBUG
-/**************************************************************
-Checks if memo contains the given item. */
+# ifdef UNIV_DEBUG
+/**********************************************************//**
+Checks if memo contains the given item.
+@return TRUE if contains */
UNIV_INLINE
ibool
mtr_memo_contains(
/*==============*/
- /* out: TRUE if contains */
- mtr_t* mtr, /* in: mtr */
- const void* object, /* in: object to search */
- ulint type) /* in: type of object */
+ mtr_t* mtr, /*!< in: mtr */
+ const void* object, /*!< in: object to search */
+ ulint type) /*!< in: type of object */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -164,16 +167,17 @@ mtr_memo_contains(
return(FALSE);
}
-#endif /* UNIV_DEBUG */
+# endif /* UNIV_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
-Returns the log object of a mini-transaction buffer. */
+/***************************************************************//**
+Returns the log object of a mini-transaction buffer.
+@return log */
UNIV_INLINE
dyn_array_t*
mtr_get_log(
/*========*/
- /* out: log */
- mtr_t* mtr) /* in: mini-transaction */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
@@ -181,14 +185,14 @@ mtr_get_log(
return(&(mtr->log));
}
-/*******************************************************************
-Gets the logging mode of a mini-transaction. */
+/***************************************************************//**
+Gets the logging mode of a mini-transaction.
+@return logging mode: MTR_LOG_NONE, ... */
UNIV_INLINE
ulint
mtr_get_log_mode(
/*=============*/
- /* out: logging mode: MTR_LOG_NONE, ... */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(mtr->log_mode >= MTR_LOG_ALL);
@@ -197,15 +201,15 @@ mtr_get_log_mode(
return(mtr->log_mode);
}
-/*******************************************************************
-Changes the logging mode of a mini-transaction. */
+/***************************************************************//**
+Changes the logging mode of a mini-transaction.
+@return old mode */
UNIV_INLINE
ulint
mtr_set_log_mode(
/*=============*/
- /* out: old mode */
- mtr_t* mtr, /* in: mtr */
- ulint mode) /* in: logging mode: MTR_LOG_NONE, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint mode) /*!< in: logging mode: MTR_LOG_NONE, ... */
{
ulint old_mode;
@@ -227,16 +231,17 @@ mtr_set_log_mode(
return(old_mode);
}
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Locks a lock in s-mode. */
UNIV_INLINE
void
mtr_s_lock_func(
/*============*/
- rw_lock_t* lock, /* in: rw-lock */
- const char* file, /* in: file name */
- ulint line, /* in: line number */
- mtr_t* mtr) /* in: mtr */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line number */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(lock);
@@ -246,16 +251,16 @@ mtr_s_lock_func(
mtr_memo_push(mtr, lock, MTR_MEMO_S_LOCK);
}
-/*************************************************************************
+/*********************************************************************//**
Locks a lock in x-mode. */
UNIV_INLINE
void
mtr_x_lock_func(
/*============*/
- rw_lock_t* lock, /* in: rw-lock */
- const char* file, /* in: file name */
- ulint line, /* in: line number */
- mtr_t* mtr) /* in: mtr */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line number */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(lock);
@@ -264,3 +269,4 @@ mtr_x_lock_func(
mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/mtr0types.h b/storage/xtradb/include/mtr0types.h
index 23634c98827..83a7aaf3839 100644
--- a/storage/xtradb/include/mtr0types.h
+++ b/storage/xtradb/include/mtr0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0types.h
Mini-transaction buffer global types
Created 11/26/1995 Heikki Tuuri
diff --git a/storage/xtradb/include/mysql_addons.h b/storage/xtradb/include/mysql_addons.h
index 2e8c87f5962..17660c18710 100644
--- a/storage/xtradb/include/mysql_addons.h
+++ b/storage/xtradb/include/mysql_addons.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mysql_addons.h
This file contains functions that need to be added to
MySQL code but have not been added yet.
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index 26897226ff4..3eff5216867 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -15,8 +15,35 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free 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
+
+***********************************************************************/
+
+/**************************************************//**
+@file include/os0file.h
The interface to the operating system file io
Created 10/21/1995 Heikki Tuuri
@@ -26,6 +53,7 @@ Created 10/21/1995 Heikki Tuuri
#define os0file_h
#include "univ.i"
+#include "trx0types.h"
#ifndef __WIN__
#include <dirent.h>
@@ -33,49 +61,63 @@ Created 10/21/1995 Heikki Tuuri
#include <time.h>
#endif
+/** File node of a tablespace or the log data space */
typedef struct fil_node_struct fil_node_t;
#ifdef UNIV_DO_FLUSH
extern ibool os_do_not_call_flush_at_each_write;
#endif /* UNIV_DO_FLUSH */
extern ibool os_has_said_disk_full;
+/** Flag: enable debug printout for asynchronous i/o */
extern ibool os_aio_print_debug;
+/** Number of pending os_file_pread() operations */
extern ulint os_file_n_pending_preads;
+/** Number of pending os_file_pwrite() operations */
extern ulint os_file_n_pending_pwrites;
+/** Number of pending read operations */
extern ulint os_n_pending_reads;
+/** Number of pending write operations */
extern ulint os_n_pending_writes;
#ifdef __WIN__
-/* We define always WIN_ASYNC_IO, and check at run-time whether
+/** We define always WIN_ASYNC_IO, and check at run-time whether
the OS actually supports it: Win 95 does not, NT does. */
#define WIN_ASYNC_IO
+/** Use unbuffered I/O */
#define UNIV_NON_BUFFERED_IO
#endif
#ifdef __WIN__
+/** File handle */
#define os_file_t HANDLE
+/** Convert a C file descriptor to a native file handle
+@param fd file descriptor
+@return native file handle */
#define OS_FILE_FROM_FD(fd) (HANDLE) _get_osfhandle(fd)
#else
+/** File handle */
typedef int os_file_t;
+/** Convert a C file descriptor to a native file handle
+@param fd file descriptor
+@return native file handle */
#define OS_FILE_FROM_FD(fd) fd
#endif
+/** Umask for creating files */
extern ulint os_innodb_umask;
-/* If this flag is TRUE, then we will use the native aio of the
+/** If this flag is TRUE, then we will use the native aio of the
OS (provided we compiled Innobase with it in), otherwise we will
use simulated aio we build below with threads */
extern ibool os_aio_use_native_aio;
-#define OS_FILE_SECTOR_SIZE 512
-
-/* The next value should be smaller or equal to the smallest sector size used
+/** The next value should be smaller or equal to the smallest sector size used
on any disk. A log block is required to be a portion of disk which is written
so that if the start and the end of a block get written to disk, then the
whole block gets written. This should be true even in most cases of a crash:
@@ -84,7 +126,7 @@ log. */
#define OS_FILE_LOG_BLOCK_SIZE 512
-/* Options for file_create */
+/** Options for file_create @{ */
#define OS_FILE_OPEN 51
#define OS_FILE_CREATE 52
#define OS_FILE_OVERWRITE 53
@@ -100,12 +142,14 @@ log. */
/* Options for file_create */
#define OS_FILE_AIO 61
#define OS_FILE_NORMAL 62
+/* @} */
-/* Types for file create */
+/** Types for file create @{ */
#define OS_DATA_FILE 100
#define OS_LOG_FILE 101
+/* @} */
-/* Error codes from os_file_get_last_error */
+/** Error codes from os_file_get_last_error @{ */
#define OS_FILE_NOT_FOUND 71
#define OS_FILE_DISK_FULL 72
#define OS_FILE_ALREADY_EXISTS 73
@@ -114,23 +158,27 @@ log. */
to become available again */
#define OS_FILE_SHARING_VIOLATION 76
#define OS_FILE_ERROR_NOT_SPECIFIED 77
+#define OS_FILE_INSUFFICIENT_RESOURCE 78
+#define OS_FILE_OPERATION_ABORTED 79
+/* @} */
-/* Types for aio operations */
+/** Types for aio operations @{ */
#define OS_FILE_READ 10
#define OS_FILE_WRITE 11
#define OS_FILE_LOG 256 /* This can be ORed to type */
+/* @} */
-#define OS_AIO_N_PENDING_IOS_PER_THREAD 32 /* Win NT does not allow more
+#define OS_AIO_N_PENDING_IOS_PER_THREAD 32 /*!< Win NT does not allow more
than 64 */
-/* Modes for aio operations */
-#define OS_AIO_NORMAL 21 /* Normal asynchronous i/o not for ibuf
+/** Modes for aio operations @{ */
+#define OS_AIO_NORMAL 21 /*!< Normal asynchronous i/o not for ibuf
pages or ibuf bitmap pages */
-#define OS_AIO_IBUF 22 /* Asynchronous i/o for ibuf pages or ibuf
+#define OS_AIO_IBUF 22 /*!< Asynchronous i/o for ibuf pages or ibuf
bitmap pages */
-#define OS_AIO_LOG 23 /* Asynchronous i/o for the log */
-#define OS_AIO_SYNC 24 /* Asynchronous i/o where the calling thread
+#define OS_AIO_LOG 23 /*!< Asynchronous i/o for the log */
+#define OS_AIO_SYNC 24 /*!< Asynchronous i/o where the calling thread
will itself wait for the i/o to complete,
doing also the job of the i/o-handler thread;
can be used for any pages, ibuf or non-ibuf.
@@ -140,16 +188,18 @@ log. */
the file seek and read or write, causing a
bottleneck for parallelism. */
-#define OS_AIO_SIMULATED_WAKE_LATER 512 /* This can be ORed to mode
+#define OS_AIO_SIMULATED_WAKE_LATER 512 /*!< This can be ORed to mode
in the call of os_aio(...),
if the caller wants to post several i/o
requests in a batch, and only after that
wake the i/o-handler thread; this has
effect only in simulated aio */
-#define OS_WIN31 1
-#define OS_WIN95 2
-#define OS_WINNT 3
-#define OS_WIN2000 4
+/* @} */
+
+#define OS_WIN31 1 /*!< Microsoft Windows 3.x */
+#define OS_WIN95 2 /*!< Microsoft Windows 95 */
+#define OS_WINNT 3 /*!< Microsoft Windows NT 3.x */
+#define OS_WIN2000 4 /*!< Microsoft Windows 2000 */
extern ulint os_n_file_reads;
extern ulint os_n_file_writes;
@@ -173,161 +223,157 @@ bigger than 4000 bytes */
/* Struct used in fetching information of a file in a directory */
struct os_file_stat_struct{
- char name[OS_FILE_MAX_PATH]; /* path to a file */
- os_file_type_t type; /* file type */
- ib_int64_t size; /* file size */
- time_t ctime; /* creation time */
- time_t mtime; /* modification time */
- time_t atime; /* access time */
+ char name[OS_FILE_MAX_PATH]; /*!< path to a file */
+ os_file_type_t type; /*!< file type */
+ ib_int64_t size; /*!< file size */
+ time_t ctime; /*!< creation time */
+ time_t mtime; /*!< modification time */
+ time_t atime; /*!< access time */
};
typedef struct os_file_stat_struct os_file_stat_t;
#ifdef __WIN__
-typedef HANDLE os_file_dir_t; /* directory stream */
+typedef HANDLE os_file_dir_t; /*!< directory stream */
#else
-typedef DIR* os_file_dir_t; /* directory stream */
+typedef DIR* os_file_dir_t; /*!< directory stream */
#endif
-/***************************************************************************
-Gets the operating system version. Currently works only on Windows. */
+/***********************************************************************//**
+Gets the operating system version. Currently works only on Windows.
+@return OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */
UNIV_INTERN
ulint
os_get_os_version(void);
/*===================*/
- /* out: OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */
-/********************************************************************
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Creates the seek mutexes used in positioned reads and writes. */
UNIV_INTERN
void
os_io_init_simple(void);
/*===================*/
-/***************************************************************************
+/***********************************************************************//**
Creates a temporary file. This function is like tmpfile(3), but
the temporary file is created in the MySQL temporary directory.
On Netware, this function is like tmpfile(3), because the C run-time
-library of Netware does not expose the delete-on-close flag. */
+library of Netware does not expose the delete-on-close flag.
+@return temporary file handle, or NULL on error */
FILE*
os_file_create_tmpfile(void);
/*========================*/
- /* out: temporary file handle, or NULL on error */
-/***************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************************//**
The os_file_opendir() function opens a directory stream corresponding to the
directory named by the dirname argument. The directory stream is positioned
at the first entry. In both Unix and Windows we automatically skip the '.'
-and '..' items at the start of the directory listing. */
+and '..' items at the start of the directory listing.
+@return directory stream, NULL if error */
UNIV_INTERN
os_file_dir_t
os_file_opendir(
/*============*/
- /* out: directory stream, NULL if
- error */
- const char* dirname, /* in: directory name; it must not
+ const char* dirname, /*!< in: directory name; it must not
contain a trailing '\' or '/' */
- ibool error_is_fatal);/* in: TRUE if we should treat an
+ ibool error_is_fatal);/*!< in: TRUE if we should treat an
error as a fatal error; if we try to
open symlinks then we do not wish a
fatal error if it happens not to be
a directory */
-/***************************************************************************
-Closes a directory stream. */
+/***********************************************************************//**
+Closes a directory stream.
+@return 0 if success, -1 if failure */
UNIV_INTERN
int
os_file_closedir(
/*=============*/
- /* out: 0 if success, -1 if failure */
- os_file_dir_t dir); /* in: directory stream */
-/***************************************************************************
+ os_file_dir_t dir); /*!< in: directory stream */
+/***********************************************************************//**
This function returns information of the next file in the directory. We jump
-over the '.' and '..' entries in the directory. */
+over the '.' and '..' entries in the directory.
+@return 0 if ok, -1 if error, 1 if at the end of the directory */
UNIV_INTERN
int
os_file_readdir_next_file(
/*======================*/
- /* out: 0 if ok, -1 if error, 1 if at the end
- of the directory */
- const char* dirname,/* in: directory name or path */
- os_file_dir_t dir, /* in: directory stream */
- os_file_stat_t* info); /* in/out: buffer where the info is returned */
-/*********************************************************************
+ const char* dirname,/*!< in: directory name or path */
+ os_file_dir_t dir, /*!< in: directory stream */
+ os_file_stat_t* info); /*!< in/out: buffer where the info is returned */
+/*****************************************************************//**
This function attempts to create a directory named pathname. The new directory
gets default permissions. On Unix, the permissions are (0770 & ~umask). If the
directory exists already, nothing is done and the call succeeds, unless the
-fail_if_exists arguments is true. */
+fail_if_exists arguments is true.
+@return TRUE if call succeeds, FALSE on error */
UNIV_INTERN
ibool
os_file_create_directory(
/*=====================*/
- /* out: TRUE if call succeeds,
- FALSE on error */
- const char* pathname, /* in: directory name as
+ const char* pathname, /*!< in: directory name as
null-terminated string */
- ibool fail_if_exists);/* in: if TRUE, pre-existing directory
+ ibool fail_if_exists);/*!< in: if TRUE, pre-existing directory
is treated as an error. */
-/********************************************************************
-A simple function to open or create a file. */
+/****************************************************************//**
+A simple function to open or create a file.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create_simple(
/*==================*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file is
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file is
opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error), or
OS_FILE_CREATE_PATH if new file
(if exists, error) and subdirectories along
its path are created (if needed)*/
- ulint access_type,/* in: OS_FILE_READ_ONLY or
+ ulint access_type,/*!< in: OS_FILE_READ_ONLY or
OS_FILE_READ_WRITE */
- ibool* success);/* out: TRUE if succeed, FALSE if error */
-/********************************************************************
-A simple function to open or create a file. */
+ ibool* success);/*!< out: TRUE if succeed, FALSE if error */
+/****************************************************************//**
+A simple function to open or create a file.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create_simple_no_error_handling(
/*====================================*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file
is opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error) */
- ulint access_type,/* in: OS_FILE_READ_ONLY,
+ ulint access_type,/*!< in: OS_FILE_READ_ONLY,
OS_FILE_READ_WRITE, or
OS_FILE_READ_ALLOW_DELETE; the last option is
used by a backup program reading the file */
- ibool* success);/* out: TRUE if succeed, FALSE if error */
-/********************************************************************
+ ibool* success);/*!< out: TRUE if succeed, FALSE if error */
+/****************************************************************//**
Tries to disable OS caching on an opened file descriptor. */
UNIV_INTERN
void
os_file_set_nocache(
/*================*/
- int fd, /* in: file descriptor to alter */
- const char* file_name, /* in: file name, used in the
+ int fd, /*!< in: file descriptor to alter */
+ const char* file_name, /*!< in: file name, used in the
diagnostic message */
- const char* operation_name);/* in: "open" or "create"; used in the
+ const char* operation_name);/*!< in: "open" or "create"; used in the
diagnostic message */
-/********************************************************************
-Opens an existing file or creates a new. */
+/****************************************************************//**
+Opens an existing file or creates a new.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create(
/*===========*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file
is opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error),
@@ -335,137 +381,141 @@ os_file_create(
or an old overwritten;
OS_FILE_OPEN_RAW, if a raw device or disk
partition should be opened */
- ulint purpose,/* in: OS_FILE_AIO, if asynchronous,
+ ulint purpose,/*!< in: OS_FILE_AIO, if asynchronous,
non-buffered i/o is desired,
OS_FILE_NORMAL, if any normal file;
NOTE that it also depends on type, os_aio_..
and srv_.. variables whether we really use
async i/o or unbuffered i/o: look in the
function source code for the exact rules */
- ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */
- ibool* success);/* out: TRUE if succeed, FALSE if error */
-/***************************************************************************
-Deletes a file. The file has to be closed before calling this. */
+ ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */
+ ibool* success);/*!< out: TRUE if succeed, FALSE if error */
+/***********************************************************************//**
+Deletes a file. The file has to be closed before calling this.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_delete(
/*===========*/
- /* out: TRUE if success */
- const char* name); /* in: file path as a null-terminated string */
+ const char* name); /*!< in: file path as a null-terminated string */
-/***************************************************************************
-Deletes a file if it exists. The file has to be closed before calling this. */
+/***********************************************************************//**
+Deletes a file if it exists. The file has to be closed before calling this.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_delete_if_exists(
/*=====================*/
- /* out: TRUE if success */
- const char* name); /* in: file path as a null-terminated string */
-/***************************************************************************
+ const char* name); /*!< in: file path as a null-terminated string */
+/***********************************************************************//**
Renames a file (can also move it to another directory). It is safest that the
-file is closed before calling this function. */
+file is closed before calling this function.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_rename(
/*===========*/
- /* out: TRUE if success */
- const char* oldpath, /* in: old file path as a
+ const char* oldpath, /*!< in: old file path as a
null-terminated string */
- const char* newpath); /* in: new file path */
-/***************************************************************************
+ const char* newpath); /*!< in: new file path */
+/***********************************************************************//**
Closes a file handle. In case of error, error number can be retrieved with
-os_file_get_last_error. */
+os_file_get_last_error.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_close(
/*==========*/
- /* out: TRUE if success */
- os_file_t file); /* in, own: handle to a file */
-/***************************************************************************
-Closes a file handle. */
+ os_file_t file); /*!< in, own: handle to a file */
+#ifdef UNIV_HOTBACKUP
+/***********************************************************************//**
+Closes a file handle.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_close_no_error_handling(
/*============================*/
- /* out: TRUE if success */
- os_file_t file); /* in, own: handle to a file */
-/***************************************************************************
-Gets a file size. */
+ os_file_t file); /*!< in, own: handle to a file */
+#endif /* UNIV_HOTBACKUP */
+/***********************************************************************//**
+Gets a file size.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_get_size(
/*=============*/
- /* out: TRUE if success */
- os_file_t file, /* in: handle to a file */
- ulint* size, /* out: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ ulint* size, /*!< out: least significant 32 bits of file
size */
- ulint* size_high);/* out: most significant 32 bits of size */
-/***************************************************************************
-Gets file size as a 64-bit integer ib_int64_t. */
+ ulint* size_high);/*!< out: most significant 32 bits of size */
+/***********************************************************************//**
+Gets file size as a 64-bit integer ib_int64_t.
+@return size in bytes, -1 if error */
UNIV_INTERN
ib_int64_t
os_file_get_size_as_iblonglong(
/*===========================*/
- /* out: size in bytes, -1 if error */
- os_file_t file); /* in: handle to a file */
-/***************************************************************************
-Write the specified number of zeros to a newly created file. */
+ os_file_t file); /*!< in: handle to a file */
+/***********************************************************************//**
+Write the specified number of zeros to a newly created file.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_set_size(
/*=============*/
- /* out: TRUE if success */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- ulint size, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ ulint size, /*!< in: least significant 32 bits of file
size */
- ulint size_high);/* in: most significant 32 bits of size */
-/***************************************************************************
-Truncates a file at its current position. */
+ ulint size_high);/*!< in: most significant 32 bits of size */
+/***********************************************************************//**
+Truncates a file at its current position.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_set_eof(
/*============*/
- /* out: TRUE if success */
- FILE* file); /* in: file to be truncated */
-/***************************************************************************
-Flushes the write buffers of a given file to the disk. */
+ FILE* file); /*!< in: file to be truncated */
+/***********************************************************************//**
+Flushes the write buffers of a given file to the disk.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_flush(
/*==========*/
- /* out: TRUE if success */
- os_file_t file); /* in, own: handle to a file */
-/***************************************************************************
+ os_file_t file); /*!< in, own: handle to a file */
+/***********************************************************************//**
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 + 100 is returned.
+@return error number, or OS error number + 100 */
UNIV_INTERN
ulint
os_file_get_last_error(
/*===================*/
- /* out: error number, or OS error
- number + 100 */
- ibool report_all_errors); /* in: TRUE if we want an error message
+ ibool report_all_errors); /*!< in: TRUE if we want an error message
printed of all errors */
-/***********************************************************************
-Requests a synchronous read operation. */
+/*******************************************************************//**
+Requests a synchronous read operation.
+@return TRUE if request was successful, FALSE if fail */
+#define os_file_read(file, buf, offset, offset_high, n) \
+ _os_file_read(file, buf, offset, offset_high, n, NULL)
+
UNIV_INTERN
ibool
-os_file_read(
+_os_file_read(
/*=========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read */
- ulint offset_high,/* in: most significant 32 bits of
+ ulint offset_high,/*!< in: most significant 32 bits of
offset */
- ulint n); /* in: number of bytes to read */
-/***********************************************************************
+ ulint n, /*!< in: number of bytes to read */
+ trx_t* trx);
+/*******************************************************************//**
Rewind file to its start, read at most size - 1 bytes from it to str, and
NUL-terminate str. All errors are silently ignored. This function is
mostly meant to be used with temporary files. */
@@ -473,54 +523,52 @@ UNIV_INTERN
void
os_file_read_string(
/*================*/
- FILE* file, /* in: file to read from */
- char* str, /* in: buffer where to read */
- ulint size); /* in: size of buffer */
-/***********************************************************************
+ FILE* file, /*!< in: file to read from */
+ char* str, /*!< in: buffer where to read */
+ ulint size); /*!< in: size of buffer */
+/*******************************************************************//**
Requests a synchronous positioned read operation. This function does not do
-any error handling. In case of error it returns FALSE. */
+any error handling. In case of error it returns FALSE.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_read_no_error_handling(
/*===========================*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read */
- ulint offset_high,/* in: most significant 32 bits of
+ ulint offset_high,/*!< in: most significant 32 bits of
offset */
- ulint n); /* in: number of bytes to read */
+ ulint n); /*!< in: number of bytes to read */
-/***********************************************************************
-Requests a synchronous write operation. */
+/*******************************************************************//**
+Requests a synchronous write operation.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_write(
/*==========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- const void* buf, /* in: buffer from which to write */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ const void* buf, /*!< in: buffer from which to write */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to write */
- ulint offset_high,/* in: most significant 32 bits of
+ ulint offset_high,/*!< in: most significant 32 bits of
offset */
- ulint n); /* in: number of bytes to write */
-/***********************************************************************
-Check the existence and type of the given file. */
+ ulint n); /*!< in: number of bytes to write */
+/*******************************************************************//**
+Check the existence and type of the given file.
+@return TRUE if call succeeded */
UNIV_INTERN
ibool
os_file_status(
/*===========*/
- /* out: TRUE if call succeeded */
- const char* path, /* in: pathname of the file */
- ibool* exists, /* out: TRUE if file exists */
- os_file_type_t* type); /* out: type of the file (if it exists) */
-/********************************************************************
+ const char* path, /*!< in: pathname of the file */
+ ibool* exists, /*!< out: TRUE if file exists */
+ os_file_type_t* type); /*!< out: type of the file (if it exists) */
+/****************************************************************//**
The function os_file_dirname returns a directory component of a
null-terminated pathname string. In the usual case, dirname returns
the string up to, but not including, the final '/', and basename
@@ -546,52 +594,54 @@ returned by dirname and basename for different paths:
"/" "/" "/"
"." "." "."
".." "." ".."
-*/
+
+@return own: directory component of the pathname */
UNIV_INTERN
char*
os_file_dirname(
/*============*/
- /* out, own: directory component of the
- pathname */
- const char* path); /* in: pathname */
-/********************************************************************
-Creates all missing subdirectories along the given path. */
+ const char* path); /*!< in: pathname */
+/****************************************************************//**
+Creates all missing subdirectories along the given path.
+@return TRUE if call succeeded FALSE otherwise */
UNIV_INTERN
ibool
os_file_create_subdirs_if_needed(
/*=============================*/
- /* out: TRUE if call succeeded
- FALSE otherwise */
- const char* path); /* in: path name */
-/****************************************************************************
-Initializes the asynchronous io system. Creates separate aio array for
-non-ibuf read and write, a third aio array for the ibuf i/o, with just one
-segment, two aio arrays for log reads and writes with one segment, and a
-synchronous aio array of the specified size. The combined number of segments
-in the three first aio arrays is the parameter n_segments given to the
-function. The caller must create an i/o handler thread for each segment in
-the four first arrays, but not for the sync aio array. */
+ const char* path); /*!< in: path name */
+/***********************************************************************
+Initializes the asynchronous io system. Creates one array each for ibuf
+and log i/o. Also creates one array each for read and write where each
+array is divided logically into n_read_segs and n_write_segs
+respectively. The caller must create an i/o handler thread for each
+segment in these arrays. This function also creates the sync array.
+No i/o handler thread needs to be created for that */
UNIV_INTERN
void
os_aio_init(
/*========*/
- ulint n, /* in: maximum number of pending aio operations
- allowed; n must be divisible by n_segments */
-// ulint n_segments, /* in: combined number of segments in the four
-// first aio arrays; must be >= 4 */
- ulint n_read_threads, /* n_segments == 2 + n_read_threads + n_write_threads */
- ulint n_write_threads, /**/
- ulint n_slots_sync); /* in: number of slots in the sync aio array */
+ ulint n_per_seg, /*<! in: maximum number of pending aio
+ operations allowed per segment */
+ ulint n_read_segs, /*<! in: number of reader threads */
+ ulint n_write_segs, /*<! in: number of writer threads */
+ ulint n_slots_sync); /*<! in: number of slots in the sync aio
+ array */
/***********************************************************************
-Requests an asynchronous i/o operation. */
+Frees the asynchronous io system. */
+UNIV_INTERN
+void
+os_aio_free(void);
+/*=============*/
+
+/*******************************************************************//**
+Requests an asynchronous i/o operation.
+@return TRUE if request was queued successfully, FALSE if fail */
UNIV_INTERN
ibool
os_aio(
/*===*/
- /* out: TRUE if request was queued
- successfully, FALSE if fail */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE */
- ulint mode, /* in: OS_AIO_NORMAL, ..., possibly ORed
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE */
+ ulint mode, /*!< in: OS_AIO_NORMAL, ..., possibly ORed
to OS_AIO_SIMULATED_WAKE_LATER: the
last flag advises this function not to wake
i/o-handler threads, but the caller will
@@ -604,42 +654,46 @@ os_aio(
because i/os are not actually handled until
all have been posted: use with great
caution! */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read or from which
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read or from which
to write */
- ulint offset, /* in: least significant 32 bits of file
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read or write */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n, /* in: number of bytes to read or write */
- fil_node_t* message1,/* in: messages for the aio handler (these
- can be used to identify a completed aio
- operation); if mode is OS_AIO_SYNC, these
- are ignored */
- void* message2);
-/****************************************************************************
+ ulint n, /*!< in: number of bytes to read or write */
+ fil_node_t* message1,/*!< in: message for the aio handler
+ (can be used to identify a completed
+ aio operation); ignored if mode is
+ OS_AIO_SYNC */
+ void* message2,/*!< in: message for the aio handler
+ (can be used to identify a completed
+ aio operation); ignored if mode is
+ OS_AIO_SYNC */
+ trx_t* trx);
+/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
UNIV_INTERN
void
os_aio_wake_all_threads_at_shutdown(void);
/*=====================================*/
-/****************************************************************************
+/************************************************************************//**
Waits until there are no pending writes in os_aio_write_array. There can
be other, synchronous, pending writes. */
UNIV_INTERN
void
os_aio_wait_until_no_pending_writes(void);
/*=====================================*/
-/**************************************************************************
+/**********************************************************************//**
Wakes up simulated aio i/o-handler threads if they have something to do. */
UNIV_INTERN
void
os_aio_simulated_wake_handler_threads(void);
/*=======================================*/
-/**************************************************************************
+/**********************************************************************//**
This function can be called if one wants to post a batch of reads and
prefers an i/o-handler thread to handle them all at once later. You must
call os_aio_simulated_wake_handler_threads later to ensure the threads
@@ -650,19 +704,19 @@ os_aio_simulated_put_read_threads_to_sleep(void);
/*============================================*/
#ifdef WIN_ASYNC_IO
-/**************************************************************************
+/**********************************************************************//**
This function is only used in Windows asynchronous i/o.
Waits for an aio operation to complete. This function is used to wait the
for completed requests. The aio array of pending requests is divided
into segments. The thread specifies which segment or slot it wants to wait
for. NOTE: this function will also take care of freeing the aio slot,
-therefore no other thread is allowed to do the freeing! */
+therefore no other thread is allowed to do the freeing!
+@return TRUE if the aio operation succeeded */
UNIV_INTERN
ibool
os_aio_windows_handle(
/*==================*/
- /* out: TRUE if the aio operation succeeded */
- ulint segment, /* in: the number of the segment in the aio
+ ulint segment, /*!< in: the number of the segment in the aio
arrays to wait for; segment 0 is the ibuf
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
@@ -670,52 +724,52 @@ os_aio_windows_handle(
this is ULINT_UNDEFINED, then it means that
sync aio is used, and this parameter is
ignored */
- ulint pos, /* this parameter is used only in sync aio:
+ ulint pos, /*!< this parameter is used only in sync aio:
wait for the aio slot at this position */
- fil_node_t**message1, /* out: the messages passed with the aio
+ fil_node_t**message1, /*!< out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
restart the operation, for example */
void** message2,
- ulint* type); /* out: OS_FILE_WRITE or ..._READ */
+ ulint* type); /*!< out: OS_FILE_WRITE or ..._READ */
#endif
-/**************************************************************************
+/**********************************************************************//**
Does simulated aio. This function should be called by an i/o-handler
-thread. */
+thread.
+@return TRUE if the aio operation succeeded */
UNIV_INTERN
ibool
os_aio_simulated_handle(
/*====================*/
- /* out: TRUE if the aio operation succeeded */
- ulint segment, /* in: the number of the segment in the aio
+ ulint segment, /*!< in: the number of the segment in the aio
arrays to wait for; segment 0 is the ibuf
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
the last are the non-ibuf write threads */
- fil_node_t**message1, /* out: the messages passed with the aio
+ fil_node_t**message1, /*!< out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
restart the operation, for example */
void** message2,
- ulint* type); /* out: OS_FILE_WRITE or ..._READ */
-/**************************************************************************
-Validates the consistency of the aio system. */
+ ulint* type); /*!< out: OS_FILE_WRITE or ..._READ */
+/**********************************************************************//**
+Validates the consistency of the aio system.
+@return TRUE if ok */
UNIV_INTERN
ibool
os_aio_validate(void);
/*=================*/
- /* out: TRUE if ok */
-/**************************************************************************
+/**********************************************************************//**
Prints info of the aio arrays. */
UNIV_INTERN
void
os_aio_print(
/*=========*/
- FILE* file); /* in: file where to print */
-/**************************************************************************
+ FILE* file); /*!< in: file where to print */
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -723,7 +777,7 @@ os_aio_refresh_stats(void);
/*======================*/
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Checks that all slots in the system have been freed, that is, there are
no pending io operations. */
UNIV_INTERN
@@ -732,27 +786,26 @@ os_aio_all_slots_free(void);
/*=======================*/
#endif /* UNIV_DEBUG */
-/***********************************************************************
-This function returns information about the specified file */
+/*******************************************************************//**
+This function returns information about the specified file
+@return TRUE if stat information found */
UNIV_INTERN
ibool
os_file_get_status(
/*===============*/
- /* out: TRUE if stat
- information found */
- const char* path, /* in: pathname of the file */
- os_file_stat_t* stat_info); /* information of a file in a
+ const char* path, /*!< in: pathname of the file */
+ os_file_stat_t* stat_info); /*!< information of a file in a
directory */
#if !defined(UNIV_HOTBACKUP) && !defined(__NETWARE__)
-/*************************************************************************
+/*********************************************************************//**
Creates a temporary file that will be deleted on close.
-This function is defined in ha_innodb.cc. */
+This function is defined in ha_innodb.cc.
+@return temporary file descriptor, or < 0 on error */
UNIV_INTERN
int
innobase_mysql_tmpfile(void);
/*========================*/
- /* out: temporary file descriptor, or < 0 on error */
#endif /* !UNIV_HOTBACKUP && !__NETWARE__ */
#endif
diff --git a/storage/xtradb/include/os0proc.h b/storage/xtradb/include/os0proc.h
index 19b0b112638..fd46bd7db87 100644
--- a/storage/xtradb/include/os0proc.h
+++ b/storage/xtradb/include/os0proc.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0proc.h
The interface to the operating system
process control primitives
@@ -40,42 +41,34 @@ extern ibool os_use_large_pages;
/* Large page size. This may be a boot-time option on some platforms */
extern ulint os_large_page_size;
-/********************************************************************
+/****************************************************************//**
Converts the current process id to a number. It is not guaranteed that the
number is unique. In Linux returns the 'process number' of the current
thread. That number is the same as one sees in 'top', for example. In Linux
-the thread id is not the same as one sees in 'top'. */
+the thread id is not the same as one sees in 'top'.
+@return process id as a number */
UNIV_INTERN
ulint
os_proc_get_number(void);
/*====================*/
-/********************************************************************
-Allocates large pages memory. */
+/****************************************************************//**
+Allocates large pages memory.
+@return allocated memory */
UNIV_INTERN
void*
os_mem_alloc_large(
/*===============*/
- /* out: allocated memory */
- ulint* n); /* in/out: number of bytes */
-/********************************************************************
+ ulint* n); /*!< in/out: number of bytes */
+/****************************************************************//**
Frees large pages memory. */
UNIV_INTERN
void
os_mem_free_large(
/*==============*/
- void *ptr, /* in: pointer returned by
+ void *ptr, /*!< in: pointer returned by
os_mem_alloc_large() */
- ulint size); /* in: size returned by
+ ulint size); /*!< in: size returned by
os_mem_alloc_large() */
-/********************************************************************
-Sets the priority boost for threads released from waiting within the current
-process. */
-UNIV_INTERN
-void
-os_process_set_priority_boost(
-/*==========================*/
- ibool do_boost); /* in: TRUE if priority boost should be done,
- FALSE if not */
#ifndef UNIV_NONINL
#include "os0proc.ic"
diff --git a/storage/xtradb/include/os0proc.ic b/storage/xtradb/include/os0proc.ic
index 9f1fb01866d..c9641644525 100644
--- a/storage/xtradb/include/os0proc.ic
+++ b/storage/xtradb/include/os0proc.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0proc.ic
The interface to the operating system
process control primitives
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index 7e058266762..0c22162b900 100644
--- a/storage/xtradb/include/os0sync.h
+++ b/storage/xtradb/include/os0sync.h
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0sync.h
The interface to the operating system
synchronization primitives.
@@ -38,52 +39,65 @@ Created 9/6/1995 Heikki Tuuri
#ifdef __WIN__
+/** Native mutex */
#define os_fast_mutex_t CRITICAL_SECTION
+/** Native event */
typedef HANDLE os_native_event_t;
+/** Operating system event */
typedef struct os_event_struct os_event_struct_t;
+/** Operating system event handle */
typedef os_event_struct_t* os_event_t;
+/** An asynchronous signal sent between threads */
struct os_event_struct {
os_native_event_t handle;
- /* Windows event */
+ /*!< Windows event */
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
- /* list of all created events */
+ /*!< list of all created events */
};
#else
+/** Native mutex */
typedef pthread_mutex_t os_fast_mutex_t;
+/** Operating system event */
typedef struct os_event_struct os_event_struct_t;
+/** Operating system event handle */
typedef os_event_struct_t* os_event_t;
+/** An asynchronous signal sent between threads */
struct os_event_struct {
- os_fast_mutex_t os_mutex; /* this mutex protects the next
+ os_fast_mutex_t os_mutex; /*!< this mutex protects the next
fields */
- ibool is_set; /* this is TRUE when the event is
+ ibool is_set; /*!< this is TRUE when the event is
in the signaled state, i.e., a thread
does not stop if it tries to wait for
this event */
- ib_int64_t signal_count; /* this is incremented each time
+ ib_int64_t signal_count; /*!< this is incremented each time
the event becomes signaled */
- pthread_cond_t cond_var; /* condition variable is used in
+ pthread_cond_t cond_var; /*!< condition variable is used in
waiting for the event */
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
- /* list of all created events */
+ /*!< list of all created events */
};
#endif
+/** Operating system mutex */
typedef struct os_mutex_struct os_mutex_str_t;
+/** Operating system mutex handle */
typedef os_mutex_str_t* os_mutex_t;
+/** Denotes an infinite delay for os_event_wait_time() */
#define OS_SYNC_INFINITE_TIME ((ulint)(-1))
+/** Return value of os_event_wait_time() when the time is exceeded */
#define OS_SYNC_TIME_EXCEEDED 1
-/* Mutex protecting counts and the event and OS 'slow' mutex lists */
+/** Mutex protecting counts and the event and OS 'slow' mutex lists */
extern os_mutex_t os_sync_mutex;
-/* This is incremented by 1 in os_thread_create and decremented by 1 in
+/** This is incremented by 1 in os_thread_create and decremented by 1 in
os_thread_exit */
extern ulint os_thread_count;
@@ -91,50 +105,38 @@ extern ulint os_event_count;
extern ulint os_mutex_count;
extern ulint os_fast_mutex_count;
-/*************************************************************
+/*********************************************************//**
Initializes global event and OS 'slow' mutex lists. */
UNIV_INTERN
void
os_sync_init(void);
/*==============*/
-/*************************************************************
+/*********************************************************//**
Frees created events and OS 'slow' mutexes. */
UNIV_INTERN
void
os_sync_free(void);
/*==============*/
-/*************************************************************
+/*********************************************************//**
Creates an event semaphore, i.e., a semaphore which may just have two states:
signaled and nonsignaled. The created event is manual reset: it must be reset
-explicitly by calling sync_os_reset_event. */
+explicitly by calling sync_os_reset_event.
+@return the event handle */
UNIV_INTERN
os_event_t
os_event_create(
/*============*/
- /* out: the event handle */
- const char* name); /* in: the name of the event, if NULL
+ const char* name); /*!< in: the name of the event, if NULL
the event is created without a name */
-#ifdef __WIN__
-/*************************************************************
-Creates an auto-reset event semaphore, i.e., an event which is automatically
-reset when a single thread is released. Works only in Windows. */
-UNIV_INTERN
-os_event_t
-os_event_create_auto(
-/*=================*/
- /* out: the event handle */
- const char* name); /* in: the name of the event, if NULL
- the event is created without a name */
-#endif
-/**************************************************************
+/**********************************************************//**
Sets an event semaphore to the signaled state: lets waiting threads
proceed. */
UNIV_INTERN
void
os_event_set(
/*=========*/
- os_event_t event); /* in: event to set */
-/**************************************************************
+ os_event_t event); /*!< in: event to set */
+/**********************************************************//**
Resets an event semaphore to the nonsignaled state. Waiting threads will
stop to wait for the event.
The return value should be passed to os_even_wait_low() if it is desired
@@ -145,16 +147,16 @@ UNIV_INTERN
ib_int64_t
os_event_reset(
/*===========*/
- os_event_t event); /* in: event to reset */
-/**************************************************************
+ os_event_t event); /*!< in: event to reset */
+/**********************************************************//**
Frees an event object. */
UNIV_INTERN
void
os_event_free(
/*==========*/
- os_event_t event); /* in: event to free */
+ os_event_t event); /*!< in: event to free */
-/**************************************************************
+/**********************************************************//**
Waits for an event object until it is in the signaled state. If
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
waiting thread when the event becomes signaled (or immediately if the
@@ -178,129 +180,263 @@ UNIV_INTERN
void
os_event_wait_low(
/*==============*/
- os_event_t event, /* in: event to wait */
- ib_int64_t reset_sig_count);/* in: zero or the value
+ os_event_t event, /*!< in: event to wait */
+ ib_int64_t reset_sig_count);/*!< in: zero or the value
returned by previous call of
os_event_reset(). */
#define os_event_wait(event) os_event_wait_low(event, 0)
-/**************************************************************
+/**********************************************************//**
Waits for an event object until it is in the signaled state or
-a timeout is exceeded. In Unix the timeout is always infinite. */
+a timeout is exceeded. In Unix the timeout is always infinite.
+@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
os_event_wait_time(
/*===============*/
- /* out: 0 if success,
- OS_SYNC_TIME_EXCEEDED if timeout
- was exceeded */
- os_event_t event, /* in: event to wait */
- ulint time); /* in: timeout in microseconds, or
+ os_event_t event, /*!< in: event to wait */
+ ulint time); /*!< in: timeout in microseconds, or
OS_SYNC_INFINITE_TIME */
#ifdef __WIN__
-/**************************************************************
+/**********************************************************//**
Waits for any event in an OS native event array. Returns if even a single
-one is signaled or becomes signaled. */
+one is signaled or becomes signaled.
+@return index of the event which was signaled */
UNIV_INTERN
ulint
os_event_wait_multiple(
/*===================*/
- /* out: index of the event
- which was signaled */
- ulint n, /* in: number of events in the
+ ulint n, /*!< in: number of events in the
array */
os_native_event_t* native_event_array);
- /* in: pointer to an array of event
+ /*!< in: pointer to an array of event
handles */
#endif
-/*************************************************************
+/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
-mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
+mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
+@return the mutex handle */
UNIV_INTERN
os_mutex_t
os_mutex_create(
/*============*/
- /* out: the mutex handle */
- const char* name); /* in: the name of the mutex, if NULL
+ const char* name); /*!< in: the name of the mutex, if NULL
the mutex is created without a name */
-/**************************************************************
+/**********************************************************//**
Acquires ownership of a mutex semaphore. */
UNIV_INTERN
void
os_mutex_enter(
/*===========*/
- os_mutex_t mutex); /* in: mutex to acquire */
-/**************************************************************
+ os_mutex_t mutex); /*!< in: mutex to acquire */
+/**********************************************************//**
Releases ownership of a mutex. */
UNIV_INTERN
void
os_mutex_exit(
/*==========*/
- os_mutex_t mutex); /* in: mutex to release */
-/**************************************************************
+ os_mutex_t mutex); /*!< in: mutex to release */
+/**********************************************************//**
Frees an mutex object. */
UNIV_INTERN
void
os_mutex_free(
/*==========*/
- os_mutex_t mutex); /* in: mutex to free */
-/**************************************************************
+ os_mutex_t mutex); /*!< in: mutex to free */
+/**********************************************************//**
Acquires ownership of a fast mutex. Currently in Windows this is the same
-as os_fast_mutex_lock! */
+as os_fast_mutex_lock!
+@return 0 if success, != 0 if was reserved by another thread */
UNIV_INLINE
ulint
os_fast_mutex_trylock(
/*==================*/
- /* out: 0 if success, != 0 if
- was reserved by another
- thread */
- os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */
-/**************************************************************
+ os_fast_mutex_t* fast_mutex); /*!< in: mutex to acquire */
+/**********************************************************//**
Releases ownership of a fast mutex. */
UNIV_INTERN
void
os_fast_mutex_unlock(
/*=================*/
- os_fast_mutex_t* fast_mutex); /* in: mutex to release */
-/*************************************************************
+ os_fast_mutex_t* fast_mutex); /*!< in: mutex to release */
+/*********************************************************//**
Initializes an operating system fast mutex semaphore. */
UNIV_INTERN
void
os_fast_mutex_init(
/*===============*/
- os_fast_mutex_t* fast_mutex); /* in: fast mutex */
-/**************************************************************
+ os_fast_mutex_t* fast_mutex); /*!< in: fast mutex */
+/**********************************************************//**
Acquires ownership of a fast mutex. */
UNIV_INTERN
void
os_fast_mutex_lock(
/*===============*/
- os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */
-/**************************************************************
+ os_fast_mutex_t* fast_mutex); /*!< in: mutex to acquire */
+/**********************************************************//**
Frees an mutex object. */
UNIV_INTERN
void
os_fast_mutex_free(
/*===============*/
- os_fast_mutex_t* fast_mutex); /* in: mutex to free */
+ os_fast_mutex_t* fast_mutex); /*!< in: mutex to free */
+
+/**********************************************************//**
+Atomic compare-and-swap and increment for InnoDB. */
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-/**************************************************************
-Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins.
+#if defined(HAVE_IB_GCC_ATOMIC_BUILTINS)
+
+#define HAVE_ATOMIC_BUILTINS
+
+/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
-#define os_compare_and_swap(ptr, old_val, new_val) \
+
+# define os_compare_and_swap(ptr, old_val, new_val) \
__sync_bool_compare_and_swap(ptr, old_val, new_val)
-/**************************************************************
-Atomic increment for InnoDB. Currently requires GCC atomic builtins.
+# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
+ os_compare_and_swap(ptr, old_val, new_val)
+
+# define os_compare_and_swap_lint(ptr, old_val, new_val) \
+ os_compare_and_swap(ptr, old_val, new_val)
+
+# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+ os_compare_and_swap(ptr, old_val, new_val)
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use GCC atomic builtins"
+# else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes use GCC atomic builtins, rw_locks do not"
+# endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
+
+/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
-#define os_atomic_increment(ptr, amount) \
+
+# define os_atomic_increment(ptr, amount) \
__sync_add_and_fetch(ptr, amount)
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+# define os_atomic_increment_lint(ptr, amount) \
+ os_atomic_increment(ptr, amount)
+
+# define os_atomic_increment_ulint(ptr, amount) \
+ os_atomic_increment(ptr, amount)
+
+/**********************************************************//**
+Returns the old value of *ptr, atomically sets *ptr to new_val */
+
+# define os_atomic_test_and_set_byte(ptr, new_val) \
+ __sync_lock_test_and_set(ptr, new_val)
+
+#elif defined(HAVE_IB_SOLARIS_ATOMICS)
+
+#define HAVE_ATOMIC_BUILTINS
+
+/* If not compiling with GCC or GCC doesn't support the atomic
+intrinsics and running on Solaris >= 10 use Solaris atomics */
+
+#include <atomic.h>
+
+/**********************************************************//**
+Returns true if swapped, ptr is pointer to target, old_val is value to
+compare to, new_val is the value to swap in. */
+
+# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
+ (atomic_cas_ulong(ptr, old_val, new_val) == old_val)
+
+# define os_compare_and_swap_lint(ptr, old_val, new_val) \
+ ((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
+
+# ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
+# if SIZEOF_PTHREAD_T == 4
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+ ((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
+# elif SIZEOF_PTHREAD_T == 8
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+ ((pthread_t)atomic_cas_64(ptr, old_val, new_val) == old_val)
+# else
+# error "SIZEOF_PTHREAD_T != 4 or 8"
+# endif /* SIZEOF_PTHREAD_T CHECK */
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use Solaris atomic functions"
+# else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes use Solaris atomic functions, rw_locks do not"
+# endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
+
+/**********************************************************//**
+Returns the resulting value, ptr is pointer to target, amount is the
+amount of increment. */
+
+# define os_atomic_increment_lint(ptr, amount) \
+ atomic_add_long_nv((ulong_t*) ptr, amount)
+
+# define os_atomic_increment_ulint(ptr, amount) \
+ atomic_add_long_nv(ptr, amount)
+
+/**********************************************************//**
+Returns the old value of *ptr, atomically sets *ptr to new_val */
+
+# define os_atomic_test_and_set_byte(ptr, new_val) \
+ atomic_swap_uchar(ptr, new_val)
+
+#elif defined(HAVE_WINDOWS_ATOMICS)
+
+#define HAVE_ATOMIC_BUILTINS
+
+/* On Windows, use Windows atomics / interlocked */
+# ifdef _WIN64
+# define win_cmp_and_xchg InterlockedCompareExchange64
+# define win_xchg_and_add InterlockedExchangeAdd64
+# else /* _WIN64 */
+# define win_cmp_and_xchg InterlockedCompareExchange
+# define win_xchg_and_add InterlockedExchangeAdd
+# endif
+
+/**********************************************************//**
+Returns true if swapped, ptr is pointer to target, old_val is value to
+compare to, new_val is the value to swap in. */
+
+# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
+ (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+
+# define os_compare_and_swap_lint(ptr, old_val, new_val) \
+ (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+
+/* windows thread objects can always be passed to windows atomic functions */
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+ (InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use Windows interlocked functions"
+
+/**********************************************************//**
+Returns the resulting value, ptr is pointer to target, amount is the
+amount of increment. */
+
+# define os_atomic_increment_lint(ptr, amount) \
+ (win_xchg_and_add(ptr, amount) + amount)
+
+# define os_atomic_increment_ulint(ptr, amount) \
+ ((ulint) (win_xchg_and_add(ptr, amount) + amount))
+
+/**********************************************************//**
+Returns the old value of *ptr, atomically sets *ptr to new_val.
+InterlockedExchange() operates on LONG, and the LONG will be
+clobbered */
+
+# define os_atomic_test_and_set_byte(ptr, new_val) \
+ ((byte) InterlockedExchange(ptr, new_val))
+
+#else
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use InnoDB's own implementation"
+#endif
#ifndef UNIV_NONINL
#include "os0sync.ic"
diff --git a/storage/xtradb/include/os0sync.ic b/storage/xtradb/include/os0sync.ic
index 5c03d184c7c..1f3ce38fa65 100644
--- a/storage/xtradb/include/os0sync.ic
+++ b/storage/xtradb/include/os0sync.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0sync.ic
The interface to the operating system synchronization primitives.
Created 9/6/1995 Heikki Tuuri
@@ -26,30 +27,21 @@ Created 9/6/1995 Heikki Tuuri
#include <winbase.h>
#endif
-/**************************************************************
+/**********************************************************//**
Acquires ownership of a fast mutex. Currently in Windows this is the same
-as os_fast_mutex_lock! */
+as os_fast_mutex_lock!
+@return 0 if success, != 0 if was reserved by another thread */
UNIV_INLINE
ulint
os_fast_mutex_trylock(
/*==================*/
- /* out: 0 if success, != 0 if
- was reserved by another
- thread */
- os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */
+ os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
EnterCriticalSection(fast_mutex);
return(0);
#else
-#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
- /* Since the hot backup version is standalone, MySQL does not redefine
- pthread_mutex_trylock for HP-UX-10.20, and consequently we must invert
- the return value here */
-
- return((ulint) (1 - pthread_mutex_trylock(fast_mutex)));
-#else
/* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock
so that it returns 0 on success. In the operating system
libraries, HP-UX-10.20 follows the old Posix 1003.4a Draft 4 and
@@ -58,5 +50,4 @@ os_fast_mutex_trylock(
return((ulint) pthread_mutex_trylock(fast_mutex));
#endif
-#endif
}
diff --git a/storage/xtradb/include/os0thread.h b/storage/xtradb/include/os0thread.h
index 863596bfa84..6583de0005f 100644
--- a/storage/xtradb/include/os0thread.h
+++ b/storage/xtradb/include/os0thread.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0thread.h
The interface to the operating system
process and thread control primitives
@@ -43,11 +44,11 @@ can wait inside InnoDB */
#ifdef __WIN__
typedef void* os_thread_t;
-typedef ulint os_thread_id_t; /* In Windows the thread id
+typedef unsigned long os_thread_id_t; /*!< In Windows the thread id
is an unsigned long int */
#else
typedef pthread_t os_thread_t;
-typedef os_thread_t os_thread_id_t; /* In Unix we use the thread
+typedef os_thread_t os_thread_id_t; /*!< In Unix we use the thread
handle itself as the id of
the thread */
#endif
@@ -55,97 +56,100 @@ typedef os_thread_t os_thread_id_t; /* In Unix we use the thread
/* Define a function pointer type to use in a typecast */
typedef void* (*os_posix_f_t) (void*);
-/*******************************************************************
-Compares two thread ids for equality. */
+/***************************************************************//**
+Compares two thread ids for equality.
+@return TRUE if equal */
UNIV_INTERN
ibool
os_thread_eq(
/*=========*/
- /* out: TRUE if equal */
- os_thread_id_t a, /* in: OS thread or thread id */
- os_thread_id_t b); /* in: OS thread or thread id */
-/********************************************************************
+ os_thread_id_t a, /*!< in: OS thread or thread id */
+ os_thread_id_t b); /*!< in: OS thread or thread id */
+/****************************************************************//**
Converts an OS thread id to a ulint. It is NOT guaranteed that the ulint is
-unique for the thread though! */
+unique for the thread though!
+@return thread identifier as a number */
UNIV_INTERN
ulint
os_thread_pf(
/*=========*/
- /* out: unsigned long int */
- os_thread_id_t a); /* in: thread or thread id */
-/********************************************************************
+ os_thread_id_t a); /*!< in: OS thread identifier */
+/****************************************************************//**
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
and returns a ulint.
NOTE: We count the number of threads in os_thread_exit(). A created
-thread should always use that to exit and not use return() to exit. */
+thread should always use that to exit and not use return() to exit.
+@return handle to the thread */
UNIV_INTERN
os_thread_t
os_thread_create(
/*=============*/
- /* out: handle to the thread */
#ifndef __WIN__
os_posix_f_t start_f,
#else
- ulint (*start_f)(void*), /* in: pointer to function
+ ulint (*start_f)(void*), /*!< in: pointer to function
from which to start */
#endif
- void* arg, /* in: argument to start
+ void* arg, /*!< in: argument to start
function */
- os_thread_id_t* thread_id); /* out: id of the created
+ os_thread_id_t* thread_id); /*!< out: id of the created
thread, or NULL */
-/*********************************************************************
+/*****************************************************************//**
Exits the current thread. */
UNIV_INTERN
void
os_thread_exit(
/*===========*/
- void* exit_value); /* in: exit value; in Windows this void*
+ void* exit_value); /*!< in: exit value; in Windows this void*
is cast as a DWORD */
-/*********************************************************************
-Returns the thread identifier of current thread. */
+/*****************************************************************//**
+Returns the thread identifier of current thread.
+@return current thread identifier */
UNIV_INTERN
os_thread_id_t
os_thread_get_curr_id(void);
/*========================*/
-/*********************************************************************
-Returns handle to the current thread. */
+/*****************************************************************//**
+Returns handle to the current thread.
+@return current thread handle */
UNIV_INTERN
os_thread_t
os_thread_get_curr(void);
/*====================*/
-/*********************************************************************
+/*****************************************************************//**
Advises the os to give up remainder of the thread's time slice. */
UNIV_INTERN
void
os_thread_yield(void);
/*=================*/
-/*********************************************************************
+/*****************************************************************//**
The thread sleeps at least the time given in microseconds. */
UNIV_INTERN
void
os_thread_sleep(
/*============*/
- ulint tm); /* in: time in microseconds */
-/**********************************************************************
-Gets a thread priority. */
+ ulint tm); /*!< in: time in microseconds */
+/******************************************************************//**
+Gets a thread priority.
+@return priority */
UNIV_INTERN
ulint
os_thread_get_priority(
/*===================*/
- /* out: priority */
- os_thread_t handle);/* in: OS handle to the thread */
-/**********************************************************************
+ os_thread_t handle);/*!< in: OS handle to the thread */
+/******************************************************************//**
Sets a thread priority. */
UNIV_INTERN
void
os_thread_set_priority(
/*===================*/
- os_thread_t handle, /* in: OS handle to the thread */
- ulint pri); /* in: priority: one of OS_PRIORITY_... */
-/**********************************************************************
-Gets the last operating system error code for the calling thread. */
+ os_thread_t handle, /*!< in: OS handle to the thread */
+ ulint pri); /*!< in: priority: one of OS_PRIORITY_... */
+/******************************************************************//**
+Gets the last operating system error code for the calling thread.
+@return last error on Windows, 0 otherwise */
UNIV_INTERN
ulint
os_thread_get_last_error(void);
diff --git a/storage/xtradb/include/os0thread.ic b/storage/xtradb/include/os0thread.ic
index a86b203809c..f89bc40b4fa 100644
--- a/storage/xtradb/include/os0thread.ic
+++ b/storage/xtradb/include/os0thread.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0thread.ic
The interface to the operating system
process and thread control primitives
diff --git a/storage/xtradb/include/page0cur.h b/storage/xtradb/include/page0cur.h
index 960ecdddf4e..1544b0abe1c 100644
--- a/storage/xtradb/include/page0cur.h
+++ b/storage/xtradb/include/page0cur.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/page0cur.h
The page cursor
Created 10/4/1994 Heikki Tuuri
@@ -52,291 +53,290 @@ Created 10/4/1994 Heikki Tuuri
#endif /* UNIV_SEARCH_DEBUG */
#ifdef UNIV_DEBUG
-/*************************************************************
-Gets pointer to the page frame where the cursor is positioned. */
+/*********************************************************//**
+Gets pointer to the page frame where the cursor is positioned.
+@return page */
UNIV_INLINE
page_t*
page_cur_get_page(
/*==============*/
- /* out: page */
- page_cur_t* cur); /* in: page cursor */
-/*************************************************************
-Gets pointer to the buffer block where the cursor is positioned. */
+ page_cur_t* cur); /*!< in: page cursor */
+/*********************************************************//**
+Gets pointer to the buffer block where the cursor is positioned.
+@return page */
UNIV_INLINE
buf_block_t*
page_cur_get_block(
/*===============*/
- /* out: page */
- page_cur_t* cur); /* in: page cursor */
-/*************************************************************
-Gets pointer to the page frame where the cursor is positioned. */
+ page_cur_t* cur); /*!< in: page cursor */
+/*********************************************************//**
+Gets pointer to the page frame where the cursor is positioned.
+@return page */
UNIV_INLINE
page_zip_des_t*
page_cur_get_page_zip(
/*==================*/
- /* out: page */
- page_cur_t* cur); /* in: page cursor */
-/*************************************************************
-Gets the record where the cursor is positioned. */
+ page_cur_t* cur); /*!< in: page cursor */
+/*********************************************************//**
+Gets the record where the cursor is positioned.
+@return record */
UNIV_INLINE
rec_t*
page_cur_get_rec(
/*=============*/
- /* out: record */
- page_cur_t* cur); /* in: page cursor */
+ page_cur_t* cur); /*!< in: page cursor */
#else /* UNIV_DEBUG */
# define page_cur_get_page(cur) page_align((cur)->rec)
# define page_cur_get_block(cur) (cur)->block
# define page_cur_get_page_zip(cur) buf_block_get_page_zip((cur)->block)
# define page_cur_get_rec(cur) (cur)->rec
#endif /* UNIV_DEBUG */
-/*************************************************************
+/*********************************************************//**
Sets the cursor object to point before the first user record
on the page. */
UNIV_INLINE
void
page_cur_set_before_first(
/*======================*/
- const buf_block_t* block, /* in: index page */
- page_cur_t* cur); /* in: cursor */
-/*************************************************************
+ const buf_block_t* block, /*!< in: index page */
+ page_cur_t* cur); /*!< in: cursor */
+/*********************************************************//**
Sets the cursor object to point after the last user record on
the page. */
UNIV_INLINE
void
page_cur_set_after_last(
/*====================*/
- const buf_block_t* block, /* in: index page */
- page_cur_t* cur); /* in: cursor */
-/*************************************************************
-Returns TRUE if the cursor is before first user record on page. */
+ const buf_block_t* block, /*!< in: index page */
+ page_cur_t* cur); /*!< in: cursor */
+/*********************************************************//**
+Returns TRUE if the cursor is before first user record on page.
+@return TRUE if at start */
UNIV_INLINE
ibool
page_cur_is_before_first(
/*=====================*/
- /* out: TRUE if at start */
- const page_cur_t* cur); /* in: cursor */
-/*************************************************************
-Returns TRUE if the cursor is after last user record. */
+ const page_cur_t* cur); /*!< in: cursor */
+/*********************************************************//**
+Returns TRUE if the cursor is after last user record.
+@return TRUE if at end */
UNIV_INLINE
ibool
page_cur_is_after_last(
/*===================*/
- /* out: TRUE if at end */
- const page_cur_t* cur); /* in: cursor */
-/**************************************************************
+ const page_cur_t* cur); /*!< in: cursor */
+/**********************************************************//**
Positions the cursor on the given record. */
UNIV_INLINE
void
page_cur_position(
/*==============*/
- const rec_t* rec, /* in: record on a page */
- const buf_block_t* block, /* in: buffer block containing
+ const rec_t* rec, /*!< in: record on a page */
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- page_cur_t* cur); /* out: page cursor */
-/**************************************************************
+ page_cur_t* cur); /*!< out: page cursor */
+/**********************************************************//**
Invalidates a page cursor by setting the record pointer NULL. */
UNIV_INLINE
void
page_cur_invalidate(
/*================*/
- page_cur_t* cur); /* out: page cursor */
-/**************************************************************
+ page_cur_t* cur); /*!< out: page cursor */
+/**********************************************************//**
Moves the cursor to the next record on page. */
UNIV_INLINE
void
page_cur_move_to_next(
/*==================*/
- page_cur_t* cur); /* in/out: cursor; must not be after last */
-/**************************************************************
+ page_cur_t* cur); /*!< in/out: cursor; must not be after last */
+/**********************************************************//**
Moves the cursor to the previous record on page. */
UNIV_INLINE
void
page_cur_move_to_prev(
/*==================*/
- page_cur_t* cur); /* in/out: cursor; not before first */
-/***************************************************************
+ page_cur_t* cur); /*!< in/out: cursor; not before first */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same logical position, but the physical position may change if it is
-pointing to a compressed page that was reorganized. */
+pointing to a compressed page that was reorganized.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INLINE
rec_t*
page_cur_tuple_insert(
/*==================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- 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 n_ext, /* in: number of externally stored columns */
- mtr_t* mtr); /* in: mini-transaction handle, or NULL */
-/***************************************************************
+ 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 n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same logical position, but the physical position may change if it is
-pointing to a compressed page that was reorganized. */
+pointing to a compressed page that was reorganized.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INLINE
rec_t*
page_cur_rec_insert(
/*================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- 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) */
- mtr_t* mtr); /* in: mini-transaction handle, or NULL */
-/***************************************************************
+ 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) */
+ mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
-space available, NULL otherwise. The cursor stays at the same position. */
+space available, NULL otherwise. The cursor stays at the same position.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INTERN
rec_t*
page_cur_insert_rec_low(
/*====================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- rec_t* current_rec,/* in: pointer to current record after
+ rec_t* current_rec,/*!< in: pointer to current record after
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) */
- mtr_t* mtr); /* in: mini-transaction handle, or NULL */
-/***************************************************************
+ 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) */
+ mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+/***********************************************************//**
Inserts a record next to page cursor on a compressed and uncompressed
page. Returns pointer to inserted record if succeed, i.e.,
enough space available, NULL otherwise.
-The cursor stays at the same position. */
+The cursor stays at the same position.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INTERN
rec_t*
page_cur_insert_rec_zip(
/*====================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- rec_t** current_rec,/* in/out: pointer to current record after
+ rec_t** current_rec,/*!< in/out: pointer to current record after
which the new record is inserted */
- buf_block_t* block, /* in: buffer block of *current_rec */
- 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) */
- mtr_t* mtr); /* in: mini-transaction handle, or NULL */
-/*****************************************************************
+ buf_block_t* block, /*!< in: buffer block of *current_rec */
+ 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) */
+ mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+/*************************************************************//**
Copies records from page to a newly created page, from a given record onward,
including that record. Infimum and supremum records are not copied. */
UNIV_INTERN
void
page_copy_rec_list_end_to_created_page(
/*===================================*/
- page_t* new_page, /* in/out: index page to copy to */
- rec_t* rec, /* in: first record to copy */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************
+ page_t* new_page, /*!< in/out: index page to copy to */
+ rec_t* rec, /*!< in: first record to copy */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************//**
Deletes a record at the page cursor. The cursor is moved to the
next record after the deleted one. */
UNIV_INTERN
void
page_cur_delete_rec(
/*================*/
- page_cur_t* cursor, /* in/out: a page cursor */
- dict_index_t* index, /* in: record descriptor */
- const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
- mtr_t* mtr); /* in: mini-transaction handle */
-/********************************************************************
-Searches the right position for a page cursor. */
+ page_cur_t* cursor, /*!< in/out: a page cursor */
+ dict_index_t* index, /*!< in: record descriptor */
+ const ulint* offsets,/*!< in: rec_get_offsets(cursor->rec, index) */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
+Searches the right position for a page cursor.
+@return number of matched fields on the left */
UNIV_INLINE
ulint
page_cur_search(
/*============*/
- /* out: number of matched
- fields on the left */
- const buf_block_t* block, /* in: buffer block */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L,
+ const buf_block_t* block, /*!< in: buffer block */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L,
PAGE_CUR_LE, PAGE_CUR_G, or
PAGE_CUR_GE */
- page_cur_t* cursor);/* out: page cursor */
-/********************************************************************
+ page_cur_t* cursor);/*!< out: page cursor */
+/****************************************************************//**
Searches the right position for a page cursor. */
UNIV_INTERN
void
page_cur_search_with_match(
/*=======================*/
- const buf_block_t* block, /* in: buffer block */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L,
+ const buf_block_t* block, /*!< in: buffer block */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L,
PAGE_CUR_LE, PAGE_CUR_G, or
PAGE_CUR_GE */
ulint* iup_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in upper limit record */
ulint* iup_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
ulint* ilow_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in lower limit record */
ulint* ilow_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
- page_cur_t* cursor);/* out: page cursor */
-/***************************************************************
+ page_cur_t* cursor);/*!< out: page cursor */
+/***********************************************************//**
Positions a page cursor on a randomly chosen user record on a page. If there
are no user records, sets the cursor on the infimum record. */
UNIV_INTERN
void
page_cur_open_on_rnd_user_rec(
/*==========================*/
- buf_block_t* block, /* in: page */
- page_cur_t* cursor);/* out: page cursor */
-/***************************************************************
-Parses a log record of a record insert on a page. */
+ buf_block_t* block, /*!< in: page */
+ page_cur_t* cursor);/*!< out: page cursor */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
+Parses a log record of a record insert on a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_cur_parse_insert_rec(
/*======================*/
- /* out: end of log record or NULL */
- ibool is_short,/* in: TRUE if short inserts */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr or NULL */
-/**************************************************************
-Parses a log record of copying a record list end to a new created page. */
+ ibool is_short,/*!< in: TRUE if short inserts */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/**********************************************************//**
+Parses a log record of copying a record list end to a new created page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_copy_rec_list_to_created_page(
/*=====================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses log record of a record delete on a page. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses log record of a record delete on a page.
+@return pointer to record end or NULL */
UNIV_INTERN
byte*
page_cur_parse_delete_rec(
/*======================*/
- /* out: pointer to record end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr or NULL */
-/* Index page cursor */
+/** Index page cursor */
struct page_cur_struct{
- byte* rec; /* pointer to a record on page */
- buf_block_t* block; /* pointer to the block containing rec */
+ byte* rec; /*!< pointer to a record on page */
+ buf_block_t* block; /*!< pointer to the block containing rec */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/page0cur.ic b/storage/xtradb/include/page0cur.ic
index 9cf10ea5e3f..3520677dfb3 100644
--- a/storage/xtradb/include/page0cur.ic
+++ b/storage/xtradb/include/page0cur.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/page0cur.ic
The page cursor
Created 10/4/1994 Heikki Tuuri
@@ -26,14 +27,14 @@ Created 10/4/1994 Heikki Tuuri
#include "buf0types.h"
#ifdef UNIV_DEBUG
-/*************************************************************
-Gets pointer to the page frame where the cursor is positioned. */
+/*********************************************************//**
+Gets pointer to the page frame where the cursor is positioned.
+@return page */
UNIV_INLINE
page_t*
page_cur_get_page(
/*==============*/
- /* out: page */
- page_cur_t* cur) /* in: page cursor */
+ page_cur_t* cur) /*!< in: page cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
@@ -41,40 +42,40 @@ page_cur_get_page(
return(page_align(cur->rec));
}
-/*************************************************************
-Gets pointer to the buffer block where the cursor is positioned. */
+/*********************************************************//**
+Gets pointer to the buffer block where the cursor is positioned.
+@return page */
UNIV_INLINE
buf_block_t*
page_cur_get_block(
/*===============*/
- /* out: page */
- page_cur_t* cur) /* in: page cursor */
+ page_cur_t* cur) /*!< in: page cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
return(cur->block);
}
-/*************************************************************
-Gets pointer to the page frame where the cursor is positioned. */
+/*********************************************************//**
+Gets pointer to the page frame where the cursor is positioned.
+@return page */
UNIV_INLINE
page_zip_des_t*
page_cur_get_page_zip(
/*==================*/
- /* out: page */
- page_cur_t* cur) /* in: page cursor */
+ page_cur_t* cur) /*!< in: page cursor */
{
return(buf_block_get_page_zip(page_cur_get_block(cur)));
}
-/*************************************************************
-Gets the record where the cursor is positioned. */
+/*********************************************************//**
+Gets the record where the cursor is positioned.
+@return record */
UNIV_INLINE
rec_t*
page_cur_get_rec(
/*=============*/
- /* out: record */
- page_cur_t* cur) /* in: page cursor */
+ page_cur_t* cur) /*!< in: page cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
@@ -83,72 +84,72 @@ page_cur_get_rec(
}
#endif /* UNIV_DEBUG */
-/*************************************************************
+/*********************************************************//**
Sets the cursor object to point before the first user record
on the page. */
UNIV_INLINE
void
page_cur_set_before_first(
/*======================*/
- const buf_block_t* block, /* in: index page */
- page_cur_t* cur) /* in: cursor */
+ const buf_block_t* block, /*!< in: index page */
+ page_cur_t* cur) /*!< in: cursor */
{
cur->block = (buf_block_t*) block;
cur->rec = page_get_infimum_rec(buf_block_get_frame(cur->block));
}
-/*************************************************************
+/*********************************************************//**
Sets the cursor object to point after the last user record on
the page. */
UNIV_INLINE
void
page_cur_set_after_last(
/*====================*/
- const buf_block_t* block, /* in: index page */
- page_cur_t* cur) /* in: cursor */
+ const buf_block_t* block, /*!< in: index page */
+ page_cur_t* cur) /*!< in: cursor */
{
cur->block = (buf_block_t*) block;
cur->rec = page_get_supremum_rec(buf_block_get_frame(cur->block));
}
-/*************************************************************
-Returns TRUE if the cursor is before first user record on page. */
+/*********************************************************//**
+Returns TRUE if the cursor is before first user record on page.
+@return TRUE if at start */
UNIV_INLINE
ibool
page_cur_is_before_first(
/*=====================*/
- /* out: TRUE if at start */
- const page_cur_t* cur) /* in: cursor */
+ const page_cur_t* cur) /*!< in: cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
return(page_rec_is_infimum(cur->rec));
}
-/*************************************************************
-Returns TRUE if the cursor is after last user record. */
+/*********************************************************//**
+Returns TRUE if the cursor is after last user record.
+@return TRUE if at end */
UNIV_INLINE
ibool
page_cur_is_after_last(
/*===================*/
- /* out: TRUE if at end */
- const page_cur_t* cur) /* in: cursor */
+ const page_cur_t* cur) /*!< in: cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
return(page_rec_is_supremum(cur->rec));
}
-/**************************************************************
+/**********************************************************//**
Positions the cursor on the given record. */
UNIV_INLINE
void
page_cur_position(
/*==============*/
- const rec_t* rec, /* in: record on a page */
- const buf_block_t* block, /* in: buffer block containing
+ const rec_t* rec, /*!< in: record on a page */
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- page_cur_t* cur) /* out: page cursor */
+ page_cur_t* cur) /*!< out: page cursor */
{
ut_ad(rec && block && cur);
ut_ad(page_align(rec) == block->frame);
@@ -157,13 +158,13 @@ page_cur_position(
cur->block = (buf_block_t*) block;
}
-/**************************************************************
+/**********************************************************//**
Invalidates a page cursor by setting the record pointer NULL. */
UNIV_INLINE
void
page_cur_invalidate(
/*================*/
- page_cur_t* cur) /* out: page cursor */
+ page_cur_t* cur) /*!< out: page cursor */
{
ut_ad(cur);
@@ -171,47 +172,47 @@ page_cur_invalidate(
cur->block = NULL;
}
-/**************************************************************
+/**********************************************************//**
Moves the cursor to the next record on page. */
UNIV_INLINE
void
page_cur_move_to_next(
/*==================*/
- page_cur_t* cur) /* in/out: cursor; must not be after last */
+ page_cur_t* cur) /*!< in/out: cursor; must not be after last */
{
ut_ad(!page_cur_is_after_last(cur));
cur->rec = page_rec_get_next(cur->rec);
}
-/**************************************************************
+/**********************************************************//**
Moves the cursor to the previous record on page. */
UNIV_INLINE
void
page_cur_move_to_prev(
/*==================*/
- page_cur_t* cur) /* in/out: page cursor, not before first */
+ page_cur_t* cur) /*!< in/out: page cursor, not before first */
{
ut_ad(!page_cur_is_before_first(cur));
cur->rec = page_rec_get_prev(cur->rec);
}
-/********************************************************************
-Searches the right position for a page cursor. */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
+Searches the right position for a page cursor.
+@return number of matched fields on the left */
UNIV_INLINE
ulint
page_cur_search(
/*============*/
- /* out: number of matched
- fields on the left */
- const buf_block_t* block, /* in: buffer block */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L,
+ const buf_block_t* block, /*!< in: buffer block */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L,
PAGE_CUR_LE, PAGE_CUR_G, or
PAGE_CUR_GE */
- page_cur_t* cursor) /* out: page cursor */
+ page_cur_t* cursor) /*!< out: page cursor */
{
ulint low_matched_fields = 0;
ulint low_matched_bytes = 0;
@@ -229,22 +230,21 @@ page_cur_search(
return(low_matched_fields);
}
-/***************************************************************
+/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same logical position, but the physical position may change if it is
-pointing to a compressed page that was reorganized. */
+pointing to a compressed page that was reorganized.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INLINE
rec_t*
page_cur_tuple_insert(
/*==================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- 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 n_ext, /* in: number of externally stored columns */
- mtr_t* mtr) /* in: mini-transaction handle, or NULL */
+ 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 n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
mem_heap_t* heap;
ulint* offsets;
@@ -271,23 +271,23 @@ page_cur_tuple_insert(
mem_heap_free(heap);
return(rec);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
+/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same logical position, but the physical position may change if it is
-pointing to a compressed page that was reorganized. */
+pointing to a compressed page that was reorganized.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INLINE
rec_t*
page_cur_rec_insert(
/*================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- 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) */
- mtr_t* mtr) /* in: mini-transaction handle, or NULL */
+ 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) */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
if (buf_block_get_page_zip(cursor->block)) {
return(page_cur_insert_rec_zip(&cursor->rec, cursor->block,
@@ -297,4 +297,3 @@ page_cur_rec_insert(
index, rec, offsets, mtr));
}
}
-
diff --git a/storage/xtradb/include/page0page.h b/storage/xtradb/include/page0page.h
index e3de6901ee1..3899499fb6a 100644
--- a/storage/xtradb/include/page0page.h
+++ b/storage/xtradb/include/page0page.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0page.h
Index page routines
Created 2/2/1994 Heikki Tuuri
@@ -66,8 +67,8 @@ typedef byte page_header_t;
#define PAGE_N_RECS 16 /* number of user records on the page */
#define PAGE_MAX_TRX_ID 18 /* highest id of a trx which may have modified
a record on the page; a dulint; defined only
- in secondary indexes; specifically, not in an
- ibuf tree; NOTE: this may be modified only
+ in secondary indexes and in the insert buffer
+ tree; NOTE: this may be modified only
when the thread has an x-latch to the page,
and ALSO an x-latch to btr_search_latch
if there is a hash index to the page! */
@@ -75,8 +76,11 @@ typedef byte page_header_t;
header which are set in a page create */
/*----*/
#define PAGE_LEVEL 26 /* level of the node in an index tree; the
- leaf level is the level 0 */
-#define PAGE_INDEX_ID 28 /* index id where the page belongs */
+ leaf level is the level 0. This field should
+ not be written to after page creation. */
+#define PAGE_INDEX_ID 28 /* index id where the page belongs.
+ This field should not be written to after
+ page creation. */
#define PAGE_BTR_SEG_LEAF 36 /* file segment header for the leaf pages in
a B-tree: defined only on the root page of a
B-tree, but not in the root of an ibuf tree */
@@ -156,294 +160,296 @@ directory. */
#define PAGE_DIR_SLOT_MAX_N_OWNED 8
#define PAGE_DIR_SLOT_MIN_N_OWNED 4
-/****************************************************************
-Gets the start of a page. */
+/************************************************************//**
+Gets the start of a page.
+@return start of the page */
UNIV_INLINE
page_t*
page_align(
/*=======*/
- /* out: start of the page */
- const void* ptr) /* in: pointer to page frame */
+ const void* ptr) /*!< in: pointer to page frame */
__attribute__((const));
-/****************************************************************
-Gets the offset within a page. */
+/************************************************************//**
+Gets the offset within a page.
+@return offset from the start of the page */
UNIV_INLINE
ulint
page_offset(
/*========*/
- /* out: offset from the start of the page */
- const void* ptr) /* in: pointer to page frame */
+ const void* ptr) /*!< in: pointer to page frame */
__attribute__((const));
-/*****************************************************************
+/*************************************************************//**
Returns the max trx id field value. */
UNIV_INLINE
-dulint
+trx_id_t
page_get_max_trx_id(
/*================*/
- const page_t* page); /* in: page */
-/*****************************************************************
+ const page_t* page); /*!< in: page */
+/*************************************************************//**
Sets the max trx id field value. */
UNIV_INTERN
void
page_set_max_trx_id(
/*================*/
- buf_block_t* block, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dulint trx_id);/* in: transaction id */
-/*****************************************************************
+ buf_block_t* block, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr); /*!< in/out: mini-transaction, or NULL */
+/*************************************************************//**
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
+ 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 */
- dulint trx_id);/* in: transaction id */
-/*****************************************************************
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr); /*!< in/out: mini-transaction */
+/*************************************************************//**
Reads the given header field. */
UNIV_INLINE
ulint
page_header_get_field(
/*==================*/
- const page_t* page, /* in: page */
- ulint field); /* in: PAGE_N_DIR_SLOTS, ... */
-/*****************************************************************
+ const page_t* page, /*!< in: page */
+ ulint field); /*!< in: PAGE_N_DIR_SLOTS, ... */
+/*************************************************************//**
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
+ 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 */
-/*****************************************************************
-Returns the offset stored in the given header field. */
+ ulint field, /*!< in: PAGE_N_DIR_SLOTS, ... */
+ ulint val); /*!< in: value */
+/*************************************************************//**
+Returns the offset stored in the given header field.
+@return offset from the start of the page, or 0 */
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, ... */
+ const page_t* page, /*!< in: page */
+ ulint field) /*!< in: PAGE_FREE, ... */
__attribute__((nonnull, pure));
-/*****************************************************************
+/*************************************************************//**
Returns the pointer stored in the given header field, or NULL. */
#define page_header_get_ptr(page, field) \
(page_header_get_offs(page, field) \
? page + page_header_get_offs(page, field) : NULL)
-/*****************************************************************
+/*************************************************************//**
Sets the pointer stored in the given header field. */
UNIV_INLINE
void
page_header_set_ptr(
/*================*/
- page_t* page, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ 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/out: PAGE_FREE, ... */
- const byte* ptr); /* in: pointer or NULL*/
-/*****************************************************************
+ ulint field, /*!< in/out: PAGE_FREE, ... */
+ const byte* ptr); /*!< in: pointer or NULL*/
+#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: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- mtr_t* mtr); /* in: mtr */
-/****************************************************************
-Gets the offset of the first record on the page. */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/************************************************************//**
+Gets the offset of the first record on the page.
+@return offset of the first record in record list, relative from 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) */
-/****************************************************************
-Gets the offset of the last record on the page. */
+ const page_t* page); /*!< in: page which must have record(s) */
+/************************************************************//**
+Gets the offset of the last record on the page.
+@return offset of the last record in record list, relative from 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) */
+ const page_t* page); /*!< in: page which must have record(s) */
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
-/****************************************************************
+/************************************************************//**
Returns the middle record of record list. If there are an even number
-of records in the list, returns the first record of upper half-list. */
+of records in the list, returns the first record of upper half-list.
+@return middle record */
UNIV_INTERN
rec_t*
page_get_middle_rec(
/*================*/
- /* out: middle record */
- page_t* page); /* in: page */
-/*****************************************************************
+ page_t* page); /*!< in: page */
+#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. */
+the positive infinity in the alphabetical order.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared */
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
+ 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
+ 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
+ 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 */
-/*****************************************************************
-Gets the page number. */
+#endif /* !UNIV_HOTBACKUP */
+/*************************************************************//**
+Gets the page number.
+@return page number */
UNIV_INLINE
ulint
page_get_page_no(
/*=============*/
- /* out: page number */
- const page_t* page); /* in: page */
-/*****************************************************************
-Gets the tablespace identifier. */
+ const page_t* page); /*!< in: page */
+/*************************************************************//**
+Gets the tablespace identifier.
+@return space id */
UNIV_INLINE
ulint
page_get_space_id(
/*==============*/
- /* out: space id */
- const page_t* page); /* in: page */
-/*****************************************************************
+ const page_t* page); /*!< in: page */
+/*************************************************************//**
Gets the number of user records on page (the infimum and supremum records
-are not user records). */
+are not user records).
+@return number of user records */
UNIV_INLINE
ulint
page_get_n_recs(
/*============*/
- /* out: number of user records */
- const page_t* page); /* in: index page */
-/*******************************************************************
+ const page_t* page); /*!< in: index page */
+/***************************************************************//**
Returns the number of records before the given record in chain.
-The number includes infimum and supremum records. */
+The number includes infimum and supremum records.
+@return number of records */
UNIV_INTERN
ulint
page_rec_get_n_recs_before(
/*=======================*/
- /* out: number of records */
- const rec_t* rec); /* in: the physical record */
-/*****************************************************************
-Gets the number of records in the heap. */
+ const rec_t* rec); /*!< in: the physical record */
+/*************************************************************//**
+Gets the number of records in the heap.
+@return number of user records */
UNIV_INLINE
ulint
page_dir_get_n_heap(
/*================*/
- /* out: number of user records */
- const page_t* page); /* in: index page */
-/*****************************************************************
+ const page_t* page); /*!< in: index page */
+/*************************************************************//**
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
+ 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 */
-/*****************************************************************
-Gets the number of dir slots in directory. */
+ ulint n_heap);/*!< in: number of records */
+/*************************************************************//**
+Gets the number of dir slots in directory.
+@return number of slots */
UNIV_INLINE
ulint
page_dir_get_n_slots(
/*=================*/
- /* out: number of slots */
- const page_t* page); /* in: index page */
-/*****************************************************************
+ const page_t* page); /*!< in: index page */
+/*************************************************************//**
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
+ 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 */
+ ulint n_slots);/*!< in: number of slots */
#ifdef UNIV_DEBUG
-/*****************************************************************
-Gets pointer to nth directory slot. */
+/*************************************************************//**
+Gets pointer to nth directory slot.
+@return pointer to dir 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 */
+ const page_t* page, /*!< in: index page */
+ ulint n); /*!< in: position */
#else /* UNIV_DEBUG */
# define page_dir_get_nth_slot(page, n) \
((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. */
+/**************************************************************//**
+Used to check the consistency of a record on a page.
+@return TRUE if succeed */
UNIV_INLINE
ibool
page_rec_check(
/*===========*/
- /* out: TRUE if succeed */
- const rec_t* rec); /* in: record */
-/*******************************************************************
-Gets the record pointed to by a directory slot. */
+ const rec_t* rec); /*!< in: record */
+/***************************************************************//**
+Gets the record pointed to by a directory slot.
+@return pointer to record */
UNIV_INLINE
const rec_t*
page_dir_slot_get_rec(
/*==================*/
- /* out: pointer to record */
- const page_dir_slot_t* slot); /* in: directory slot */
-/*******************************************************************
+ const page_dir_slot_t* slot); /*!< in: directory 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 */
-/*******************************************************************
-Gets the number of records owned by a directory slot. */
+ page_dir_slot_t* slot, /*!< in: directory slot */
+ rec_t* rec); /*!< in: record on the page */
+/***************************************************************//**
+Gets the number of records owned by a directory slot.
+@return number of records */
UNIV_INLINE
ulint
page_dir_slot_get_n_owned(
/*======================*/
- /* out: number of records */
- const page_dir_slot_t* slot); /* in: page directory slot */
-/*******************************************************************
+ const page_dir_slot_t* slot); /*!< in: page directory slot */
+/***************************************************************//**
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 */
-/****************************************************************
+ 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 */
+/************************************************************//**
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
@@ -452,167 +458,167 @@ UNIV_INLINE
ulint
page_dir_calc_reserved_space(
/*=========================*/
- ulint n_recs); /* in: number of records */
-/*******************************************************************
-Looks for the directory slot which owns the given record. */
+ ulint n_recs); /*!< in: number of records */
+/***************************************************************//**
+Looks for the directory slot which owns the given record.
+@return the directory slot number */
UNIV_INTERN
ulint
page_dir_find_owner_slot(
/*=====================*/
- /* out: the directory slot number */
- const rec_t* rec); /* in: the physical record */
-/****************************************************************
-Determine whether the page is in new-style compact format. */
+ const rec_t* rec); /*!< in: the physical record */
+/************************************************************//**
+Determine whether the page is in new-style compact format.
+@return nonzero if the page is in compact format, zero if it is in
+old-style 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 */
-/****************************************************************
-TRUE if the record is on a page in compact format. */
+ const page_t* page); /*!< in: index page */
+/************************************************************//**
+TRUE if the record is on a page in compact format.
+@return nonzero if in compact format */
UNIV_INLINE
ulint
page_rec_is_comp(
/*=============*/
- /* out: nonzero if in compact format */
- const rec_t* rec); /* in: record */
-/*******************************************************************
-Returns the heap number of a record. */
+ const rec_t* rec); /*!< in: record */
+/***************************************************************//**
+Returns the heap number of a record.
+@return heap number */
UNIV_INLINE
ulint
page_rec_get_heap_no(
/*=================*/
- /* out: heap number */
- const rec_t* rec); /* in: the physical record */
-/****************************************************************
-Determine whether the page is a B-tree leaf. */
+ const rec_t* rec); /*!< in: the physical record */
+/************************************************************//**
+Determine whether the page is a B-tree leaf.
+@return TRUE if 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 */
+ const page_t* page) /*!< in: page */
__attribute__((nonnull, pure));
-/****************************************************************
-Gets the pointer to the next record on the page. */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
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 */
-/****************************************************************
-Gets the pointer to the next record on the page. */
+ const rec_t* rec, /*!< in: pointer to record */
+ ulint comp); /*!< in: nonzero=compact page layout */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- /* out: pointer to next record */
- rec_t* rec); /* in: pointer to record */
-/****************************************************************
-Gets the pointer to the next record on the page. */
+ rec_t* rec); /*!< in: pointer to record */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
const rec_t*
page_rec_get_next_const(
/*====================*/
- /* out: pointer to next record */
- const rec_t* rec); /* in: pointer to record */
-/****************************************************************
+ const rec_t* rec); /*!< in: pointer to record */
+/************************************************************//**
Sets the pointer to the next record on the page. */
UNIV_INLINE
void
page_rec_set_next(
/*==============*/
- rec_t* rec, /* in: pointer to record,
+ rec_t* rec, /*!< in: pointer to record,
must not be page supremum */
- rec_t* next); /* in: pointer to next record,
+ rec_t* next); /*!< in: pointer to next record,
must not be page infimum */
-/****************************************************************
-Gets the pointer to the previous record. */
+/************************************************************//**
+Gets the pointer to the previous record.
+@return pointer to 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
+ const rec_t* rec); /*!< in: pointer to record, must not be page
infimum */
-/****************************************************************
-Gets the pointer to the previous record. */
+/************************************************************//**
+Gets the pointer to the previous record.
+@return pointer to previous record */
UNIV_INLINE
rec_t*
page_rec_get_prev(
/*==============*/
- /* out: pointer to previous record */
- rec_t* rec); /* in: pointer to record,
+ rec_t* rec); /*!< in: pointer to record,
must not be page infimum */
-/****************************************************************
-TRUE if the record is a user record on the page. */
+/************************************************************//**
+TRUE if the record is a user record on the page.
+@return TRUE if a user record */
UNIV_INLINE
ibool
page_rec_is_user_rec_low(
/*=====================*/
- /* out: TRUE if a user record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
__attribute__((const));
-/****************************************************************
-TRUE if the record is the supremum record on a page. */
+/************************************************************//**
+TRUE if the record is the supremum record on a page.
+@return TRUE if the supremum record */
UNIV_INLINE
ibool
page_rec_is_supremum_low(
/*=====================*/
- /* out: TRUE if the supremum record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
__attribute__((const));
-/****************************************************************
-TRUE if the record is the infimum record on a page. */
+/************************************************************//**
+TRUE if the record is the infimum record on a page.
+@return TRUE if the infimum record */
UNIV_INLINE
ibool
page_rec_is_infimum_low(
/*====================*/
- /* out: TRUE if the infimum record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
__attribute__((const));
-/****************************************************************
-TRUE if the record is a user record on the page. */
+/************************************************************//**
+TRUE if the record is a user record on the page.
+@return TRUE if a user record */
UNIV_INLINE
ibool
page_rec_is_user_rec(
/*=================*/
- /* out: TRUE if a user record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
__attribute__((const));
-/****************************************************************
-TRUE if the record is the supremum record on a page. */
+/************************************************************//**
+TRUE if the record is the supremum record on a page.
+@return TRUE if the supremum record */
UNIV_INLINE
ibool
page_rec_is_supremum(
/*=================*/
- /* out: TRUE if the supremum record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
__attribute__((const));
-/****************************************************************
-TRUE if the record is the infimum record on a page. */
+/************************************************************//**
+TRUE if the record is the infimum record on a page.
+@return TRUE if the infimum record */
UNIV_INLINE
ibool
page_rec_is_infimum(
/*================*/
- /* out: TRUE if the infimum record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
__attribute__((const));
-/*******************************************************************
-Looks for the record which owns the given record. */
+/***************************************************************//**
+Looks for the record which owns the given record.
+@return the owner record */
UNIV_INLINE
rec_t*
page_rec_find_owner_rec(
/*====================*/
- /* out: the owner record */
- rec_t* rec); /* in: the physical record */
-/***************************************************************************
+ rec_t* rec); /*!< in: the physical record */
+/***********************************************************************//**
This is a low-level operation which is used in a database index creation
to update the page number of a created B-tree to a data dictionary
record. */
@@ -620,245 +626,235 @@ UNIV_INTERN
void
page_rec_write_index_page_no(
/*=========================*/
- rec_t* rec, /* in: record to update */
- ulint i, /* in: index of the field to update */
- ulint page_no,/* in: value to write */
- mtr_t* mtr); /* in: mtr */
-/****************************************************************
+ rec_t* rec, /*!< in: record to update */
+ ulint i, /*!< in: index of the field to update */
+ ulint page_no,/*!< in: value to write */
+ mtr_t* mtr); /*!< in: mtr */
+/************************************************************//**
Returns the maximum combined size of records which can be inserted on top
-of record heap. */
+of record heap.
+@return maximum combined size for inserted records */
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 */
-/****************************************************************
+ const page_t* page, /*!< in: index page */
+ ulint n_recs);/*!< in: number of records */
+/************************************************************//**
Returns the maximum combined size of records which can be inserted on top
-of record heap if page is first reorganized. */
+of record heap if page is first reorganized.
+@return maximum combined size for inserted records */
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 */
-/*****************************************************************
-Calculates free space if a page is emptied. */
+ const page_t* page, /*!< in: index page */
+ ulint n_recs);/*!< in: number of records */
+/*************************************************************//**
+Calculates free space if a page is emptied.
+@return free space */
UNIV_INLINE
ulint
page_get_free_space_of_empty(
/*=========================*/
- /* out: free space */
- ulint comp) /* in: nonzero=compact page format */
+ ulint comp) /*!< in: nonzero=compact page format */
__attribute__((const));
-/**************************************************************
+/**********************************************************//**
Returns the base extra size of a physical record. This is the
-size of the fixed header, independent of the record size. */
+size of the fixed header, independent of the record size.
+@return REC_N_NEW_EXTRA_BYTES or REC_N_OLD_EXTRA_BYTES */
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 */
-/****************************************************************
+ const rec_t* rec); /*!< in: physical record */
+/************************************************************//**
Returns the sum of the sizes of the records in the record list
-excluding the infimum and supremum records. */
+excluding the infimum and supremum records.
+@return data in bytes */
UNIV_INLINE
ulint
page_get_data_size(
/*===============*/
- /* out: data in bytes */
- const page_t* page); /* in: index page */
-/****************************************************************
+ const page_t* page); /*!< in: index page */
+/************************************************************//**
Allocates a block of memory from the head of the free list
of an index page. */
UNIV_INLINE
void
page_mem_alloc_free(
/*================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page with enough
+ 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
+ rec_t* next_rec,/*!< in: pointer to the new head of the
free record list */
- ulint need); /* in: number of bytes allocated */
-/****************************************************************
-Allocates a block of memory from the heap of an index page. */
+ 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(
/*================*/
- /* out: pointer to start of allocated
- buffer, or NULL if allocation fails */
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page with enough
+ 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
+ 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
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() */
-/**************************************************************
-Create an uncompressed B-tree index page. */
+ 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() */
+/**********************************************************//**
+Create an uncompressed B-tree index page.
+@return pointer to the page */
UNIV_INTERN
page_t*
page_create(
/*========*/
- /* out: pointer to the page */
- buf_block_t* block, /* in: a buffer block where the
+ buf_block_t* block, /*!< in: a buffer block where the
page is created */
- mtr_t* mtr, /* in: mini-transaction handle */
- ulint comp); /* in: nonzero=compact page format */
-/**************************************************************
-Create a compressed B-tree index page. */
+ mtr_t* mtr, /*!< in: mini-transaction handle */
+ ulint comp); /*!< in: nonzero=compact page format */
+/**********************************************************//**
+Create a compressed B-tree index page.
+@return pointer to the page */
UNIV_INTERN
page_t*
page_create_zip(
/*============*/
- /* out: pointer to the page */
- buf_block_t* block, /* in/out: a buffer frame where the
+ buf_block_t* block, /*!< in/out: a buffer frame where the
page is created */
- dict_index_t* index, /* in: the index of the page */
- ulint level, /* in: the B-tree level of the page */
- mtr_t* mtr); /* in: mini-transaction handle */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint level, /*!< in: the B-tree level of the page */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
-/*****************************************************************
+/*************************************************************//**
Differs from page_copy_rec_list_end, because this function does not
touch the lock table and max trx id on page or compress the page. */
UNIV_INTERN
void
page_copy_rec_list_end_no_locks(
/*============================*/
- buf_block_t* new_block, /* in: index page to copy to */
- buf_block_t* block, /* in: index page of rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ buf_block_t* new_block, /*!< in: index page to copy to */
+ buf_block_t* block, /*!< in: index page of rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Copies records from page to new_page, from the given record onward,
including that record. Infimum and supremum records are not copied.
-The records are copied to the start of the record list on new_page. */
+The records are copied to the start of the record list on new_page.
+@return pointer to the original successor of the infimum record on
+new_page, or NULL on zip overflow (new_block will be decompressed) */
UNIV_INTERN
rec_t*
page_copy_rec_list_end(
/*===================*/
- /* out: pointer to the original
- successor of the infimum record
- on new_page, or NULL on zip overflow
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page to copy to */
- buf_block_t* block, /* in: index page containing rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page to copy to */
+ buf_block_t* block, /*!< in: index page containing rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
Copies records from page to new_page, up to the given record, NOT
including that record. Infimum and supremum records are not copied.
-The records are copied to the end of the record list on new_page. */
+The records are copied to the end of the record list on new_page.
+@return pointer to the original predecessor of the supremum record on
+new_page, or NULL on zip overflow (new_block will be decompressed) */
UNIV_INTERN
rec_t*
page_copy_rec_list_start(
/*=====================*/
- /* out: pointer to the original
- predecessor of the supremum record
- on new_page, or NULL on zip overflow
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page to copy to */
- buf_block_t* block, /* in: index page containing rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page to copy to */
+ buf_block_t* block, /*!< in: index page containing rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
Deletes records from a page from a given record onward, including that record.
The infimum and supremum records are not deleted. */
UNIV_INTERN
void
page_delete_rec_list_end(
/*=====================*/
- rec_t* rec, /* in: pointer to record on page */
- buf_block_t* block, /* in: buffer block of the page */
- dict_index_t* index, /* in: record descriptor */
- ulint n_recs, /* in: number of records to delete,
+ rec_t* rec, /*!< in: pointer to record on page */
+ buf_block_t* block, /*!< in: buffer block of the page */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n_recs, /*!< in: number of records to delete,
or ULINT_UNDEFINED if not known */
- ulint size, /* in: the sum of the sizes of the
+ ulint size, /*!< in: the sum of the sizes of the
records in the end of the chain to
delete, or ULINT_UNDEFINED if not known */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
Deletes records from page, up to the given record, NOT including
that record. Infimum and supremum records are not deleted. */
UNIV_INTERN
void
page_delete_rec_list_start(
/*=======================*/
- rec_t* rec, /* in: record on page */
- buf_block_t* block, /* in: buffer block of the page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record on page */
+ buf_block_t* block, /*!< in: buffer block of the page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
Moves record list end to another page. Moved records include
-split_rec. */
+split_rec.
+@return TRUE on success; FALSE on compression failure (new_block will
+be decompressed) */
UNIV_INTERN
ibool
page_move_rec_list_end(
/*===================*/
- /* out: TRUE on success; FALSE on
- compression failure
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page where to move */
- buf_block_t* block, /* in: index page from where to move */
- rec_t* split_rec, /* in: first record to move */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page where to move */
+ buf_block_t* block, /*!< in: index page from where to move */
+ rec_t* split_rec, /*!< in: first record to move */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull(1, 2, 4, 5)));
-/*****************************************************************
+/*************************************************************//**
Moves record list start to another page. Moved records do not include
-split_rec. */
+split_rec.
+@return TRUE on success; FALSE on compression failure */
UNIV_INTERN
ibool
page_move_rec_list_start(
/*=====================*/
- /* out: TRUE on success; FALSE on
- compression failure */
- buf_block_t* new_block, /* in/out: index page where to move */
- buf_block_t* block, /* in/out: page containing split_rec */
- rec_t* split_rec, /* in: first record not to move */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page where to move */
+ buf_block_t* block, /*!< in/out: page containing split_rec */
+ rec_t* split_rec, /*!< in: first record not to move */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull(1, 2, 4, 5)));
-/********************************************************************
+/****************************************************************//**
Splits a directory slot which owns too many records. */
UNIV_INTERN
void
page_dir_split_slot(
/*================*/
- page_t* page, /* in: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be written, or NULL */
- ulint slot_no)/* in: the directory slot */
+ ulint slot_no)/*!< in: the directory slot */
__attribute__((nonnull(1)));
-/*****************************************************************
+/*************************************************************//**
Tries to balance the given directory slot with too few records
with the upper neighbor, so that there are at least the minimum number
of records owned by the slot; this may result in the merging of
@@ -867,98 +863,98 @@ UNIV_INTERN
void
page_dir_balance_slot(
/*==================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint slot_no)/* in: the directory slot */
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint slot_no)/*!< in: the directory slot */
__attribute__((nonnull(1)));
-/**************************************************************
-Parses a log record of a record list end or start deletion. */
+/**********************************************************//**
+Parses a log record of a record list end or start deletion.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_delete_rec_list(
/*=======================*/
- /* out: end of log record or NULL */
- byte type, /* in: MLOG_LIST_END_DELETE,
+ byte type, /*!< in: MLOG_LIST_END_DELETE,
MLOG_LIST_START_DELETE,
MLOG_COMP_LIST_END_DELETE or
MLOG_COMP_LIST_START_DELETE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in/out: buffer block or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses a redo log record of creating a page. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in/out: buffer block or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses a redo log record of creating a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_create(
/*==============*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint comp, /* in: nonzero=compact page format */
- buf_block_t* block, /* in: block or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/****************************************************************
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint comp, /*!< in: nonzero=compact page format */
+ buf_block_t* block, /*!< in: block or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/************************************************************//**
Prints record contents including the data relevant only in
the index page context. */
UNIV_INTERN
void
page_rec_print(
/*===========*/
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: record descriptor */
-/*******************************************************************
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: record descriptor */
+/***************************************************************//**
This is used to print the contents of the directory for
debugging purposes. */
UNIV_INTERN
void
page_dir_print(
/*===========*/
- page_t* page, /* in: index page */
- ulint pr_n); /* in: print n first and n last entries */
-/*******************************************************************
+ page_t* page, /*!< in: index page */
+ ulint pr_n); /*!< in: print n first and n last entries */
+/***************************************************************//**
This is used to print the contents of the page record list for
debugging purposes. */
UNIV_INTERN
void
page_print_list(
/*============*/
- buf_block_t* block, /* in: index page */
- dict_index_t* index, /* in: dictionary index of the page */
- ulint pr_n); /* in: print n first and n last entries */
-/*******************************************************************
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index, /*!< in: dictionary index of the page */
+ ulint pr_n); /*!< in: print n first and n last entries */
+/***************************************************************//**
Prints the info in a page header. */
UNIV_INTERN
void
page_header_print(
/*==============*/
- const page_t* page);
-/*******************************************************************
+ const page_t* page); /*!< in: index page */
+/***************************************************************//**
This is used to print the contents of the page for
debugging purposes. */
UNIV_INTERN
void
page_print(
/*=======*/
- buf_block_t* block, /* in: index page */
- dict_index_t* index, /* in: dictionary index of the page */
- ulint dn, /* in: print dn first and last entries
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index, /*!< in: dictionary index of the page */
+ ulint dn, /*!< in: print dn first and last entries
in directory */
- ulint rn); /* in: print rn first and last records
+ ulint rn); /*!< in: print rn first and last records
in directory */
-/*******************************************************************
+/***************************************************************//**
The following is used to validate a record on a page. This function
differs from rec_validate as it can also check the n_owned field and
-the heap_no field. */
+the heap_no field.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_rec_validate(
/*==============*/
- /* out: TRUE if ok */
- rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
+ rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Checks that the first directory slot points to the infimum record and
the last to the supremum. This function is intended to track if the
bug fixed in 4.0.14 has caused corruption to users' databases. */
@@ -966,46 +962,46 @@ UNIV_INTERN
void
page_check_dir(
/*===========*/
- const page_t* page); /* in: index page */
-/*******************************************************************
+ const page_t* page); /*!< in: index page */
+/***************************************************************//**
This function checks the consistency of an index page when we do not
know the index. This is also resilient so that this should never crash
-even if the page is total garbage. */
+even if the page is total garbage.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_simple_validate_old(
/*=====================*/
- /* out: TRUE if ok */
- page_t* page); /* in: old-style index page */
-/*******************************************************************
+ page_t* page); /*!< in: old-style index page */
+/***************************************************************//**
This function checks the consistency of an index page when we do not
know the index. This is also resilient so that this should never crash
-even if the page is total garbage. */
+even if the page is total garbage.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_simple_validate_new(
/*=====================*/
- /* out: TRUE if ok */
- page_t* block); /* in: new-style index page */
-/*******************************************************************
-This function checks the consistency of an index page. */
+ page_t* block); /*!< in: new-style index page */
+/***************************************************************//**
+This function checks the consistency of an index page.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_validate(
/*==========*/
- /* out: TRUE if ok */
- page_t* page, /* in: index page */
- dict_index_t* index); /* in: data dictionary index containing
+ page_t* page, /*!< in: index page */
+ dict_index_t* index); /*!< in: data dictionary index containing
the page record type definition */
-/*******************************************************************
-Looks in the page record list for a record with the given heap number. */
+/***************************************************************//**
+Looks in the page record list for a record with the given heap number.
+@return record, NULL if not found */
const rec_t*
page_find_rec_with_heap_no(
/*=======================*/
- /* out: record, NULL if not found */
- const page_t* page, /* in: index page */
- ulint heap_no);/* in: heap number */
+ const page_t* page, /*!< in: index page */
+ ulint heap_no);/*!< in: heap number */
#ifdef UNIV_MATERIALIZE
#undef UNIV_INLINE
diff --git a/storage/xtradb/include/page0page.ic b/storage/xtradb/include/page0page.ic
index df0f6f8b360..8f794410f20 100644
--- a/storage/xtradb/include/page0page.ic
+++ b/storage/xtradb/include/page0page.ic
@@ -16,14 +16,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0page.ic
Index page routines
Created 2/2/1994 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
-#include "rem0cmp.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"
@@ -32,70 +38,80 @@ Created 2/2/1994 Heikki Tuuri
#define UNIV_INLINE
#endif
-/****************************************************************
-Gets the start of a page. */
+/************************************************************//**
+Gets the start of a page.
+@return start of the page */
UNIV_INLINE
page_t*
page_align(
/*=======*/
- /* out: start of the page */
- const void* ptr) /* in: pointer to page frame */
+ const void* ptr) /*!< in: pointer to page frame */
{
return((page_t*) ut_align_down(ptr, UNIV_PAGE_SIZE));
}
-/****************************************************************
-Gets the offset within a page. */
+/************************************************************//**
+Gets the offset within a page.
+@return offset from the start of the page */
UNIV_INLINE
ulint
page_offset(
/*========*/
- /* out: offset from the start of the page */
- const void* ptr) /* in: pointer to page frame */
+ 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
-dulint
+trx_id_t
page_get_max_trx_id(
/*================*/
- const page_t* page) /* in: page */
+ 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
+ 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 */
- dulint trx_id) /* in: transaction id */
+ 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);
+ 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, ... */
+ const page_t* page, /*!< in: page */
+ ulint field) /*!< in: PAGE_LEVEL, ... */
{
ut_ad(page);
ut_ad(field <= PAGE_INDEX_ID);
@@ -103,17 +119,17 @@ page_header_get_field(
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
+ 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 */
+ ulint field, /*!< in: PAGE_N_DIR_SLOTS, ... */
+ ulint val) /*!< in: value */
{
ut_ad(page);
ut_ad(field <= PAGE_N_RECS);
@@ -127,16 +143,15 @@ page_header_set_field(
}
}
-/*****************************************************************
-Returns the offset stored in the given header field. */
+/*************************************************************//**
+Returns the offset stored in the given header field.
+@return offset from the start of the page, or 0 */
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, ... */
+ const page_t* page, /*!< in: page */
+ ulint field) /*!< in: PAGE_FREE, ... */
{
ulint offs;
@@ -152,17 +167,17 @@ page_header_get_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
+ 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 field, /*!< in: PAGE_FREE, ... */
+ const byte* ptr) /*!< in: pointer or NULL*/
{
ulint offs;
@@ -182,17 +197,18 @@ page_header_set_ptr(
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
+ 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 */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(page && mtr);
@@ -206,41 +222,42 @@ page_header_reset_last_insert(
MLOG_2BYTES, mtr);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/****************************************************************
-Determine whether the page is in new-style compact format. */
+/************************************************************//**
+Determine whether the page is in new-style compact format.
+@return nonzero if the page is in compact format, zero if it is in
+old-style 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 */
+ 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. */
+/************************************************************//**
+TRUE if the record is on a page in compact format.
+@return nonzero if in compact format */
UNIV_INLINE
ulint
page_rec_is_comp(
/*=============*/
- /* out: nonzero if in compact format */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
{
return(page_is_comp(page_align(rec)));
}
-/*******************************************************************
-Returns the heap number of a record. */
+/***************************************************************//**
+Returns the heap number of a record.
+@return heap number */
UNIV_INLINE
ulint
page_rec_get_heap_no(
/*=================*/
- /* out: heap number */
- const rec_t* rec) /* in: the physical record */
+ const rec_t* rec) /*!< in: the physical record */
{
if (page_rec_is_comp(rec)) {
return(rec_get_heap_no_new(rec));
@@ -249,27 +266,26 @@ page_rec_get_heap_no(
}
}
-/****************************************************************
-Determine whether the page is a B-tree leaf. */
+/************************************************************//**
+Determine whether the page is a B-tree leaf.
+@return TRUE if 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 */
+ const page_t* page) /*!< in: page */
{
return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
}
-/****************************************************************
-Gets the offset of the first record on the page. */
+/************************************************************//**
+Gets the offset of the first record on the page.
+@return offset of the first record in record list, relative from 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) */
+ const page_t* page) /*!< in: page which must have record(s) */
{
ut_ad(page);
ut_ad(!page_offset(page));
@@ -281,15 +297,14 @@ page_get_infimum_offset(
}
}
-/****************************************************************
-Gets the offset of the last record on the page. */
+/************************************************************//**
+Gets the offset of the last record on the page.
+@return offset of the last record in record list, relative from 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) */
+ const page_t* page) /*!< in: page which must have record(s) */
{
ut_ad(page);
ut_ad(!page_offset(page));
@@ -301,14 +316,14 @@ page_get_supremum_offset(
}
}
-/****************************************************************
-TRUE if the record is a user record on the page. */
+/************************************************************//**
+TRUE if the record is a user record on the page.
+@return TRUE if a user record */
UNIV_INLINE
ibool
page_rec_is_user_rec_low(
/*=====================*/
- /* out: TRUE if a user record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
#if PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM
@@ -337,14 +352,14 @@ page_rec_is_user_rec_low(
&& UNIV_LIKELY(offset != PAGE_OLD_SUPREMUM));
}
-/****************************************************************
-TRUE if the record is the supremum record on a page. */
+/************************************************************//**
+TRUE if the record is the supremum record on a page.
+@return TRUE if the supremum record */
UNIV_INLINE
ibool
page_rec_is_supremum_low(
/*=====================*/
- /* out: TRUE if the supremum record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
@@ -353,14 +368,14 @@ page_rec_is_supremum_low(
|| UNIV_UNLIKELY(offset == PAGE_OLD_SUPREMUM));
}
-/****************************************************************
-TRUE if the record is the infimum record on a page. */
+/************************************************************//**
+TRUE if the record is the infimum record on a page.
+@return TRUE if the infimum record */
UNIV_INLINE
ibool
page_rec_is_infimum_low(
/*====================*/
- /* out: TRUE if the infimum record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
@@ -369,65 +384,65 @@ page_rec_is_infimum_low(
|| UNIV_UNLIKELY(offset == PAGE_OLD_INFIMUM));
}
-/****************************************************************
-TRUE if the record is a user record on the page. */
+/************************************************************//**
+TRUE if the record is a user record on the page.
+@return TRUE if a user record */
UNIV_INLINE
ibool
page_rec_is_user_rec(
/*=================*/
- /* out: TRUE if a user record */
- const rec_t* rec) /* in: 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. */
+/************************************************************//**
+TRUE if the record is the supremum record on a page.
+@return TRUE if the supremum record */
UNIV_INLINE
ibool
page_rec_is_supremum(
/*=================*/
- /* out: TRUE if the supremum record */
- const rec_t* rec) /* in: 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. */
+/************************************************************//**
+TRUE if the record is the infimum record on a page.
+@return TRUE if the infimum record */
UNIV_INLINE
ibool
page_rec_is_infimum(
/*================*/
- /* out: TRUE if the infimum record */
- const rec_t* rec) /* in: 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. */
+the positive infinity in the alphabetical order.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared */
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
+ 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
+ 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
+ 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 */
@@ -453,96 +468,97 @@ page_cmp_dtuple_rec_with_match(
matched_fields,
matched_bytes));
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
-Gets the page number. */
+/*************************************************************//**
+Gets the page number.
+@return page number */
UNIV_INLINE
ulint
page_get_page_no(
/*=============*/
- /* out: page number */
- const page_t* page) /* in: page */
+ 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. */
+/*************************************************************//**
+Gets the tablespace identifier.
+@return space id */
UNIV_INLINE
ulint
page_get_space_id(
/*==============*/
- /* out: space id */
- const page_t* page) /* in: page */
+ 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). */
+are not user records).
+@return number of user records */
UNIV_INLINE
ulint
page_get_n_recs(
/*============*/
- /* out: number of user records */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
return(page_header_get_field(page, PAGE_N_RECS));
}
-/*****************************************************************
-Gets the number of dir slots in directory. */
+/*************************************************************//**
+Gets the number of dir slots in directory.
+@return number of slots */
UNIV_INLINE
ulint
page_dir_get_n_slots(
/*=================*/
- /* out: number of slots */
- const page_t* page) /* in: index page */
+ 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
+ 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 */
+ 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. */
+/*************************************************************//**
+Gets the number of records in the heap.
+@return number of user records */
UNIV_INLINE
ulint
page_dir_get_n_heap(
/*================*/
- /* out: number of user records */
- const page_t* page) /* in: index page */
+ 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
+ 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 */
+ ulint n_heap) /*!< in: number of records */
{
ut_ad(n_heap < 0x8000);
ut_ad(!page_zip || n_heap
@@ -554,15 +570,15 @@ page_dir_set_n_heap(
}
#ifdef UNIV_DEBUG
-/*****************************************************************
-Gets pointer to nth directory slot. */
+/*************************************************************//**
+Gets pointer to nth directory slot.
+@return pointer to dir 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 */
+ const page_t* page, /*!< in: index page */
+ ulint n) /*!< in: position */
{
ut_ad(page_dir_get_n_slots(page) > n);
@@ -572,14 +588,14 @@ page_dir_get_nth_slot(
}
#endif /* UNIV_DEBUG */
-/******************************************************************
-Used to check the consistency of a record on a page. */
+/**************************************************************//**
+Used to check the consistency of a record on a page.
+@return TRUE if succeed */
UNIV_INLINE
ibool
page_rec_check(
/*===========*/
- /* out: TRUE if succeed */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
{
const page_t* page = page_align(rec);
@@ -591,40 +607,40 @@ page_rec_check(
return(TRUE);
}
-/*******************************************************************
-Gets the record pointed to by a directory slot. */
+/***************************************************************//**
+Gets the record pointed to by a directory slot.
+@return pointer to record */
UNIV_INLINE
const rec_t*
page_dir_slot_get_rec(
/*==================*/
- /* out: pointer to record */
- const page_dir_slot_t* slot) /* in: directory slot */
+ 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 */
+ 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. */
+/***************************************************************//**
+Gets the number of records owned by a directory slot.
+@return number of records */
UNIV_INLINE
ulint
page_dir_slot_get_n_owned(
/*======================*/
- /* out: number of records */
- const page_dir_slot_t* slot) /* in: page directory slot */
+ 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)) {
@@ -634,15 +650,15 @@ page_dir_slot_get_n_owned(
}
}
-/*******************************************************************
+/***************************************************************//**
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 */
+ 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)) {
@@ -653,7 +669,7 @@ page_dir_slot_set_n_owned(
}
}
-/****************************************************************
+/************************************************************//**
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. */
@@ -661,21 +677,21 @@ UNIV_INLINE
ulint
page_dir_calc_reserved_space(
/*=========================*/
- ulint n_recs) /* in: number of records */
+ 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. */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
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 */
+ const rec_t* rec, /*!< in: pointer to record */
+ ulint comp) /*!< in: nonzero=compact page layout */
{
ulint offs;
const page_t* page;
@@ -708,39 +724,39 @@ page_rec_get_next_low(
return(page + offs);
}
-/****************************************************************
-Gets the pointer to the next record on the page. */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- /* out: pointer to next record */
- rec_t* rec) /* in: pointer to 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. */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
const rec_t*
page_rec_get_next_const(
/*====================*/
- /* out: pointer to next record */
- const rec_t* rec) /* in: pointer to 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,
+ rec_t* rec, /*!< in: pointer to record,
must not be page supremum */
- rec_t* next) /* in: pointer to next record,
+ rec_t* next) /*!< in: pointer to next record,
must not be page infimum */
{
ulint offs;
@@ -765,14 +781,14 @@ page_rec_set_next(
}
}
-/****************************************************************
-Gets the pointer to the previous record. */
+/************************************************************//**
+Gets the pointer to the previous record.
+@return pointer to 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
+ const rec_t* rec) /*!< in: pointer to record, must not be page
infimum */
{
const page_dir_slot_t* slot;
@@ -812,27 +828,27 @@ page_rec_get_prev_const(
return(prev_rec);
}
-/****************************************************************
-Gets the pointer to the previous record. */
+/************************************************************//**
+Gets the pointer to the previous record.
+@return pointer to 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
+ 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. */
+/***************************************************************//**
+Looks for the record which owns the given record.
+@return the owner record */
UNIV_INLINE
rec_t*
page_rec_find_owner_rec(
/*====================*/
- /* out: the owner record */
- rec_t* rec) /* in: the physical record */
+ rec_t* rec) /*!< in: the physical record */
{
ut_ad(page_rec_check(rec));
@@ -849,16 +865,15 @@ page_rec_find_owner_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. */
+size of the fixed header, independent of the record size.
+@return REC_N_NEW_EXTRA_BYTES or REC_N_OLD_EXTRA_BYTES */
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 */
+ 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"
@@ -866,15 +881,15 @@ page_rec_get_base_extra_size(
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. */
+the infimum and supremum records.
+@return data in bytes */
UNIV_INLINE
ulint
page_get_data_size(
/*===============*/
- /* out: data in bytes */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
ulint ret;
@@ -890,19 +905,19 @@ page_get_data_size(
}
-/****************************************************************
+/************************************************************//**
Allocates a block of memory from the free list of an index page. */
-UNIV_INTERN
+UNIV_INLINE
void
page_mem_alloc_free(
/*================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page with enough
+ 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
+ rec_t* next_rec,/*!< in: pointer to the new head of the
free record list */
- ulint need) /* in: number of bytes allocated */
+ ulint need) /*!< in: number of bytes allocated */
{
ulint garbage;
@@ -923,14 +938,14 @@ page_mem_alloc_free(
page_header_set_field(page, page_zip, PAGE_GARBAGE, garbage - need);
}
-/*****************************************************************
-Calculates free space if a page is emptied. */
+/*************************************************************//**
+Calculates free space if a page is emptied.
+@return free space */
UNIV_INLINE
ulint
page_get_free_space_of_empty(
/*=========================*/
- /* out: free space */
- ulint comp) /* in: nonzero=compact page layout */
+ ulint comp) /*!< in: nonzero=compact page layout */
{
if (UNIV_LIKELY(comp)) {
return((ulint)(UNIV_PAGE_SIZE
@@ -945,21 +960,20 @@ page_get_free_space_of_empty(
- 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. */
+which can be inserted on top of the record heap.
+@return maximum combined size for inserted records */
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 */
+ const page_t* page, /*!< in: index page */
+ ulint n_recs) /*!< in: number of records */
{
ulint occupied;
ulint free_space;
@@ -992,17 +1006,16 @@ page_get_max_insert_size(
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. */
+of the record heap if a page is first reorganized.
+@return maximum combined size for inserted records */
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 */
+ const page_t* page, /*!< in: index page */
+ ulint n_recs) /*!< in: number of records */
{
ulint occupied;
ulint free_space;
@@ -1020,17 +1033,17 @@ page_get_max_insert_size_after_reorganize(
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() */
+ 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;
diff --git a/storage/xtradb/include/page0types.h b/storage/xtradb/include/page0types.h
index 06af7a63d58..d9a277bf208 100644
--- a/storage/xtradb/include/page0types.h
+++ b/storage/xtradb/include/page0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0types.h
Index page routines
Created 2/2/1994 Heikki Tuuri
@@ -29,46 +30,52 @@ Created 2/2/1994 Heikki Tuuri
#include "dict0types.h"
#include "mtr0types.h"
-/* Type of the index page */
-/* The following define eliminates a name collision on HP-UX */
+/** Eliminates a name collision on HP-UX */
#define page_t ib_page_t
+/** Type of the index page */
typedef byte page_t;
-typedef struct page_search_struct page_search_t;
+/** Index page cursor */
typedef struct page_cur_struct page_cur_t;
+/** Compressed index page */
typedef byte page_zip_t;
+/** Compressed page descriptor */
typedef struct page_zip_des_struct page_zip_des_t;
/* The following definitions would better belong to page0zip.h,
but we cannot include page0zip.h from rem0rec.ic, because
page0*.h includes rem0rec.h and may include rem0rec.ic. */
+/** Number of bits needed for representing different compressed page sizes */
#define PAGE_ZIP_SSIZE_BITS 3
-#define PAGE_ZIP_MIN_SIZE_SHIFT 10 /* log2 of smallest compressed size */
+/** log2 of smallest compressed page size */
+#define PAGE_ZIP_MIN_SIZE_SHIFT 10
+/** Smallest compressed page size */
#define PAGE_ZIP_MIN_SIZE (1 << PAGE_ZIP_MIN_SIZE_SHIFT)
+/** Number of supported compressed page sizes */
#define PAGE_ZIP_NUM_SSIZE (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 2)
#if PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)
# error "PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)"
#endif
-/* Compressed page descriptor */
+/** Compressed page descriptor */
struct page_zip_des_struct
{
- page_zip_t* data; /* compressed page data */
+ page_zip_t* data; /*!< compressed page data */
#ifdef UNIV_DEBUG
- unsigned m_start:16; /* start offset of modification log */
+ unsigned m_start:16; /*!< start offset of modification log */
#endif /* UNIV_DEBUG */
- unsigned m_end:16; /* end offset of modification log */
- unsigned m_nonempty:1; /* TRUE if the modification log
+ unsigned m_end:16; /*!< end offset of modification log */
+ unsigned m_nonempty:1; /*!< TRUE if the modification log
is not empty */
- unsigned n_blobs:12; /* number of externally stored
+ unsigned n_blobs:12; /*!< number of externally stored
columns on the page; the maximum
is 744 on a 16 KiB page */
unsigned ssize:PAGE_ZIP_SSIZE_BITS;
- /* 0 or compressed page size;
+ /*!< 0 or compressed page size;
the size in bytes is
PAGE_ZIP_MIN_SIZE << (ssize - 1). */
};
@@ -87,56 +94,57 @@ struct page_zip_stat_struct {
ib_uint64_t decompressed_usec;
};
+/** Compression statistics */
typedef struct page_zip_stat_struct page_zip_stat_t;
-/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
+/** Statistics on compression, indexed by page_zip_des_struct::ssize - 1 */
extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
-/**************************************************************************
+/**********************************************************************//**
Write the "deleted" flag of a record on a compressed page. The flag must
already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_deleted(
/*=====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the deleted flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Write the "owned" flag of a record on a compressed page. The n_owned field
must already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_owned(
/*===================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the owned flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the owned flag (nonzero=TRUE) */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Shift the dense page directory when a record is deleted. */
UNIV_INTERN
void
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 byte* free) /* in: previous start of the free list */
+ 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 byte* free) /*!< in: previous start of the free list */
__attribute__((nonnull(1,2,3,4)));
-/**************************************************************************
+/**********************************************************************//**
Add a slot to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_add_slot(
/*==================*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint is_clustered) /* in: nonzero for clustered index,
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint is_clustered) /*!< in: nonzero for clustered index,
zero for others */
__attribute__((nonnull));
#endif
diff --git a/storage/xtradb/include/page0zip.h b/storage/xtradb/include/page0zip.h
index 0183e013d05..574809e5227 100644
--- a/storage/xtradb/include/page0zip.h
+++ b/storage/xtradb/include/page0zip.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0zip.h
Compressed page interface
Created June 2005 by Marko Makela
@@ -34,334 +35,336 @@ Created June 2005 by Marko Makela
#include "page0types.h"
#include "buf0types.h"
#include "dict0types.h"
+#include "trx0types.h"
#include "mem0mem.h"
-/**************************************************************************
-Determine the size of a compressed page in bytes. */
+/**********************************************************************//**
+Determine the size of a compressed page in bytes.
+@return size in bytes */
UNIV_INLINE
ulint
page_zip_get_size(
/*==============*/
- /* out: size in bytes */
- const page_zip_des_t* page_zip) /* in: compressed page */
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
__attribute__((nonnull, pure));
-/**************************************************************************
+/**********************************************************************//**
Set the size of a compressed page in bytes. */
UNIV_INLINE
void
page_zip_set_size(
/*==============*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint size); /* in: size in bytes */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint size); /*!< in: size in bytes */
-/**************************************************************************
-Determine if a record is so big that it needs to be stored externally. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Determine if a record is so big that it needs to be stored externally.
+@return FALSE if the entire record can be stored locally on the page */
UNIV_INLINE
ibool
page_zip_rec_needs_ext(
/*===================*/
- /* out: FALSE if the entire record
- can be stored locally on the page */
- ulint rec_size, /* in: length of the record in bytes */
- ulint comp, /* in: nonzero=compact format */
- ulint n_fields, /* in: number of fields in the record;
+ ulint rec_size, /*!< in: length of the record in bytes */
+ ulint comp, /*!< in: nonzero=compact format */
+ ulint n_fields, /*!< in: number of fields in the record;
ignored if zip_size == 0 */
- ulint zip_size) /* in: compressed page size in bytes, or 0 */
+ ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
__attribute__((const));
-/**************************************************************************
-Determine the guaranteed free space on an empty page. */
+/**********************************************************************//**
+Determine the guaranteed free space on an empty page.
+@return minimum payload size on the page */
UNIV_INTERN
ulint
page_zip_empty_size(
/*================*/
- /* out: minimum payload size on the page */
- ulint n_fields, /* in: number of columns in the index */
- ulint zip_size) /* in: compressed page size in bytes */
+ ulint n_fields, /*!< in: number of columns in the index */
+ ulint zip_size) /*!< in: compressed page size in bytes */
__attribute__((const));
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Initialize a compressed page descriptor. */
UNIV_INLINE
void
page_zip_des_init(
/*==============*/
- page_zip_des_t* page_zip); /* in/out: compressed page
+ page_zip_des_t* page_zip); /*!< in/out: compressed page
descriptor */
-/**************************************************************************
+/**********************************************************************//**
Configure the zlib allocator to use the given memory heap. */
UNIV_INTERN
void
page_zip_set_alloc(
/*===============*/
- void* stream, /* in/out: zlib stream */
- mem_heap_t* heap); /* in: memory heap to use */
+ void* stream, /*!< in/out: zlib stream */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/**************************************************************************
-Compress a page. */
+/**********************************************************************//**
+Compress a page.
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure. */
UNIV_INTERN
ibool
page_zip_compress(
/*==============*/
- /* out: TRUE on success, FALSE on failure;
- page_zip will be left intact on failure. */
- page_zip_des_t* page_zip,/* in: size; out: data, n_blobs,
+ page_zip_des_t* page_zip,/*!< in: size; out: data, n_blobs,
m_start, m_end, m_nonempty */
- const page_t* page, /* in: uncompressed page */
- dict_index_t* index, /* in: index of the B-tree node */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ const page_t* page, /*!< in: uncompressed page */
+ dict_index_t* index, /*!< in: index of the B-tree node */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2,3)));
-/**************************************************************************
+/**********************************************************************//**
Decompress a page. This function should tolerate errors on the compressed
page. Instead of letting assertions fail, it will return FALSE if an
-inconsistency is detected. */
+inconsistency is detected.
+@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
page_zip_decompress(
/*================*/
- /* out: TRUE on success, FALSE on failure */
- page_zip_des_t* page_zip,/* in: data, ssize;
+ page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
- page_t* page) /* out: uncompressed page, may be trashed */
- __attribute__((nonnull));
+ page_t* page, /*!< out: uncompressed page, may be trashed */
+ ibool all) /*!< in: TRUE=decompress the whole page;
+ FALSE=verify but do not copy some
+ page header fields that should not change
+ after page creation */
+ __attribute__((nonnull(1,2)));
#ifdef UNIV_DEBUG
-/**************************************************************************
-Validate a compressed page descriptor. */
+/**********************************************************************//**
+Validate a compressed page descriptor.
+@return TRUE if ok */
UNIV_INLINE
ibool
page_zip_simple_validate(
/*=====================*/
- /* out: TRUE if ok */
- const page_zip_des_t* page_zip); /* in: compressed page
+ const page_zip_des_t* page_zip); /*!< in: compressed page
descriptor */
#endif /* UNIV_DEBUG */
#ifdef UNIV_ZIP_DEBUG
-/**************************************************************************
-Check that the compressed and decompressed pages match. */
+/**********************************************************************//**
+Check that the compressed and decompressed pages match.
+@return TRUE if valid, FALSE if not */
UNIV_INTERN
ibool
page_zip_validate_low(
/*==================*/
- /* out: TRUE if valid, FALSE if not */
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page, /* in: uncompressed page */
- ibool sloppy) /* in: FALSE=strict,
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page, /*!< in: uncompressed page */
+ ibool sloppy) /*!< in: FALSE=strict,
TRUE=ignore the MIN_REC_FLAG */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Check that the compressed and decompressed pages match. */
UNIV_INTERN
ibool
page_zip_validate(
/*==============*/
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page) /* in: uncompressed page */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page) /*!< in: uncompressed page */
__attribute__((nonnull));
#endif /* UNIV_ZIP_DEBUG */
-/**************************************************************************
-Determine how big record can be inserted without recompressing the page. */
+/**********************************************************************//**
+Determine how big record can be inserted without recompressing the page.
+@return a positive number indicating the maximum size of a record
+whose insertion is guaranteed to succeed, or zero or negative */
UNIV_INLINE
lint
page_zip_max_ins_size(
/*==================*/
- /* out: a positive number
- indicating the maximum size of
- a record whose insertion is
- guaranteed to succeed, or
- zero or negative */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust)/* in: TRUE if clustered index */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust)/*!< in: TRUE if clustered index */
__attribute__((nonnull, pure));
-/**************************************************************************
-Determine if enough space is available in the modification log. */
+/**********************************************************************//**
+Determine if enough space is available in the modification log.
+@return TRUE if page_zip_write_rec() will succeed */
UNIV_INLINE
ibool
page_zip_available(
/*===============*/
- /* out: TRUE if page_zip_write_rec()
- will succeed */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust,/* in: TRUE if clustered index */
- ulint length, /* in: combined size of the record */
- ulint create) /* in: nonzero=add the record to
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust,/*!< in: TRUE if clustered index */
+ ulint length, /*!< in: combined size of the record */
+ ulint create) /*!< in: nonzero=add the record to
the heap */
__attribute__((nonnull, pure));
-/**************************************************************************
+/**********************************************************************//**
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page. */
UNIV_INLINE
void
page_zip_write_header(
/*==================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* str, /* in: address on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* str, /*!< in: address on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
-/**************************************************************************
+/**********************************************************************//**
Write an entire record on the compressed page. The data must already
have been written to the uncompressed page. */
UNIV_INTERN
void
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) */
- ulint create) /* in: nonzero=insert, zero=update */
+ 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) */
+ ulint create) /*!< in: nonzero=insert, zero=update */
__attribute__((nonnull));
-/***************************************************************
-Parses a log record of writing a BLOB pointer of a record. */
+/***********************************************************//**
+Parses a log record of writing a BLOB pointer of a record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_blob_ptr(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip);/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip);/*!< in/out: compressed page */
-/**************************************************************************
+/**********************************************************************//**
Write a BLOB pointer of a record on the leaf page of a clustered index.
The information must already have been updated on the uncompressed page. */
UNIV_INTERN
void
page_zip_write_blob_ptr(
/*====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in/out: record whose data is being
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ 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) */
- ulint n, /* in: column index */
- mtr_t* mtr) /* in: mini-transaction handle,
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* 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 */
__attribute__((nonnull(1,2,3,4)));
-/***************************************************************
-Parses a log record of writing the node pointer of a record. */
+/***********************************************************//**
+Parses a log record of writing the node pointer of a record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_node_ptr(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip);/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip);/*!< in/out: compressed page */
-/**************************************************************************
+/**********************************************************************//**
Write the node pointer of a record on a non-leaf compressed page. */
UNIV_INTERN
void
page_zip_write_node_ptr(
/*====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in/out: record */
- ulint size, /* in: data size of rec */
- ulint ptr, /* in: node pointer */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in/out: record */
+ ulint size, /*!< in: data size of rec */
+ ulint ptr, /*!< in: node pointer */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
-/**************************************************************************
+/**********************************************************************//**
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
UNIV_INTERN
void
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) */
- ulint trx_id_col,/* in: column number of TRX_ID in rec */
- dulint trx_id, /* in: transaction identifier */
- dulint roll_ptr)/* in: 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) */
+ 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 */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Write the "deleted" flag of a record on a compressed page. The flag must
already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_deleted(
/*=====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the deleted flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Write the "owned" flag of a record on a compressed page. The n_owned field
must already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_owned(
/*===================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the owned flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the owned flag (nonzero=TRUE) */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Insert a record to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_insert(
/*================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* prev_rec,/* in: record after which to insert */
- const byte* free_rec,/* in: record from which rec was
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* prev_rec,/*!< in: record after which to insert */
+ const byte* free_rec,/*!< in: record from which rec was
allocated, or NULL */
- byte* rec); /* in: record to insert */
+ byte* rec); /*!< in: record to insert */
-/**************************************************************************
+/**********************************************************************//**
Shift the dense page directory and the array of BLOB pointers
when a record is deleted. */
UNIV_INTERN
void
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 byte* free) /* in: previous start of the free list */
+ 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 byte* free) /*!< in: previous start of the free list */
__attribute__((nonnull(1,2,3,4)));
-/**************************************************************************
+/**********************************************************************//**
Add a slot to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_add_slot(
/*==================*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint is_clustered) /* in: nonzero for clustered index,
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint is_clustered) /*!< in: nonzero for clustered index,
zero for others */
__attribute__((nonnull));
-/***************************************************************
-Parses a log record of writing to the header of a page. */
+/***********************************************************//**
+Parses a log record of writing to the header of a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_header(
/*========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip);/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip);/*!< in/out: compressed page */
-/**************************************************************************
+/**********************************************************************//**
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page.
However, the data portion of the uncompressed page may differ from
@@ -371,13 +374,13 @@ UNIV_INLINE
void
page_zip_write_header(
/*==================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* str, /* in: address on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* str, /*!< in: address on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
-/**************************************************************************
+/**********************************************************************//**
Reorganize and compress a page. This is a low-level operation for
compressed pages, to be used when page_zip_compress() fails.
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.
@@ -385,22 +388,22 @@ The function btr_page_reorganize() should be preferred whenever possible.
IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
-will be redo-logged. */
+will be redo-logged.
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure, but page will be overwritten. */
UNIV_INTERN
ibool
page_zip_reorganize(
/*================*/
- /* out: TRUE on success, FALSE on failure;
- page and page_zip will be left intact
- on failure. */
- buf_block_t* block, /* in/out: page with compressed page;
+ buf_block_t* block, /*!< in/out: page with compressed page;
on the compressed page, in: size;
out: data, n_blobs,
m_start, m_end, m_nonempty */
- dict_index_t* index, /* in: index of the B-tree node */
- mtr_t* mtr) /* in: mini-transaction */
+ dict_index_t* index, /*!< in: index of the B-tree node */
+ mtr_t* mtr) /*!< in: mini-transaction */
__attribute__((nonnull));
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Copy the records of a page byte for byte. Do not copy the page header
or trailer, except those B-tree header fields that are directly
related to the storage of records. Also copy PAGE_MAX_TRX_ID.
@@ -409,40 +412,57 @@ UNIV_INTERN
void
page_zip_copy_recs(
/*===============*/
- page_zip_des_t* page_zip, /* out: copy of src_zip
+ page_zip_des_t* page_zip, /*!< out: copy of src_zip
(n_blobs, m_start, m_end,
m_nonempty, data[0..size-1]) */
- page_t* page, /* out: copy of src */
- const page_zip_des_t* src_zip, /* in: compressed page */
- const page_t* src, /* in: page */
- dict_index_t* index, /* in: index of the B-tree */
- mtr_t* mtr) /* in: mini-transaction */
+ page_t* page, /*!< out: copy of src */
+ const page_zip_des_t* src_zip, /*!< in: compressed page */
+ const page_t* src, /*!< in: page */
+ dict_index_t* index, /*!< in: index of the B-tree */
+ mtr_t* mtr) /*!< in: mini-transaction */
__attribute__((nonnull(1,2,3,4)));
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Parses a log record of compressing an index page. */
+/**********************************************************************//**
+Parses a log record of compressing an index page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_compress(
/*====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* out: uncompressed page */
- page_zip_des_t* page_zip)/* out: compressed page */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< out: compressed page */
__attribute__((nonnull(1,2)));
-/**************************************************************************
-Calculate the compressed page checksum. */
+/**********************************************************************//**
+Calculate the compressed page checksum.
+@return page checksum */
UNIV_INTERN
ulint
page_zip_calc_checksum(
/*===================*/
- /* out: page checksum */
- const void* data, /* in: compressed page */
- ulint size) /* in: size of compressed page */
+ const void* data, /*!< in: compressed page */
+ ulint size) /*!< in: size of compressed page */
__attribute__((nonnull));
+#ifndef UNIV_HOTBACKUP
+/** Check if a pointer to an uncompressed page matches a compressed page.
+@param ptr pointer to an uncompressed page frame
+@param page_zip compressed page descriptor
+@return TRUE if ptr and page_zip refer to the same block */
+# define PAGE_ZIP_MATCH(ptr, page_zip) \
+ (buf_frame_get_page_zip(ptr) == (page_zip))
+#else /* !UNIV_HOTBACKUP */
+/** Check if a pointer to an uncompressed page matches a compressed page.
+@param ptr pointer to an uncompressed page frame
+@param page_zip compressed page descriptor
+@return TRUE if ptr and page_zip refer to the same block */
+# define PAGE_ZIP_MATCH(ptr, page_zip) \
+ (page_align(ptr) + UNIV_PAGE_SIZE == (page_zip)->data)
+#endif /* !UNIV_HOTBACKUP */
+
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
diff --git a/storage/xtradb/include/page0zip.ic b/storage/xtradb/include/page0zip.ic
index 3db5f025c31..75cc7a9fcc4 100644
--- a/storage/xtradb/include/page0zip.ic
+++ b/storage/xtradb/include/page0zip.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0zip.ic
Compressed page interface
Created June 2005 by Marko Makela
@@ -97,25 +98,25 @@ In summary, the compressed page looks like this:
- deleted records (free list) in link order
*/
-/* Start offset of the area that will be compressed */
+/** Start offset of the area that will be compressed */
#define PAGE_ZIP_START PAGE_NEW_SUPREMUM_END
-/* Size of an compressed page directory entry */
+/** Size of an compressed page directory entry */
#define PAGE_ZIP_DIR_SLOT_SIZE 2
-/* Mask of record offsets */
+/** Mask of record offsets */
#define PAGE_ZIP_DIR_SLOT_MASK 0x3fff
-/* 'owned' flag */
+/** 'owned' flag */
#define PAGE_ZIP_DIR_SLOT_OWNED 0x4000
-/* 'deleted' flag */
+/** 'deleted' flag */
#define PAGE_ZIP_DIR_SLOT_DEL 0x8000
-/**************************************************************************
-Determine the size of a compressed page in bytes. */
+/**********************************************************************//**
+Determine the size of a compressed page in bytes.
+@return size in bytes */
UNIV_INLINE
ulint
page_zip_get_size(
/*==============*/
- /* out: size in bytes */
- const page_zip_des_t* page_zip) /* in: compressed page */
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
{
ulint size;
@@ -130,14 +131,14 @@ page_zip_get_size(
return(size);
}
-/**************************************************************************
+/**********************************************************************//**
Set the size of a compressed page in bytes. */
UNIV_INLINE
void
page_zip_set_size(
/*==============*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint size) /* in: size in bytes */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint size) /*!< in: size in bytes */
{
if (size) {
int ssize;
@@ -155,19 +156,19 @@ page_zip_set_size(
ut_ad(page_zip_get_size(page_zip) == size);
}
-/**************************************************************************
-Determine if a record is so big that it needs to be stored externally. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Determine if a record is so big that it needs to be stored externally.
+@return FALSE if the entire record can be stored locally on the page */
UNIV_INLINE
ibool
page_zip_rec_needs_ext(
/*===================*/
- /* out: FALSE if the entire record
- can be stored locally on the page */
- ulint rec_size, /* in: length of the record in bytes */
- ulint comp, /* in: nonzero=compact format */
- ulint n_fields, /* in: number of fields in the record;
+ ulint rec_size, /*!< in: length of the record in bytes */
+ ulint comp, /*!< in: nonzero=compact format */
+ ulint n_fields, /*!< in: number of fields in the record;
ignored if zip_size == 0 */
- ulint zip_size) /* in: compressed page size in bytes, or 0 */
+ ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
{
ut_ad(rec_size > comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES);
ut_ad(ut_is_2pow(zip_size));
@@ -194,16 +195,17 @@ page_zip_rec_needs_ext(
return(rec_size >= page_get_free_space_of_empty(comp) / 2);
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/**************************************************************************
-Validate a compressed page descriptor. */
+/**********************************************************************//**
+Validate a compressed page descriptor.
+@return TRUE if ok */
UNIV_INLINE
ibool
page_zip_simple_validate(
/*=====================*/
- /* out: TRUE if ok */
- const page_zip_des_t* page_zip)/* in: compressed page descriptor */
+ const page_zip_des_t* page_zip)/*!< in: compressed page descriptor */
{
ut_ad(page_zip);
ut_ad(page_zip->data);
@@ -218,18 +220,17 @@ page_zip_simple_validate(
}
#endif /* UNIV_DEBUG */
-/**************************************************************************
-Determine if the length of the page trailer. */
+/**********************************************************************//**
+Determine if the length of the page trailer.
+@return length of the page trailer, in bytes, not including the
+terminating zero byte of the modification log */
UNIV_INLINE
ibool
page_zip_get_trailer_len(
/*=====================*/
- /* out: length of the page trailer,
- in bytes, not including the terminating
- zero byte of the modification log */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust,/* in: TRUE if clustered index */
- ulint* entry_size)/* out: size of the uncompressed
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust,/*!< in: TRUE if clustered index */
+ ulint* entry_size)/*!< out: size of the uncompressed
portion of a user record */
{
ulint uncompressed_size;
@@ -258,19 +259,16 @@ page_zip_get_trailer_len(
+ page_zip->n_blobs * BTR_EXTERN_FIELD_REF_SIZE);
}
-/**************************************************************************
-Determine how big record can be inserted without recompressing the page. */
+/**********************************************************************//**
+Determine how big record can be inserted without recompressing the page.
+@return a positive number indicating the maximum size of a record
+whose insertion is guaranteed to succeed, or zero or negative */
UNIV_INLINE
lint
page_zip_max_ins_size(
/*==================*/
- /* out: a positive number
- indicating the maximum size of
- a record whose insertion is
- guaranteed to succeed, or
- zero or negative */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust)/* in: TRUE if clustered index */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust)/*!< in: TRUE if clustered index */
{
ulint uncompressed_size;
ulint trailer_len;
@@ -292,18 +290,17 @@ page_zip_max_ins_size(
- (REC_N_NEW_EXTRA_BYTES - 2));
}
-/**************************************************************************
-Determine if enough space is available in the modification log. */
+/**********************************************************************//**
+Determine if enough space is available in the modification log.
+@return TRUE if enough space is available */
UNIV_INLINE
ibool
page_zip_available(
/*===============*/
- /* out: TRUE if enough space
- is available */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust,/* in: TRUE if clustered index */
- ulint length, /* in: combined size of the record */
- ulint create) /* in: nonzero=add the record to
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust,/*!< in: TRUE if clustered index */
+ ulint length, /*!< in: combined size of the record */
+ ulint create) /*!< in: nonzero=add the record to
the heap */
{
ulint uncompressed_size;
@@ -335,29 +332,29 @@ page_zip_available(
< page_zip_get_size(page_zip)));
}
-/**************************************************************************
+/**********************************************************************//**
Initialize a compressed page descriptor. */
UNIV_INLINE
void
page_zip_des_init(
/*==============*/
- page_zip_des_t* page_zip) /* in/out: compressed page
+ page_zip_des_t* page_zip) /*!< in/out: compressed page
descriptor */
{
memset(page_zip, 0, sizeof *page_zip);
}
-/**************************************************************************
+/**********************************************************************//**
Write a log record of writing to the uncompressed header portion of a page. */
UNIV_INTERN
void
page_zip_write_header_log(
/*======================*/
- const byte* data,/* in: data on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr); /* in: mini-transaction */
+ const byte* data,/*!< in: data on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr); /*!< in: mini-transaction */
-/**************************************************************************
+/**********************************************************************//**
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page.
However, the data portion of the uncompressed page may differ from
@@ -367,14 +364,14 @@ UNIV_INLINE
void
page_zip_write_header(
/*==================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* str, /* in: address on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* str, /*!< in: address on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
{
ulint pos;
- ut_ad(buf_frame_get_page_zip(str) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(str, page_zip));
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
@@ -388,7 +385,9 @@ page_zip_write_header(
/* ut_ad(page_zip_validate(page_zip, str - pos)); */
if (UNIV_LIKELY_NULL(mtr)) {
+#ifndef UNIV_HOTBACKUP
page_zip_write_header_log(str, length, mtr);
+#endif /* !UNIV_HOTBACKUP */
}
}
diff --git a/storage/xtradb/include/pars0opt.h b/storage/xtradb/include/pars0opt.h
index 02524e9d893..42d956068f8 100644
--- a/storage/xtradb/include/pars0opt.h
+++ b/storage/xtradb/include/pars0opt.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0opt.h
Simple SQL optimizer
Created 12/21/1997 Heikki Tuuri
@@ -32,7 +33,7 @@ Created 12/21/1997 Heikki Tuuri
#include "dict0types.h"
#include "row0sel.h"
-/***********************************************************************
+/*******************************************************************//**
Optimizes a select. Decides which indexes to tables to use. The tables
are accessed in the order that they were written to the FROM part in the
select statement. */
@@ -40,8 +41,8 @@ UNIV_INTERN
void
opt_search_plan(
/*============*/
- sel_node_t* sel_node); /* in: parsed select node */
-/***********************************************************************
+ sel_node_t* sel_node); /*!< in: parsed select node */
+/*******************************************************************//**
Looks for occurrences of the columns of the table in the query subgraph and
adds them to the list of columns if an occurrence of the same column does not
already exist in the list. If the column is already in the list, puts a value
@@ -52,20 +53,20 @@ UNIV_INTERN
void
opt_find_all_cols(
/*==============*/
- ibool copy_val, /* in: if TRUE, new found columns are
+ ibool copy_val, /*!< in: if TRUE, new found columns are
added as columns to copy */
- dict_index_t* index, /* in: index to use */
- sym_node_list_t* col_list, /* in: base node of a list where
+ dict_index_t* index, /*!< in: index to use */
+ sym_node_list_t* col_list, /*!< in: base node of a list where
to add new found columns */
- plan_t* plan, /* in: plan or NULL */
- que_node_t* exp); /* in: expression or condition */
-/************************************************************************
+ plan_t* plan, /*!< in: plan or NULL */
+ que_node_t* exp); /*!< in: expression or condition */
+/********************************************************************//**
Prints info of a query plan. */
UNIV_INTERN
void
opt_print_query_plan(
/*=================*/
- sel_node_t* sel_node); /* in: select node */
+ sel_node_t* sel_node); /*!< in: select node */
#ifndef UNIV_NONINL
#include "pars0opt.ic"
diff --git a/storage/xtradb/include/pars0opt.ic b/storage/xtradb/include/pars0opt.ic
index 35653453b30..e0bb6bf1af2 100644
--- a/storage/xtradb/include/pars0opt.ic
+++ b/storage/xtradb/include/pars0opt.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0opt.ic
Simple SQL optimizer
Created 12/21/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/pars0pars.h b/storage/xtradb/include/pars0pars.h
index 865f24f7bf4..fe5d76ebbb0 100644
--- a/storage/xtradb/include/pars0pars.h
+++ b/storage/xtradb/include/pars0pars.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0pars.h
SQL parser
Created 11/19/1996 Heikki Tuuri
@@ -33,18 +34,19 @@ Created 11/19/1996 Heikki Tuuri
#include "trx0types.h"
#include "ut0vec.h"
-/* Type of the user functions. The first argument is always InnoDB-supplied
+/** Type of the user functions. The first argument is always InnoDB-supplied
and varies in type, while 'user_arg' is a user-supplied argument. The
meaning of the return type also varies. See the individual use cases, e.g.
the FETCH statement, for details on them. */
typedef void* (*pars_user_func_cb_t)(void* arg, void* user_arg);
+/** If the following is set TRUE, the parser will emit debugging
+information */
extern int yydebug;
-/* If the following is set TRUE, the lexer will print the SQL string
-as it tokenizes it */
-
#ifdef UNIV_SQL_DEBUG
+/** If the following is set TRUE, the lexer will print the SQL string
+as it tokenizes it */
extern ibool pars_print_lexed;
#endif /* UNIV_SQL_DEBUG */
@@ -93,315 +95,309 @@ extern ulint pars_star_denoter;
int
yyparse(void);
-/*****************************************************************
-Parses an SQL string returning the query graph. */
+/*************************************************************//**
+Parses an SQL string returning the query graph.
+@return own: the query graph */
UNIV_INTERN
que_t*
pars_sql(
/*=====*/
- /* out, own: the query graph */
- pars_info_t* info, /* in: extra information, or NULL */
- const char* str); /* in: SQL string */
-/*****************************************************************
+ pars_info_t* info, /*!< in: extra information, or NULL */
+ const char* str); /*!< in: SQL string */
+/*************************************************************//**
Retrieves characters to the lexical analyzer. */
UNIV_INTERN
void
pars_get_lex_chars(
/*===============*/
- char* buf, /* in/out: buffer where to copy */
- int* result, /* out: number of characters copied or EOF */
- int max_size); /* in: maximum number of characters which fit
+ char* buf, /*!< in/out: buffer where to copy */
+ int* result, /*!< out: number of characters copied or EOF */
+ int max_size); /*!< in: maximum number of characters which fit
in the buffer */
-/*****************************************************************
+/*************************************************************//**
Called by yyparse on error. */
UNIV_INTERN
void
yyerror(
/*====*/
- const char* s); /* in: error message string */
-/*************************************************************************
-Parses a variable declaration. */
+ const char* s); /*!< in: error message string */
+/*********************************************************************//**
+Parses a variable declaration.
+@return own: symbol table node of type SYM_VAR */
UNIV_INTERN
sym_node_t*
pars_variable_declaration(
/*======================*/
- /* out, own: symbol table node of type
- SYM_VAR */
- sym_node_t* node, /* in: symbol table node allocated for the
+ sym_node_t* node, /*!< in: symbol table node allocated for the
id of the variable */
- pars_res_word_t* type); /* in: pointer to a type token */
-/*************************************************************************
-Parses a function expression. */
+ pars_res_word_t* type); /*!< in: pointer to a type token */
+/*********************************************************************//**
+Parses a function expression.
+@return own: function node in a query tree */
UNIV_INTERN
func_node_t*
pars_func(
/*======*/
- /* out, own: function node in a query tree */
- que_node_t* res_word,/* in: function name reserved word */
- que_node_t* arg); /* in: first argument in the argument list */
-/*************************************************************************
-Parses an operator expression. */
+ que_node_t* res_word,/*!< in: function name reserved word */
+ que_node_t* arg); /*!< in: first argument in the argument list */
+/*********************************************************************//**
+Parses an operator expression.
+@return own: function node in a query tree */
UNIV_INTERN
func_node_t*
pars_op(
/*====*/
- /* out, own: function node in a query tree */
- int func, /* in: operator token code */
- que_node_t* arg1, /* in: first argument */
- que_node_t* arg2); /* in: second argument or NULL for an unary
+ int func, /*!< in: operator token code */
+ que_node_t* arg1, /*!< in: first argument */
+ que_node_t* arg2); /*!< in: second argument or NULL for an unary
operator */
-/*************************************************************************
-Parses an ORDER BY clause. Order by a single column only is supported. */
+/*********************************************************************//**
+Parses an ORDER BY clause. Order by a single column only is supported.
+@return own: order-by node in a query tree */
UNIV_INTERN
order_node_t*
pars_order_by(
/*==========*/
- /* out, own: order-by node in a query tree */
- sym_node_t* column, /* in: column name */
- pars_res_word_t* asc); /* in: &pars_asc_token or pars_desc_token */
-/*************************************************************************
+ sym_node_t* column, /*!< in: column name */
+ pars_res_word_t* asc); /*!< in: &pars_asc_token or pars_desc_token */
+/*********************************************************************//**
Parses a select list; creates a query graph node for the whole SELECT
-statement. */
+statement.
+@return own: select node in a query tree */
UNIV_INTERN
sel_node_t*
pars_select_list(
/*=============*/
- /* out, own: select node in a query
- tree */
- que_node_t* select_list, /* in: select list */
- sym_node_t* into_list); /* in: variables list or NULL */
-/*************************************************************************
-Parses a cursor declaration. */
+ que_node_t* select_list, /*!< in: select list */
+ sym_node_t* into_list); /*!< in: variables list or NULL */
+/*********************************************************************//**
+Parses a cursor declaration.
+@return sym_node */
UNIV_INTERN
que_node_t*
pars_cursor_declaration(
/*====================*/
- /* out: sym_node */
- sym_node_t* sym_node, /* in: cursor id node in the symbol
+ sym_node_t* sym_node, /*!< in: cursor id node in the symbol
table */
- sel_node_t* select_node); /* in: select node */
-/*************************************************************************
-Parses a function declaration. */
+ sel_node_t* select_node); /*!< in: select node */
+/*********************************************************************//**
+Parses a function declaration.
+@return sym_node */
UNIV_INTERN
que_node_t*
pars_function_declaration(
/*======================*/
- /* out: sym_node */
- sym_node_t* sym_node); /* in: function id node in the symbol
+ sym_node_t* sym_node); /*!< in: function id node in the symbol
table */
-/*************************************************************************
-Parses a select statement. */
+/*********************************************************************//**
+Parses a select statement.
+@return own: select node in a query tree */
UNIV_INTERN
sel_node_t*
pars_select_statement(
/*==================*/
- /* out, own: select node in a query
- tree */
- sel_node_t* select_node, /* in: select node already containing
+ sel_node_t* select_node, /*!< in: select node already containing
the select list */
- sym_node_t* table_list, /* in: table list */
- que_node_t* search_cond, /* in: search condition or NULL */
- pars_res_word_t* for_update, /* in: NULL or &pars_update_token */
- pars_res_word_t* consistent_read,/* in: NULL or
+ sym_node_t* table_list, /*!< in: table list */
+ que_node_t* search_cond, /*!< in: search condition or NULL */
+ pars_res_word_t* for_update, /*!< in: NULL or &pars_update_token */
+ pars_res_word_t* consistent_read,/*!< in: NULL or
&pars_consistent_token */
- order_node_t* order_by); /* in: NULL or an order-by node */
-/*************************************************************************
-Parses a column assignment in an update. */
+ order_node_t* order_by); /*!< in: NULL or an order-by node */
+/*********************************************************************//**
+Parses a column assignment in an update.
+@return column assignment node */
UNIV_INTERN
col_assign_node_t*
pars_column_assignment(
/*===================*/
- /* out: column assignment node */
- sym_node_t* column, /* in: column to assign */
- que_node_t* exp); /* in: value to assign */
-/*************************************************************************
-Parses a delete or update statement start. */
+ sym_node_t* column, /*!< in: column to assign */
+ que_node_t* exp); /*!< in: value to assign */
+/*********************************************************************//**
+Parses a delete or update statement start.
+@return own: update node in a query tree */
UNIV_INTERN
upd_node_t*
pars_update_statement_start(
/*========================*/
- /* out, own: update node in a query
- tree */
- ibool is_delete, /* in: TRUE if delete */
- sym_node_t* table_sym, /* in: table name node */
- col_assign_node_t* col_assign_list);/* in: column assignment list, NULL
+ ibool is_delete, /*!< in: TRUE if delete */
+ sym_node_t* table_sym, /*!< in: table name node */
+ col_assign_node_t* col_assign_list);/*!< in: column assignment list, NULL
if delete */
-/*************************************************************************
-Parses an update or delete statement. */
+/*********************************************************************//**
+Parses an update or delete statement.
+@return own: update node in a query tree */
UNIV_INTERN
upd_node_t*
pars_update_statement(
/*==================*/
- /* out, own: update node in a query
- tree */
- upd_node_t* node, /* in: update node */
- sym_node_t* cursor_sym, /* in: pointer to a cursor entry in
+ upd_node_t* node, /*!< in: update node */
+ sym_node_t* cursor_sym, /*!< in: pointer to a cursor entry in
the symbol table or NULL */
- que_node_t* search_cond); /* in: search condition or NULL */
-/*************************************************************************
-Parses an insert statement. */
+ que_node_t* search_cond); /*!< in: search condition or NULL */
+/*********************************************************************//**
+Parses an insert statement.
+@return own: update node in a query tree */
UNIV_INTERN
ins_node_t*
pars_insert_statement(
/*==================*/
- /* out, own: update node in a query
- tree */
- sym_node_t* table_sym, /* in: table name node */
- 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. */
+ sym_node_t* table_sym, /*!< in: table name node */
+ 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 */
UNIV_INTERN
sym_node_t*
pars_parameter_declaration(
/*=======================*/
- /* out, own: symbol table node of type
- SYM_VAR */
- sym_node_t* node, /* in: symbol table node allocated for the
+ 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. */
+ /*!< in: PARS_INPUT or PARS_OUTPUT */
+ pars_res_word_t* type); /*!< in: pointer to a type token */
+/*********************************************************************//**
+Parses an elsif element.
+@return elsif node */
UNIV_INTERN
elsif_node_t*
pars_elsif_element(
/*===============*/
- /* out: elsif node */
- que_node_t* cond, /* in: if-condition */
- que_node_t* stat_list); /* in: statement list */
-/*************************************************************************
-Parses an if-statement. */
+ que_node_t* cond, /*!< in: if-condition */
+ que_node_t* stat_list); /*!< in: statement list */
+/*********************************************************************//**
+Parses an if-statement.
+@return if-statement node */
UNIV_INTERN
if_node_t*
pars_if_statement(
/*==============*/
- /* out: if-statement node */
- que_node_t* cond, /* in: if-condition */
- que_node_t* stat_list, /* in: statement list */
- que_node_t* else_part); /* in: else-part statement list */
-/*************************************************************************
-Parses a for-loop-statement. */
+ que_node_t* cond, /*!< in: if-condition */
+ que_node_t* stat_list, /*!< in: statement list */
+ que_node_t* else_part); /*!< in: else-part statement list */
+/*********************************************************************//**
+Parses a for-loop-statement.
+@return for-statement node */
UNIV_INTERN
for_node_t*
pars_for_statement(
/*===============*/
- /* out: for-statement node */
- sym_node_t* loop_var, /* in: loop variable */
- que_node_t* loop_start_limit,/* in: loop start expression */
- que_node_t* loop_end_limit, /* in: loop end expression */
- que_node_t* stat_list); /* in: statement list */
-/*************************************************************************
-Parses a while-statement. */
+ sym_node_t* loop_var, /*!< in: loop variable */
+ que_node_t* loop_start_limit,/*!< in: loop start expression */
+ que_node_t* loop_end_limit, /*!< in: loop end expression */
+ que_node_t* stat_list); /*!< in: statement list */
+/*********************************************************************//**
+Parses a while-statement.
+@return while-statement node */
UNIV_INTERN
while_node_t*
pars_while_statement(
/*=================*/
- /* out: while-statement node */
- que_node_t* cond, /* in: while-condition */
- que_node_t* stat_list); /* in: statement list */
-/*************************************************************************
-Parses an exit statement. */
+ que_node_t* cond, /*!< in: while-condition */
+ que_node_t* stat_list); /*!< in: statement list */
+/*********************************************************************//**
+Parses an exit statement.
+@return exit statement node */
UNIV_INTERN
exit_node_t*
pars_exit_statement(void);
/*=====================*/
- /* out: exit statement node */
-/*************************************************************************
-Parses a return-statement. */
+/*********************************************************************//**
+Parses a return-statement.
+@return return-statement node */
UNIV_INTERN
return_node_t*
pars_return_statement(void);
/*=======================*/
- /* out: return-statement node */
-/*************************************************************************
-Parses a procedure call. */
+/*********************************************************************//**
+Parses a procedure call.
+@return function node */
UNIV_INTERN
func_node_t*
pars_procedure_call(
/*================*/
- /* out: function node */
- que_node_t* res_word,/* in: procedure name reserved word */
- que_node_t* args); /* in: argument list */
-/*************************************************************************
-Parses an assignment statement. */
+ que_node_t* res_word,/*!< in: procedure name reserved word */
+ que_node_t* args); /*!< in: argument list */
+/*********************************************************************//**
+Parses an assignment statement.
+@return assignment statement node */
UNIV_INTERN
assign_node_t*
pars_assignment_statement(
/*======================*/
- /* out: assignment statement node */
- sym_node_t* var, /* in: variable to assign */
- que_node_t* val); /* in: value to assign */
-/*************************************************************************
+ sym_node_t* var, /*!< in: variable to assign */
+ que_node_t* val); /*!< in: value to assign */
+/*********************************************************************//**
Parses a fetch statement. into_list or user_func (but not both) must be
-non-NULL. */
+non-NULL.
+@return fetch statement node */
UNIV_INTERN
fetch_node_t*
pars_fetch_statement(
/*=================*/
- /* out: fetch statement node */
- sym_node_t* cursor, /* in: cursor node */
- sym_node_t* into_list, /* in: variables to set, or NULL */
- sym_node_t* user_func); /* in: user function name, or NULL */
-/*************************************************************************
-Parses an open or close cursor statement. */
+ sym_node_t* cursor, /*!< in: cursor node */
+ sym_node_t* into_list, /*!< in: variables to set, or NULL */
+ sym_node_t* user_func); /*!< in: user function name, or NULL */
+/*********************************************************************//**
+Parses an open or close cursor statement.
+@return fetch statement node */
UNIV_INTERN
open_node_t*
pars_open_statement(
/*================*/
- /* out: fetch statement node */
- ulint type, /* in: ROW_SEL_OPEN_CURSOR
+ ulint type, /*!< in: ROW_SEL_OPEN_CURSOR
or ROW_SEL_CLOSE_CURSOR */
- sym_node_t* cursor); /* in: cursor node */
-/*************************************************************************
-Parses a row_printf-statement. */
+ sym_node_t* cursor); /*!< in: cursor node */
+/*********************************************************************//**
+Parses a row_printf-statement.
+@return row_printf-statement node */
UNIV_INTERN
row_printf_node_t*
pars_row_printf_statement(
/*======================*/
- /* out: row_printf-statement node */
- sel_node_t* sel_node); /* in: select node */
-/*************************************************************************
-Parses a commit statement. */
+ sel_node_t* sel_node); /*!< in: select node */
+/*********************************************************************//**
+Parses a commit statement.
+@return own: commit node struct */
UNIV_INTERN
commit_node_t*
pars_commit_statement(void);
/*=======================*/
-/*************************************************************************
-Parses a rollback statement. */
+/*********************************************************************//**
+Parses a rollback statement.
+@return own: rollback node struct */
UNIV_INTERN
roll_node_t*
pars_rollback_statement(void);
/*=========================*/
-/*************************************************************************
-Parses a column definition at a table creation. */
+/*********************************************************************//**
+Parses a column definition at a table creation.
+@return column sym table node */
UNIV_INTERN
sym_node_t*
pars_column_def(
/*============*/
- /* out: column sym table
- node */
- sym_node_t* sym_node, /* in: column node in the
+ sym_node_t* sym_node, /*!< in: column node in the
symbol table */
- pars_res_word_t* type, /* in: data type */
- sym_node_t* len, /* in: length of column, or
+ 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
+ void* is_unsigned, /*!< in: if not NULL, column
is of type UNSIGNED. */
- void* is_not_null); /* in: if not NULL, column
+ void* is_not_null); /*!< in: if not NULL, column
is of type NOT NULL. */
-/*************************************************************************
-Parses a table creation operation. */
+/*********************************************************************//**
+Parses a table creation operation.
+@return table create subgraph */
UNIV_INTERN
tab_node_t*
pars_create_table(
/*==============*/
- /* out: table create subgraph */
- sym_node_t* table_sym, /* in: table name node in the symbol
+ sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_defs, /* in: list of column names */
- void* not_fit_in_memory);/* in: a non-NULL pointer means that
+ sym_node_t* column_defs, /*!< in: list of column names */
+ void* not_fit_in_memory);/*!< in: a non-NULL pointer means that
this is a table which in simulations
should be simulated as not fitting
in memory; thread is put to sleep
@@ -411,99 +407,99 @@ pars_create_table(
will forget about non-NULL value if
it has to reload the table definition
from disk */
-/*************************************************************************
-Parses an index creation operation. */
+/*********************************************************************//**
+Parses an index creation operation.
+@return index create subgraph */
UNIV_INTERN
ind_node_t*
pars_create_index(
/*==============*/
- /* out: index create subgraph */
- pars_res_word_t* unique_def, /* in: not NULL if a unique index */
- pars_res_word_t* clustered_def, /* in: not NULL if a clustered index */
- sym_node_t* index_sym, /* in: index name node in the symbol
+ pars_res_word_t* unique_def, /*!< in: not NULL if a unique index */
+ pars_res_word_t* clustered_def, /*!< in: not NULL if a clustered index */
+ sym_node_t* index_sym, /*!< in: index name node in the symbol
table */
- sym_node_t* table_sym, /* in: table name node in the symbol
+ sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_list); /* in: list of column names */
-/*************************************************************************
-Parses a procedure definition. */
+ sym_node_t* column_list); /*!< in: list of column names */
+/*********************************************************************//**
+Parses a procedure definition.
+@return query fork node */
UNIV_INTERN
que_fork_t*
pars_procedure_definition(
/*======================*/
- /* out: query fork node */
- sym_node_t* sym_node, /* in: procedure id node in the symbol
+ 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 */
+ sym_node_t* param_list, /*!< in: parameter declaration list */
+ que_node_t* stat_list); /*!< in: statement list */
-/*****************************************************************
+/*************************************************************//**
Parses a stored procedure call, when this is not within another stored
procedure, that is, the client issues a procedure call directly.
In MySQL/InnoDB, stored InnoDB procedures are invoked via the
-parsed procedure tree, not via InnoDB SQL, so this function is not used. */
+parsed procedure tree, not via InnoDB SQL, so this function is not used.
+@return query graph */
UNIV_INTERN
que_fork_t*
pars_stored_procedure_call(
/*=======================*/
- /* out: query graph */
- sym_node_t* sym_node); /* in: stored procedure name */
-/**********************************************************************
+ sym_node_t* sym_node); /*!< in: stored procedure name */
+/******************************************************************//**
Completes a query graph by adding query thread and fork nodes
above it and prepares the graph for running. The fork created is of
-type QUE_FORK_MYSQL_INTERFACE. */
+type QUE_FORK_MYSQL_INTERFACE.
+@return query thread node to run */
UNIV_INTERN
que_thr_t*
pars_complete_graph_for_exec(
/*=========================*/
- /* out: query thread node to run */
- que_node_t* node, /* in: root node for an incomplete
+ que_node_t* node, /*!< in: root node for an incomplete
query graph */
- trx_t* trx, /* in: transaction handle */
- mem_heap_t* heap); /* in: memory heap from which allocated */
+ trx_t* trx, /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: memory heap from which allocated */
-/********************************************************************
-Create parser info struct.*/
+/****************************************************************//**
+Create parser info struct.
+@return own: info struct */
UNIV_INTERN
pars_info_t*
pars_info_create(void);
/*==================*/
- /* out, own: info struct */
-/********************************************************************
-Free info struct and everything it contains.*/
+/****************************************************************//**
+Free info struct and everything it contains. */
UNIV_INTERN
void
pars_info_free(
/*===========*/
- pars_info_t* info); /* in: info struct */
+ pars_info_t* info); /*!< in, own: info struct */
-/********************************************************************
+/****************************************************************//**
Add bound literal. */
UNIV_INTERN
void
pars_info_add_literal(
/*==================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const void* address, /* in: address */
- ulint length, /* in: length of data */
- ulint type, /* in: type, e.g. DATA_FIXBINARY */
- ulint prtype); /* in: precise type, e.g.
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const void* address, /*!< in: address */
+ ulint length, /*!< in: length of data */
+ ulint type, /*!< in: type, e.g. DATA_FIXBINARY */
+ ulint prtype); /*!< in: precise type, e.g.
DATA_UNSIGNED */
-/********************************************************************
+/****************************************************************//**
Equivalent to pars_info_add_literal(info, name, str, strlen(str),
DATA_VARCHAR, DATA_ENGLISH). */
UNIV_INTERN
void
pars_info_add_str_literal(
/*======================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const char* str); /* in: string */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const char* str); /*!< in: string */
-/********************************************************************
+/****************************************************************//**
Equivalent to:
char buf[4];
@@ -516,11 +512,11 @@ UNIV_INTERN
void
pars_info_add_int4_literal(
/*=======================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- lint val); /* in: value */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ lint val); /*!< in: value */
-/********************************************************************
+/****************************************************************//**
Equivalent to:
char buf[8];
@@ -533,212 +529,217 @@ UNIV_INTERN
void
pars_info_add_dulint_literal(
/*=========================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- dulint val); /* in: value */
-/********************************************************************
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ dulint val); /*!< in: value */
+/****************************************************************//**
Add user function. */
UNIV_INTERN
void
pars_info_add_function(
/*===================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: function name */
- pars_user_func_cb_t func, /* in: function address */
- void* arg); /* in: user-supplied argument */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: function name */
+ pars_user_func_cb_t func, /*!< in: function address */
+ void* arg); /*!< in: user-supplied argument */
-/********************************************************************
+/****************************************************************//**
Add bound id. */
UNIV_INTERN
void
pars_info_add_id(
/*=============*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const char* id); /* in: id */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const char* id); /*!< in: id */
-/********************************************************************
-Get user function with the given name.*/
+/****************************************************************//**
+Get user function with the given name.
+@return user func, or NULL if not found */
UNIV_INTERN
pars_user_func_t*
pars_info_get_user_func(
/*====================*/
- /* out: user func, or NULL if not
- found */
- pars_info_t* info, /* in: info struct */
- const char* name); /* in: function name to find*/
+ pars_info_t* info, /*!< in: info struct */
+ const char* name); /*!< in: function name to find*/
-/********************************************************************
-Get bound literal with the given name.*/
+/****************************************************************//**
+Get bound literal with the given name.
+@return bound literal, or NULL if not found */
UNIV_INTERN
pars_bound_lit_t*
pars_info_get_bound_lit(
/*====================*/
- /* out: bound literal, or NULL if
- not found */
- pars_info_t* info, /* in: info struct */
- const char* name); /* in: bound literal name to find */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name); /*!< in: bound literal name to find */
-/********************************************************************
-Get bound id with the given name.*/
+/****************************************************************//**
+Get bound id with the given name.
+@return bound id, or NULL if not found */
UNIV_INTERN
pars_bound_id_t*
pars_info_get_bound_id(
/*===================*/
- /* out: bound id, or NULL if not
- found */
- pars_info_t* info, /* in: info struct */
- const char* name); /* in: bound id name to find */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name); /*!< in: bound id name to find */
+/******************************************************************//**
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void);
+/*==================*/
-/* Extra information supplied for pars_sql(). */
+/** Extra information supplied for pars_sql(). */
struct pars_info_struct {
- mem_heap_t* heap; /* our own memory heap */
+ mem_heap_t* heap; /*!< our own memory heap */
- ib_vector_t* funcs; /* user functions, or NUll
+ ib_vector_t* funcs; /*!< user functions, or NUll
(pars_user_func_t*) */
- ib_vector_t* bound_lits; /* bound literals, or NULL
+ ib_vector_t* bound_lits; /*!< bound literals, or NULL
(pars_bound_lit_t*) */
- ib_vector_t* bound_ids; /* bound ids, or NULL
+ ib_vector_t* bound_ids; /*!< bound ids, or NULL
(pars_bound_id_t*) */
- ibool graph_owns_us; /* if TRUE (which is the default),
+ ibool graph_owns_us; /*!< if TRUE (which is the default),
que_graph_free() will free us */
};
-/* User-supplied function and argument. */
+/** User-supplied function and argument. */
struct pars_user_func_struct {
- const char* name; /* function name */
- pars_user_func_cb_t func; /* function address */
- void* arg; /* user-supplied argument */
+ const char* name; /*!< function name */
+ pars_user_func_cb_t func; /*!< function address */
+ void* arg; /*!< user-supplied argument */
};
-/* Bound literal. */
+/** Bound literal. */
struct pars_bound_lit_struct {
- const char* name; /* name */
- const void* address; /* address */
- ulint length; /* length of data */
- ulint type; /* type, e.g. DATA_FIXBINARY */
- ulint prtype; /* precise type, e.g. DATA_UNSIGNED */
+ const char* name; /*!< name */
+ const void* address; /*!< address */
+ ulint length; /*!< length of data */
+ ulint type; /*!< type, e.g. DATA_FIXBINARY */
+ ulint prtype; /*!< precise type, e.g. DATA_UNSIGNED */
};
-/* Bound id. */
+/** Bound identifier. */
struct pars_bound_id_struct {
- const char* name; /* name */
- const char* id; /* id */
+ const char* name; /*!< name */
+ const char* id; /*!< identifier */
};
-/* Struct used to denote a reserved word in a parsing tree */
+/** Struct used to denote a reserved word in a parsing tree */
struct pars_res_word_struct{
- int code; /* the token code for the reserved word from
+ int code; /*!< the token code for the reserved word from
pars0grm.h */
};
-/* A predefined function or operator node in a parsing tree; this construct
+/** A predefined function or operator node in a parsing tree; this construct
is also used for some non-functions like the assignment ':=' */
struct func_node_struct{
- que_common_t common; /* type: QUE_NODE_FUNC */
- int func; /* token code of the function name */
- ulint class; /* class of the function */
- que_node_t* args; /* argument(s) of the function */
+ que_common_t common; /*!< type: QUE_NODE_FUNC */
+ int func; /*!< token code of the function name */
+ ulint class; /*!< class of the function */
+ que_node_t* args; /*!< argument(s) of the function */
UT_LIST_NODE_T(func_node_t) cond_list;
- /* list of comparison conditions; defined
+ /*!< list of comparison conditions; defined
only for comparison operator nodes except,
presently, for OPT_SCROLL_TYPE ones */
UT_LIST_NODE_T(func_node_t) func_node_list;
- /* list of function nodes in a parsed
+ /*!< list of function nodes in a parsed
query graph */
};
-/* An order-by node in a select */
+/** An order-by node in a select */
struct order_node_struct{
- que_common_t common; /* type: QUE_NODE_ORDER */
- sym_node_t* column; /* order-by column */
- ibool asc; /* TRUE if ascending, FALSE if descending */
+ que_common_t common; /*!< type: QUE_NODE_ORDER */
+ sym_node_t* column; /*!< order-by column */
+ ibool asc; /*!< TRUE if ascending, FALSE if descending */
};
-/* Procedure definition node */
+/** Procedure definition node */
struct proc_node_struct{
- que_common_t common; /* type: QUE_NODE_PROC */
- sym_node_t* proc_id; /* procedure name symbol in the symbol
+ 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 */
+ 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 */
};
-/* elsif-element node */
+/** elsif-element node */
struct elsif_node_struct{
- que_common_t common; /* type: QUE_NODE_ELSIF */
- que_node_t* cond; /* if condition */
- que_node_t* stat_list; /* statement list */
+ que_common_t common; /*!< type: QUE_NODE_ELSIF */
+ que_node_t* cond; /*!< if condition */
+ que_node_t* stat_list; /*!< statement list */
};
-/* if-statement node */
+/** if-statement node */
struct if_node_struct{
- que_common_t common; /* type: QUE_NODE_IF */
- que_node_t* cond; /* if condition */
- que_node_t* stat_list; /* statement list */
- que_node_t* else_part; /* else-part statement list */
- elsif_node_t* elsif_list; /* elsif element list */
+ que_common_t common; /*!< type: QUE_NODE_IF */
+ que_node_t* cond; /*!< if condition */
+ que_node_t* stat_list; /*!< statement list */
+ que_node_t* else_part; /*!< else-part statement list */
+ elsif_node_t* elsif_list; /*!< elsif element list */
};
-/* while-statement node */
+/** while-statement node */
struct while_node_struct{
- que_common_t common; /* type: QUE_NODE_WHILE */
- que_node_t* cond; /* while condition */
- que_node_t* stat_list; /* statement list */
+ que_common_t common; /*!< type: QUE_NODE_WHILE */
+ que_node_t* cond; /*!< while condition */
+ que_node_t* stat_list; /*!< statement list */
};
-/* for-loop-statement node */
+/** for-loop-statement node */
struct for_node_struct{
- que_common_t common; /* type: QUE_NODE_FOR */
- sym_node_t* loop_var; /* loop variable: this is the
+ que_common_t common; /*!< type: QUE_NODE_FOR */
+ sym_node_t* loop_var; /*!< loop variable: this is the
dereferenced symbol from the
variable declarations, not the
symbol occurrence in the for loop
definition */
- que_node_t* loop_start_limit;/* initial value of loop variable */
- que_node_t* loop_end_limit; /* end value of loop variable */
- lint loop_end_value; /* evaluated value for the end value:
+ que_node_t* loop_start_limit;/*!< initial value of loop variable */
+ que_node_t* loop_end_limit; /*!< end value of loop variable */
+ lint loop_end_value; /*!< evaluated value for the end value:
it is calculated only when the loop
is entered, and will not change within
the loop */
- que_node_t* stat_list; /* statement list */
+ que_node_t* stat_list; /*!< statement list */
};
-/* exit statement node */
+/** exit statement node */
struct exit_node_struct{
- que_common_t common; /* type: QUE_NODE_EXIT */
+ que_common_t common; /*!< type: QUE_NODE_EXIT */
};
-/* return-statement node */
+/** return-statement node */
struct return_node_struct{
- que_common_t common; /* type: QUE_NODE_RETURN */
+ que_common_t common; /*!< type: QUE_NODE_RETURN */
};
-/* Assignment statement node */
+/** Assignment statement node */
struct assign_node_struct{
- que_common_t common; /* type: QUE_NODE_ASSIGNMENT */
- sym_node_t* var; /* variable to set */
- que_node_t* val; /* value to assign */
+ que_common_t common; /*!< type: QUE_NODE_ASSIGNMENT */
+ sym_node_t* var; /*!< variable to set */
+ que_node_t* val; /*!< value to assign */
};
-/* Column assignment node */
+/** Column assignment node */
struct col_assign_node_struct{
- que_common_t common; /* type: QUE_NODE_COL_ASSIGN */
- sym_node_t* col; /* column to set */
- que_node_t* val; /* value to assign */
+ que_common_t common; /*!< type: QUE_NODE_COL_ASSIGN */
+ sym_node_t* col; /*!< column to set */
+ que_node_t* val; /*!< value to assign */
};
-/* Classes of functions */
-#define PARS_FUNC_ARITH 1 /* +, -, *, / */
-#define PARS_FUNC_LOGICAL 2
-#define PARS_FUNC_CMP 3
-#define PARS_FUNC_PREDEFINED 4 /* TO_NUMBER, SUBSTR, ... */
-#define PARS_FUNC_AGGREGATE 5 /* COUNT, DISTINCT, SUM */
-#define PARS_FUNC_OTHER 6 /* these are not real functions,
+/** Classes of functions */
+/* @{ */
+#define PARS_FUNC_ARITH 1 /*!< +, -, *, / */
+#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_OTHER 6 /*!< these are not real functions,
e.g., := */
+/* @} */
#ifndef UNIV_NONINL
#include "pars0pars.ic"
diff --git a/storage/xtradb/include/pars0pars.ic b/storage/xtradb/include/pars0pars.ic
index 3a55ad86f48..ae6c13cd671 100644
--- a/storage/xtradb/include/pars0pars.ic
+++ b/storage/xtradb/include/pars0pars.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0pars.ic
SQL parser
Created 11/19/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/pars0sym.h b/storage/xtradb/include/pars0sym.h
index 69227a2917e..6d1a4b82414 100644
--- a/storage/xtradb/include/pars0sym.h
+++ b/storage/xtradb/include/pars0sym.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0sym.h
SQL parser symbol table
Created 12/15/1997 Heikki Tuuri
@@ -32,15 +33,15 @@ Created 12/15/1997 Heikki Tuuri
#include "pars0types.h"
#include "row0types.h"
-/**********************************************************************
-Creates a symbol table for a single stored procedure or query. */
+/******************************************************************//**
+Creates a symbol table for a single stored procedure or query.
+@return own: symbol table */
UNIV_INTERN
sym_tab_t*
sym_tab_create(
/*===========*/
- /* out, own: symbol table */
- mem_heap_t* heap); /* in: memory heap where to create */
-/**********************************************************************
+ mem_heap_t* heap); /*!< in: memory heap where to create */
+/******************************************************************//**
Frees the memory allocated dynamically AFTER parsing phase for variables
etc. in the symbol table. Does not free the mem heap where the table was
originally created. Frees also SQL explicit cursor definitions. */
@@ -48,71 +49,89 @@ UNIV_INTERN
void
sym_tab_free_private(
/*=================*/
- sym_tab_t* sym_tab); /* in, own: symbol table */
-/**********************************************************************
-Adds an integer literal to a symbol table. */
+ sym_tab_t* sym_tab); /*!< in, own: symbol table */
+/******************************************************************//**
+Adds an integer literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_int_lit(
/*================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- ulint val); /* in: integer value */
-/**********************************************************************
-Adds an string literal to a symbol table. */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ ulint val); /*!< in: integer value */
+/******************************************************************//**
+Adds an string literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_str_lit(
/*================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- byte* str, /* in: string with no quotes around
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ byte* str, /*!< in: string with no quotes around
it */
- ulint len); /* in: string length */
-/**********************************************************************
-Add a bound literal to a symbol table. */
+ ulint len); /*!< in: string length */
+/******************************************************************//**
+Add a bound literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_bound_lit(
/*==================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- const char* name, /* in: name of bound literal */
- ulint* lit_type); /* out: type of literal (PARS_*_LIT) */
-/**********************************************************************
-Adds an SQL null literal to a symbol table. */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ const char* name, /*!< in: name of bound literal */
+ ulint* lit_type); /*!< out: type of literal (PARS_*_LIT) */
+/******************************************************************//**
+Adds an SQL null literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_null_lit(
/*=================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab); /* in: symbol table */
-/**********************************************************************
-Adds an identifier to a symbol table. */
+ sym_tab_t* sym_tab); /*!< in: symbol table */
+/******************************************************************//**
+Adds an identifier to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_id(
/*===========*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- byte* name, /* in: identifier name */
- ulint len); /* in: identifier length */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ byte* name, /*!< in: identifier name */
+ ulint len); /*!< in: identifier length */
-/**********************************************************************
-Add a bound identifier to a symbol table. */
+/******************************************************************//**
+Add a bound identifier to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_bound_id(
/*===========*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- const char* name); /* in: name of bound id */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ const char* name); /*!< in: name of bound id */
+/** Index of sym_node_struct::field_nos corresponding to the clustered index */
#define SYM_CLUST_FIELD_NO 0
+/** Index of sym_node_struct::field_nos corresponding to a secondary index */
#define SYM_SEC_FIELD_NO 1
+/** Types of a symbol table node */
+enum sym_tab_entry {
+ SYM_VAR = 91, /*!< declared parameter or local
+ variable of a procedure */
+ SYM_IMPLICIT_VAR, /*!< storage for a intermediate result
+ of a calculation */
+ SYM_LIT, /*!< literal */
+ SYM_TABLE, /*!< database table name */
+ SYM_COLUMN, /*!< database table name */
+ SYM_CURSOR, /*!< named cursor */
+ SYM_PROCEDURE_NAME, /*!< stored procedure name */
+ SYM_INDEX, /*!< database index name */
+ SYM_FUNCTION /*!< user function name */
+};
+
+/** Symbol table node */
struct sym_node_struct{
- que_common_t common; /* node type:
+ que_common_t common; /*!< node type:
QUE_NODE_SYMBOL */
/* NOTE: if the data field in 'common.val' is not NULL and the symbol
table node is not for a temporary column, the memory for the value has
@@ -132,25 +151,25 @@ struct sym_node_struct{
TODO: It would be cleaner to make 'indirection' a boolean field and
always use 'alias' to refer to the primary node. */
- sym_node_t* indirection; /* pointer to
+ sym_node_t* indirection; /*!< pointer to
another symbol table
node which contains
the value for this
node, NULL otherwise */
- sym_node_t* alias; /* pointer to
+ sym_node_t* alias; /*!< pointer to
another symbol table
node for which this
node is an alias,
NULL otherwise */
- UT_LIST_NODE_T(sym_node_t) col_var_list; /* list of table
+ UT_LIST_NODE_T(sym_node_t) col_var_list; /*!< list of table
columns or a list of
input variables for an
explicit cursor */
- ibool copy_val; /* TRUE if a column
+ ibool copy_val; /*!< TRUE if a column
and its value should
be copied to dynamic
memory when fetched */
- ulint field_nos[2]; /* if a column, in
+ ulint field_nos[2]; /*!< if a column, in
the position
SYM_CLUST_FIELD_NO is
the field number in the
@@ -162,76 +181,62 @@ struct sym_node_struct{
use first; if not found
from the index, then
ULINT_UNDEFINED */
- ibool resolved; /* TRUE if the
+ ibool resolved; /*!< TRUE if the
meaning of a variable
or a column has been
resolved; for literals
this is always TRUE */
- ulint token_type; /* SYM_VAR, SYM_COLUMN,
- SYM_IMPLICIT_VAR,
- SYM_LIT, SYM_TABLE,
- SYM_CURSOR, ... */
- const char* name; /* name of an id */
- ulint name_len; /* id name length */
- dict_table_t* table; /* table definition
+ enum sym_tab_entry token_type; /*!< type of the
+ parsed token */
+ const char* name; /*!< name of an id */
+ ulint name_len; /*!< id name length */
+ dict_table_t* table; /*!< table definition
if a table id or a
column id */
- ulint col_no; /* column number if a
+ ulint col_no; /*!< column number if a
column */
- sel_buf_t* prefetch_buf; /* NULL, or a buffer
+ sel_buf_t* prefetch_buf; /*!< NULL, or a buffer
for cached column
values for prefetched
rows */
- sel_node_t* cursor_def; /* cursor definition
+ sel_node_t* cursor_def; /*!< cursor definition
select node if a
named cursor */
- ulint param_type; /* PARS_INPUT,
+ ulint param_type; /*!< PARS_INPUT,
PARS_OUTPUT, or
PARS_NOT_PARAM if not a
procedure parameter */
- sym_tab_t* sym_table; /* back pointer to
+ sym_tab_t* sym_table; /*!< back pointer to
the symbol table */
- UT_LIST_NODE_T(sym_node_t) sym_list; /* list of symbol
+ UT_LIST_NODE_T(sym_node_t) sym_list; /*!< list of symbol
nodes */
};
+/** Symbol table */
struct sym_tab_struct{
que_t* query_graph;
- /* query graph generated by the
+ /*!< query graph generated by the
parser */
const char* sql_string;
- /* SQL string to parse */
+ /*!< SQL string to parse */
size_t string_len;
- /* SQL string length */
+ /*!< SQL string length */
int next_char_pos;
- /* position of the next character in
+ /*!< position of the next character in
sql_string to give to the lexical
analyzer */
- pars_info_t* info; /* extra information, or NULL */
+ pars_info_t* info; /*!< extra information, or NULL */
sym_node_list_t sym_list;
- /* list of symbol nodes in the symbol
+ /*!< list of symbol nodes in the symbol
table */
UT_LIST_BASE_NODE_T(func_node_t)
func_node_list;
- /* list of function nodes in the
+ /*!< list of function nodes in the
parsed query graph */
- mem_heap_t* heap; /* memory heap from which we can
+ mem_heap_t* heap; /*!< memory heap from which we can
allocate space */
};
-/* Types of a symbol table entry */
-#define SYM_VAR 91 /* declared parameter or local
- variable of a procedure */
-#define SYM_IMPLICIT_VAR 92 /* storage for a intermediate result
- of a calculation */
-#define SYM_LIT 93 /* literal */
-#define SYM_TABLE 94 /* database table name */
-#define SYM_COLUMN 95 /* database table name */
-#define SYM_CURSOR 96 /* named cursor */
-#define SYM_PROCEDURE_NAME 97 /* stored procedure name */
-#define SYM_INDEX 98 /* database index name */
-#define SYM_FUNCTION 99 /* user function name */
-
#ifndef UNIV_NONINL
#include "pars0sym.ic"
#endif
diff --git a/storage/xtradb/include/pars0sym.ic b/storage/xtradb/include/pars0sym.ic
index 235d6819ae9..9eb09db3a47 100644
--- a/storage/xtradb/include/pars0sym.ic
+++ b/storage/xtradb/include/pars0sym.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0sym.ic
SQL parser symbol table
Created 12/15/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/pars0types.h b/storage/xtradb/include/pars0types.h
index e0902d0611a..e0a8a86bf07 100644
--- a/storage/xtradb/include/pars0types.h
+++ b/storage/xtradb/include/pars0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0types.h
SQL parser global types
Created 1/11/1998 Heikki Tuuri
diff --git a/storage/xtradb/include/que0que.h b/storage/xtradb/include/que0que.h
index a534cb7e464..420f34550e2 100644
--- a/storage/xtradb/include/que0que.h
+++ b/storage/xtradb/include/que0que.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/que0que.h
Query graph
Created 5/27/1996 Heikki Tuuri
@@ -39,116 +40,106 @@ Created 5/27/1996 Heikki Tuuri
of SQL execution in the UNIV_SQL_DEBUG version */
extern ibool que_trace_on;
-/***************************************************************************
+/***********************************************************************//**
Adds a query graph to the session's list of graphs. */
UNIV_INTERN
void
que_graph_publish(
/*==============*/
- que_t* graph, /* in: graph */
- sess_t* sess); /* in: session */
-/***************************************************************************
-Creates a query graph fork node. */
+ que_t* graph, /*!< in: graph */
+ sess_t* sess); /*!< in: session */
+/***********************************************************************//**
+Creates a query graph fork node.
+@return own: fork node */
UNIV_INTERN
que_fork_t*
que_fork_create(
/*============*/
- /* out, own: fork node */
- que_t* graph, /* in: graph, if NULL then this
+ que_t* graph, /*!< in: graph, if NULL then this
fork node is assumed to be the
graph root */
- que_node_t* parent, /* in: parent node */
- ulint fork_type, /* in: fork type */
- mem_heap_t* heap); /* in: memory heap where created */
-/***************************************************************************
+ que_node_t* parent, /*!< in: parent node */
+ ulint fork_type, /*!< in: fork type */
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/***********************************************************************//**
Gets the first thr in a fork. */
UNIV_INLINE
que_thr_t*
que_fork_get_first_thr(
/*===================*/
- que_fork_t* fork); /* in: query fork */
-/***************************************************************************
+ que_fork_t* fork); /*!< in: query fork */
+/***********************************************************************//**
Gets the child node of the first thr in a fork. */
UNIV_INLINE
que_node_t*
que_fork_get_child(
/*===============*/
- que_fork_t* fork); /* in: query fork */
-/***************************************************************************
+ que_fork_t* fork); /*!< in: query fork */
+/***********************************************************************//**
Sets the parent of a graph node. */
UNIV_INLINE
void
que_node_set_parent(
/*================*/
- que_node_t* node, /* in: graph node */
- que_node_t* parent);/* in: parent */
-/***************************************************************************
-Creates a query graph thread node. */
+ que_node_t* node, /*!< in: graph node */
+ que_node_t* parent);/*!< in: parent */
+/***********************************************************************//**
+Creates a query graph thread node.
+@return own: query thread node */
UNIV_INTERN
que_thr_t*
que_thr_create(
/*===========*/
- /* out, own: query thread node */
- que_fork_t* parent, /* in: parent node, i.e., a fork node */
- mem_heap_t* heap); /* in: memory heap where created */
-/**************************************************************************
-Checks if the query graph is in a state where it should be freed, and
-frees it in that case. If the session is in a state where it should be
-closed, also this is done. */
-UNIV_INTERN
-ibool
-que_graph_try_free(
-/*===============*/
- /* out: TRUE if freed */
- que_t* graph); /* in: query graph */
-/**************************************************************************
+ que_fork_t* parent, /*!< in: parent node, i.e., a fork node */
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/**********************************************************************//**
Frees a query graph, but not the heap where it was created. Does not free
explicit cursor declarations, they are freed in que_graph_free. */
UNIV_INTERN
void
que_graph_free_recursive(
/*=====================*/
- que_node_t* node); /* in: query graph node */
-/**************************************************************************
+ que_node_t* node); /*!< in: query graph node */
+/**********************************************************************//**
Frees a query graph. */
UNIV_INTERN
void
que_graph_free(
/*===========*/
- que_t* graph); /* in: query graph; we assume that the memory
+ que_t* graph); /*!< in: query graph; we assume that the memory
heap where this graph was created is private
to this graph: if not, then use
que_graph_free_recursive and free the heap
afterwards! */
-/**************************************************************************
+/**********************************************************************//**
Stops a query thread if graph or trx is in a state requiring it. The
conditions are tested in the order (1) graph, (2) trx. The kernel mutex has
-to be reserved. */
+to be reserved.
+@return TRUE if stopped */
UNIV_INTERN
ibool
que_thr_stop(
/*=========*/
- /* out: TRUE if stopped */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction. */
UNIV_INTERN
void
que_thr_move_to_run_state_for_mysql(
/*================================*/
- que_thr_t* thr, /* in: an query thread */
- trx_t* trx); /* in: transaction */
-/**************************************************************************
+ que_thr_t* thr, /*!< in: an query thread */
+ trx_t* trx); /*!< in: transaction */
+/**********************************************************************//**
A patch for MySQL used to 'stop' a dummy query thread used in MySQL
select, when there is no error or lock wait. */
UNIV_INTERN
void
que_thr_stop_for_mysql_no_error(
/*============================*/
- que_thr_t* thr, /* in: query thread */
- trx_t* trx); /* in: transaction */
-/**************************************************************************
+ que_thr_t* thr, /*!< in: query thread */
+ trx_t* trx); /*!< in: transaction */
+/**********************************************************************//**
A patch for MySQL used to 'stop' a dummy query thread used in MySQL. The
query thread is stopped and made inactive, except in the case where
it was put to the lock wait state in lock0lock.c, but the lock has already
@@ -157,15 +148,15 @@ UNIV_INTERN
void
que_thr_stop_for_mysql(
/*===================*/
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
Run a query thread. Handles lock waits. */
UNIV_INTERN
void
que_run_threads(
/*============*/
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
After signal handling is finished, returns control to a query graph error
handling routine. (Currently, just returns the control to the root of the
graph so that the graph can communicate an error message to the client.) */
@@ -173,10 +164,10 @@ UNIV_INTERN
void
que_fork_error_handle(
/*==================*/
- trx_t* trx, /* in: trx */
- que_t* fork); /* in: query graph which was run before signal
+ trx_t* trx, /*!< in: trx */
+ que_t* fork); /*!< in: query graph which was run before signal
handling started, NULL not allowed */
-/**************************************************************************
+/**********************************************************************//**
Moves a suspended query thread to the QUE_THR_RUNNING state and releases
a single worker thread to execute it. This function should be used to end
the wait state of a query thread waiting for a lock or a stored procedure
@@ -185,203 +176,199 @@ UNIV_INTERN
void
que_thr_end_wait(
/*=============*/
- que_thr_t* thr, /* in: query thread in the
+ que_thr_t* thr, /*!< in: query thread in the
QUE_THR_LOCK_WAIT,
or QUE_THR_PROCEDURE_WAIT, or
QUE_THR_SIG_REPLY_WAIT state */
- que_thr_t** next_thr); /* in/out: next query thread to run;
+ que_thr_t** next_thr); /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread */
-/**************************************************************************
+/**********************************************************************//**
Same as que_thr_end_wait, but no parameter next_thr available. */
UNIV_INTERN
void
que_thr_end_wait_no_next_thr(
/*=========================*/
- que_thr_t* thr); /* in: query thread in the
+ que_thr_t* thr); /*!< in: query thread in the
QUE_THR_LOCK_WAIT,
or QUE_THR_PROCEDURE_WAIT, or
QUE_THR_SIG_REPLY_WAIT state */
-/**************************************************************************
+/**********************************************************************//**
Starts execution of a command in a query fork. Picks a query thread which
is not in the QUE_THR_RUNNING state and moves it to that state. If none
can be chosen, a situation which may arise in parallelized fetches, NULL
-is returned. */
+is returned.
+@return a query thread of the graph moved to QUE_THR_RUNNING state, or
+NULL; the query thread should be executed by que_run_threads by the
+caller */
UNIV_INTERN
que_thr_t*
que_fork_start_command(
/*===================*/
- /* out: a query thread of the graph moved to
- QUE_THR_RUNNING state, or NULL; the query
- thread should be executed by que_run_threads
- by the caller */
- que_fork_t* fork); /* in: a query fork */
-/***************************************************************************
+ que_fork_t* fork); /*!< in: a query fork */
+/***********************************************************************//**
Gets the trx of a query thread. */
UNIV_INLINE
trx_t*
thr_get_trx(
/*========*/
- que_thr_t* thr); /* in: query thread */
-/***************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************************//**
Gets the type of a graph node. */
UNIV_INLINE
ulint
que_node_get_type(
/*==============*/
- que_node_t* node); /* in: graph node */
-/***************************************************************************
+ que_node_t* node); /*!< in: graph node */
+/***********************************************************************//**
Gets pointer to the value data type field of a graph node. */
UNIV_INLINE
dtype_t*
que_node_get_data_type(
/*===================*/
- que_node_t* node); /* in: graph node */
-/***************************************************************************
+ que_node_t* node); /*!< in: graph node */
+/***********************************************************************//**
Gets pointer to the value dfield of a graph node. */
UNIV_INLINE
dfield_t*
que_node_get_val(
/*=============*/
- que_node_t* node); /* in: graph node */
-/***************************************************************************
-Gets the value buffer size of a graph node. */
+ que_node_t* node); /*!< in: graph node */
+/***********************************************************************//**
+Gets the value buffer size of a graph node.
+@return val buffer size, not defined if val.data == NULL in node */
UNIV_INLINE
ulint
que_node_get_val_buf_size(
/*======================*/
- /* out: val buffer size, not defined if
- val.data == NULL in node */
- que_node_t* node); /* in: graph node */
-/***************************************************************************
+ que_node_t* node); /*!< in: graph node */
+/***********************************************************************//**
Sets the value buffer size of a graph node. */
UNIV_INLINE
void
que_node_set_val_buf_size(
/*======================*/
- que_node_t* node, /* in: graph node */
- ulint size); /* in: size */
-/*************************************************************************
+ que_node_t* node, /*!< in: graph node */
+ ulint size); /*!< in: size */
+/*********************************************************************//**
Gets the next list node in a list of query graph nodes. */
UNIV_INLINE
que_node_t*
que_node_get_next(
/*==============*/
- que_node_t* node); /* in: node in a list */
-/*************************************************************************
-Gets the parent node of a query graph node. */
+ que_node_t* node); /*!< in: node in a list */
+/*********************************************************************//**
+Gets the parent node of a query graph node.
+@return parent node or NULL */
UNIV_INLINE
que_node_t*
que_node_get_parent(
/*================*/
- /* out: parent node or NULL */
- que_node_t* node); /* in: node */
-/********************************************************************
+ que_node_t* node); /*!< in: node */
+/****************************************************************//**
Get the first containing loop node (e.g. while_node_t or for_node_t) for the
-given node, or NULL if the node is not within a loop. */
+given node, or NULL if the node is not within a loop.
+@return containing loop node, or NULL. */
UNIV_INTERN
que_node_t*
que_node_get_containing_loop_node(
/*==============================*/
- /* out: containing loop node, or NULL. */
- que_node_t* node); /* in: node */
-/*************************************************************************
-Catenates a query graph node to a list of them, possible empty list. */
+ que_node_t* node); /*!< in: node */
+/*********************************************************************//**
+Catenates a query graph node to a list of them, possible empty list.
+@return one-way list of nodes */
UNIV_INLINE
que_node_t*
que_node_list_add_last(
/*===================*/
- /* out: one-way list of nodes */
- que_node_t* node_list, /* in: node list, or NULL */
- que_node_t* node); /* in: node */
-/*************************************************************************
-Gets a query graph node list length. */
+ que_node_t* node_list, /*!< in: node list, or NULL */
+ que_node_t* node); /*!< in: node */
+/*********************************************************************//**
+Gets a query graph node list length.
+@return length, for NULL list 0 */
UNIV_INLINE
ulint
que_node_list_get_len(
/*==================*/
- /* out: length, for NULL list 0 */
- que_node_t* node_list); /* in: node list, or NULL */
-/**************************************************************************
+ que_node_t* node_list); /*!< in: node list, or NULL */
+/**********************************************************************//**
Checks if graph, trx, or session is in a state where the query thread should
-be stopped. */
+be stopped.
+@return TRUE if should be stopped; NOTE that if the peek is made
+without reserving the kernel mutex, then another peek with the mutex
+reserved is necessary before deciding the actual stopping */
UNIV_INLINE
ibool
que_thr_peek_stop(
/*==============*/
- /* out: TRUE if should be stopped; NOTE that
- if the peek is made without reserving the
- kernel mutex, then another peek with the
- mutex reserved is necessary before deciding
- the actual stopping */
- que_thr_t* thr); /* in: query thread */
-/***************************************************************************
-Returns TRUE if the query graph is for a SELECT statement. */
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************************//**
+Returns TRUE if the query graph is for a SELECT statement.
+@return TRUE if a select */
UNIV_INLINE
ibool
que_graph_is_select(
/*================*/
- /* out: TRUE if a select */
- que_t* graph); /* in: graph */
-/**************************************************************************
+ que_t* graph); /*!< in: graph */
+/**********************************************************************//**
Prints info of an SQL query graph node. */
UNIV_INTERN
void
que_node_print_info(
/*================*/
- que_node_t* node); /* in: query graph node */
-/*************************************************************************
-Evaluate the given SQL */
+ que_node_t* node); /*!< in: query graph node */
+/*********************************************************************//**
+Evaluate the given SQL
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
que_eval_sql(
/*=========*/
- /* out: error code or DB_SUCCESS */
- pars_info_t* info, /* in: info struct, or NULL */
- const char* sql, /* in: SQL string */
+ pars_info_t* info, /*!< in: info struct, or NULL */
+ const char* sql, /*!< in: SQL string */
ibool reserve_dict_mutex,
- /* in: if TRUE, acquire/release
+ /*!< in: if TRUE, acquire/release
dict_sys->mutex around call to pars_sql. */
- trx_t* trx); /* in: trx */
+ trx_t* trx); /*!< in: trx */
/* Query graph query thread node: the fields are protected by the kernel
mutex with the exceptions named below */
struct que_thr_struct{
- que_common_t common; /* type: QUE_NODE_THR */
- ulint magic_n; /* magic number to catch memory
+ que_common_t common; /*!< type: QUE_NODE_THR */
+ ulint magic_n; /*!< magic number to catch memory
corruption */
- que_node_t* child; /* graph child node */
- que_t* graph; /* graph where this node belongs */
- ibool is_active; /* TRUE if the thread has been set
+ que_node_t* child; /*!< graph child node */
+ que_t* graph; /*!< graph where this node belongs */
+ ibool is_active; /*!< TRUE if the thread has been set
to the run state in
que_thr_move_to_run_state, but not
deactivated in
que_thr_dec_reference_count */
- ulint state; /* state of the query thread */
+ ulint state; /*!< state of the query thread */
UT_LIST_NODE_T(que_thr_t)
- thrs; /* list of thread nodes of the fork
+ thrs; /*!< list of thread nodes of the fork
node */
UT_LIST_NODE_T(que_thr_t)
- trx_thrs; /* lists of threads in wait list of
+ trx_thrs; /*!< lists of threads in wait list of
the trx */
UT_LIST_NODE_T(que_thr_t)
- queue; /* list of runnable thread nodes in
+ queue; /*!< list of runnable thread nodes in
the server task queue */
/*------------------------------*/
/* The following fields are private to the OS thread executing the
query thread, and are not protected by the kernel mutex: */
- que_node_t* run_node; /* pointer to the node where the
+ que_node_t* run_node; /*!< pointer to the node where the
subgraph down from this node is
currently executed */
- que_node_t* prev_node; /* pointer to the node from which
+ que_node_t* prev_node; /*!< pointer to the node from which
the control came */
- ulint resource; /* resource usage of the query thread
+ ulint resource; /*!< resource usage of the query thread
thus far */
- ulint lock_state; /* lock state of thread (table or
+ ulint lock_state; /*!< lock state of thread (table or
row) */
};
@@ -390,49 +377,49 @@ struct que_thr_struct{
/* Query graph fork node: its fields are protected by the kernel mutex */
struct que_fork_struct{
- que_common_t common; /* type: QUE_NODE_FORK */
- que_t* graph; /* query graph of this node */
- ulint fork_type; /* fork type */
- ulint n_active_thrs; /* if this is the root of a graph, the
+ que_common_t common; /*!< type: QUE_NODE_FORK */
+ que_t* graph; /*!< query graph of this node */
+ ulint fork_type; /*!< fork type */
+ ulint n_active_thrs; /*!< if this is the root of a graph, the
number query threads that have been
started in que_thr_move_to_run_state
but for which que_thr_dec_refer_count
has not yet been called */
- trx_t* trx; /* transaction: this is set only in
+ trx_t* trx; /*!< transaction: this is set only in
the root node */
- ulint state; /* state of the fork node */
- que_thr_t* caller; /* pointer to a possible calling query
+ ulint state; /*!< state of the fork node */
+ que_thr_t* caller; /*!< pointer to a possible calling query
thread */
UT_LIST_BASE_NODE_T(que_thr_t)
- thrs; /* list of query threads */
+ thrs; /*!< list of query threads */
/*------------------------------*/
/* The fields in this section are defined only in the root node */
- sym_tab_t* sym_tab; /* symbol table of the query,
+ sym_tab_t* sym_tab; /*!< symbol table of the query,
generated by the parser, or NULL
if the graph was created 'by hand' */
- pars_info_t* info; /* in: info struct, or NULL */
+ pars_info_t* info; /*!< info struct, or NULL */
/* The following cur_... fields are relevant only in a select graph */
- ulint cur_end; /* QUE_CUR_NOT_DEFINED, QUE_CUR_START,
+ ulint cur_end; /*!< QUE_CUR_NOT_DEFINED, QUE_CUR_START,
QUE_CUR_END */
- ulint cur_pos; /* if there are n rows in the result
+ ulint cur_pos; /*!< if there are n rows in the result
set, values 0 and n + 1 mean before
first row, or after last row, depending
on cur_end; values 1...n mean a row
index */
- ibool cur_on_row; /* TRUE if cursor is on a row, i.e.,
+ ibool cur_on_row; /*!< TRUE if cursor is on a row, i.e.,
it is not before the first row or
after the last row */
- dulint n_inserts; /* number of rows inserted */
- dulint n_updates; /* number of rows updated */
- dulint n_deletes; /* number of rows deleted */
- sel_node_t* last_sel_node; /* last executed select node, or NULL
+ dulint n_inserts; /*!< number of rows inserted */
+ dulint n_updates; /*!< number of rows updated */
+ dulint n_deletes; /*!< number of rows deleted */
+ sel_node_t* last_sel_node; /*!< last executed select node, or NULL
if none */
UT_LIST_NODE_T(que_fork_t)
- graphs; /* list of query graphs of a session
+ graphs; /*!< list of query graphs of a session
or a stored procedure */
/*------------------------------*/
- mem_heap_t* heap; /* memory heap where the fork was
+ mem_heap_t* heap; /*!< memory heap where the fork was
created */
};
diff --git a/storage/xtradb/include/que0que.ic b/storage/xtradb/include/que0que.ic
index e9a6b00b9ab..a1c0dc1e77a 100644
--- a/storage/xtradb/include/que0que.ic
+++ b/storage/xtradb/include/que0que.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/que0que.ic
Query graph
Created 5/27/1996 Heikki Tuuri
@@ -24,37 +25,37 @@ Created 5/27/1996 Heikki Tuuri
#include "usr0sess.h"
-/***************************************************************************
+/***********************************************************************//**
Gets the trx of a query thread. */
UNIV_INLINE
trx_t*
thr_get_trx(
/*========*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ut_ad(thr);
return(thr->graph->trx);
}
-/***************************************************************************
+/***********************************************************************//**
Gets the first thr in a fork. */
UNIV_INLINE
que_thr_t*
que_fork_get_first_thr(
/*===================*/
- que_fork_t* fork) /* in: query fork */
+ que_fork_t* fork) /*!< in: query fork */
{
return(UT_LIST_GET_FIRST(fork->thrs));
}
-/***************************************************************************
+/***********************************************************************//**
Gets the child node of the first thr in a fork. */
UNIV_INLINE
que_node_t*
que_fork_get_child(
/*===============*/
- que_fork_t* fork) /* in: query fork */
+ que_fork_t* fork) /*!< in: query fork */
{
que_thr_t* thr;
@@ -63,97 +64,96 @@ que_fork_get_child(
return(thr->child);
}
-/***************************************************************************
+/***********************************************************************//**
Gets the type of a graph node. */
UNIV_INLINE
ulint
que_node_get_type(
/*==============*/
- que_node_t* node) /* in: graph node */
+ que_node_t* node) /*!< in: graph node */
{
ut_ad(node);
return(((que_common_t*)node)->type);
}
-/***************************************************************************
+/***********************************************************************//**
Gets pointer to the value dfield of a graph node. */
UNIV_INLINE
dfield_t*
que_node_get_val(
/*=============*/
- que_node_t* node) /* in: graph node */
+ que_node_t* node) /*!< in: graph node */
{
ut_ad(node);
return(&(((que_common_t*)node)->val));
}
-/***************************************************************************
-Gets the value buffer size of a graph node. */
+/***********************************************************************//**
+Gets the value buffer size of a graph node.
+@return val buffer size, not defined if val.data == NULL in node */
UNIV_INLINE
ulint
que_node_get_val_buf_size(
/*======================*/
- /* out: val buffer size, not defined if
- val.data == NULL in node */
- que_node_t* node) /* in: graph node */
+ que_node_t* node) /*!< in: graph node */
{
ut_ad(node);
return(((que_common_t*)node)->val_buf_size);
}
-/***************************************************************************
+/***********************************************************************//**
Sets the value buffer size of a graph node. */
UNIV_INLINE
void
que_node_set_val_buf_size(
/*======================*/
- que_node_t* node, /* in: graph node */
- ulint size) /* in: size */
+ que_node_t* node, /*!< in: graph node */
+ ulint size) /*!< in: size */
{
ut_ad(node);
((que_common_t*)node)->val_buf_size = size;
}
-/***************************************************************************
+/***********************************************************************//**
Sets the parent of a graph node. */
UNIV_INLINE
void
que_node_set_parent(
/*================*/
- que_node_t* node, /* in: graph node */
- que_node_t* parent) /* in: parent */
+ que_node_t* node, /*!< in: graph node */
+ que_node_t* parent) /*!< in: parent */
{
ut_ad(node);
((que_common_t*)node)->parent = parent;
}
-/***************************************************************************
+/***********************************************************************//**
Gets pointer to the value data type field of a graph node. */
UNIV_INLINE
dtype_t*
que_node_get_data_type(
/*===================*/
- que_node_t* node) /* in: graph node */
+ que_node_t* node) /*!< in: graph node */
{
ut_ad(node);
return(dfield_get_type(&((que_common_t*) node)->val));
}
-/*************************************************************************
-Catenates a query graph node to a list of them, possible empty list. */
+/*********************************************************************//**
+Catenates a query graph node to a list of them, possible empty list.
+@return one-way list of nodes */
UNIV_INLINE
que_node_t*
que_node_list_add_last(
/*===================*/
- /* out: one-way list of nodes */
- que_node_t* node_list, /* in: node list, or NULL */
- que_node_t* node) /* in: node */
+ que_node_t* node_list, /*!< in: node list, or NULL */
+ que_node_t* node) /*!< in: node */
{
que_common_t* cnode;
que_common_t* cnode2;
@@ -178,26 +178,26 @@ que_node_list_add_last(
return(node_list);
}
-/*************************************************************************
-Gets the next list node in a list of query graph nodes. */
+/*********************************************************************//**
+Gets the next list node in a list of query graph nodes.
+@return next node in a list of nodes */
UNIV_INLINE
que_node_t*
que_node_get_next(
/*==============*/
- /* out: next node in a list of nodes */
- que_node_t* node) /* in: node in a list */
+ que_node_t* node) /*!< in: node in a list */
{
return(((que_common_t*)node)->brother);
}
-/*************************************************************************
-Gets a query graph node list length. */
+/*********************************************************************//**
+Gets a query graph node list length.
+@return length, for NULL list 0 */
UNIV_INLINE
ulint
que_node_list_get_len(
/*==================*/
- /* out: length, for NULL list 0 */
- que_node_t* node_list) /* in: node list, or NULL */
+ que_node_t* node_list) /*!< in: node list, or NULL */
{
const que_common_t* cnode;
ulint len;
@@ -213,31 +213,29 @@ que_node_list_get_len(
return(len);
}
-/*************************************************************************
-Gets the parent node of a query graph node. */
+/*********************************************************************//**
+Gets the parent node of a query graph node.
+@return parent node or NULL */
UNIV_INLINE
que_node_t*
que_node_get_parent(
/*================*/
- /* out: parent node or NULL */
- que_node_t* node) /* in: node */
+ que_node_t* node) /*!< in: node */
{
return(((que_common_t*)node)->parent);
}
-/**************************************************************************
+/**********************************************************************//**
Checks if graph, trx, or session is in a state where the query thread should
-be stopped. */
+be stopped.
+@return TRUE if should be stopped; NOTE that if the peek is made
+without reserving the kernel mutex, then another peek with the mutex
+reserved is necessary before deciding the actual stopping */
UNIV_INLINE
ibool
que_thr_peek_stop(
/*==============*/
- /* out: TRUE if should be stopped; NOTE that
- if the peek is made without reserving the
- kernel mutex, then another peek with the
- mutex reserved is necessary before deciding
- the actual stopping */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
que_t* graph;
@@ -256,14 +254,14 @@ que_thr_peek_stop(
return(FALSE);
}
-/***************************************************************************
-Returns TRUE if the query graph is for a SELECT statement. */
+/***********************************************************************//**
+Returns TRUE if the query graph is for a SELECT statement.
+@return TRUE if a select */
UNIV_INLINE
ibool
que_graph_is_select(
/*================*/
- /* out: TRUE if a select */
- que_t* graph) /* in: graph */
+ que_t* graph) /*!< in: graph */
{
if (graph->fork_type == QUE_FORK_SELECT_SCROLL
|| graph->fork_type == QUE_FORK_SELECT_NON_SCROLL) {
diff --git a/storage/xtradb/include/que0types.h b/storage/xtradb/include/que0types.h
index 1d3217fb491..ea976074768 100644
--- a/storage/xtradb/include/que0types.h
+++ b/storage/xtradb/include/que0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/que0types.h
Query graph global types
Created 5/27/1996 Heikki Tuuri
@@ -43,10 +44,10 @@ typedef struct que_common_struct que_common_t;
substruct must be 'common' */
struct que_common_struct{
- ulint type; /* query node type */
- que_node_t* parent; /* back pointer to parent node, or NULL */
+ ulint type; /*!< query node type */
+ que_node_t* parent; /*!< back pointer to parent node, or NULL */
que_node_t* brother;/* pointer to a possible brother node */
- dfield_t val; /* evaluated value for an expression */
+ dfield_t val; /*!< evaluated value for an expression */
ulint val_buf_size;
/* buffer size for the evaluated value data,
if the buffer has been allocated dynamically:
diff --git a/storage/xtradb/include/read0read.h b/storage/xtradb/include/read0read.h
index 7ea8bdaf8dd..4d9a9fade36 100644
--- a/storage/xtradb/include/read0read.h
+++ b/storage/xtradb/include/read0read.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/read0read.h
Cursor read
Created 2/16/1997 Heikki Tuuri
@@ -33,64 +34,64 @@ Created 2/16/1997 Heikki Tuuri
#include "trx0trx.h"
#include "read0types.h"
-/*************************************************************************
+/*********************************************************************//**
Opens a read view where exactly the transactions serialized before this
-point in time are seen in the view. */
+point in time are seen in the view.
+@return own: read view struct */
UNIV_INTERN
read_view_t*
read_view_open_now(
/*===============*/
- /* out, own: read view struct */
- dulint cr_trx_id, /* in: trx_id of creating
- transaction, or (0, 0) used in
- purge */
- mem_heap_t* heap); /* in: memory heap from which
+ trx_id_t cr_trx_id, /*!< in: trx_id of creating
+ transaction, or ut_dulint_zero
+ used in purge */
+ mem_heap_t* heap); /*!< in: memory heap from which
allocated */
-/*************************************************************************
+/*********************************************************************//**
Makes a copy of the oldest existing read view, or opens a new. The view
-must be closed with ..._close. */
+must be closed with ..._close.
+@return own: read view struct */
UNIV_INTERN
read_view_t*
read_view_oldest_copy_or_open_new(
/*==============================*/
- /* out, own: read view struct */
- dulint cr_trx_id, /* in: trx_id of creating
- transaction, or (0, 0) used in
- purge */
- mem_heap_t* heap); /* in: memory heap from which
+ trx_id_t cr_trx_id, /*!< in: trx_id of creating
+ transaction, or ut_dulint_zero
+ used in purge */
+ mem_heap_t* heap); /*!< in: memory heap from which
allocated */
-/*************************************************************************
+/*********************************************************************//**
Closes a read view. */
UNIV_INTERN
void
read_view_close(
/*============*/
- read_view_t* view); /* in: read view */
-/*************************************************************************
+ read_view_t* view); /*!< in: read view */
+/*********************************************************************//**
Closes a consistent read view for MySQL. This function is called at an SQL
statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
UNIV_INTERN
void
read_view_close_for_mysql(
/*======================*/
- trx_t* trx); /* in: trx which has a read view */
-/*************************************************************************
-Checks if a read view sees the specified transaction. */
+ trx_t* trx); /*!< in: trx which has a read view */
+/*********************************************************************//**
+Checks if a read view sees the specified transaction.
+@return TRUE if sees */
UNIV_INLINE
ibool
read_view_sees_trx_id(
/*==================*/
- /* out: TRUE if sees */
- read_view_t* view, /* in: read view */
- dulint trx_id);/* in: trx id */
-/*************************************************************************
+ const read_view_t* view, /*!< in: read view */
+ trx_id_t trx_id);/*!< in: trx id */
+/*********************************************************************//**
Prints a read view to stderr. */
UNIV_INTERN
void
read_view_print(
/*============*/
- read_view_t* view); /* in: read view */
-/*************************************************************************
+ const read_view_t* view); /*!< in: read view */
+/*********************************************************************//**
Create a consistent cursor view for mysql to be used in cursors. In this
consistent read view modifications done by the creating transaction or future
transactions are not visible. */
@@ -98,17 +99,17 @@ UNIV_INTERN
cursor_view_t*
read_cursor_view_create_for_mysql(
/*==============================*/
- trx_t* cr_trx);/* in: trx where cursor view is created */
-/*************************************************************************
+ trx_t* cr_trx);/*!< in: trx where cursor view is created */
+/*********************************************************************//**
Close a given consistent cursor view for mysql and restore global read view
back to a transaction read view. */
UNIV_INTERN
void
read_cursor_view_close_for_mysql(
/*=============================*/
- trx_t* trx, /* in: trx */
- cursor_view_t* curview); /* in: cursor view to be closed */
-/*************************************************************************
+ trx_t* trx, /*!< in: trx */
+ cursor_view_t* curview); /*!< in: cursor view to be closed */
+/*********************************************************************//**
This function sets a given consistent cursor view to a transaction
read view if given consistent cursor view is not NULL. Otherwise, function
restores a global read view to a transaction read view. */
@@ -116,61 +117,73 @@ UNIV_INTERN
void
read_cursor_set_for_mysql(
/*======================*/
- trx_t* trx, /* in: transaction where cursor is set */
- cursor_view_t* curview);/* in: consistent cursor view to be set */
+ trx_t* trx, /*!< in: transaction where cursor is set */
+ cursor_view_t* curview);/*!< in: consistent cursor view to be set */
-/* Read view lists the trx ids of those transactions for which a consistent
+/** Read view lists the trx ids of those transactions for which a consistent
read should not see the modifications to the database. */
struct read_view_struct{
- ulint type; /* VIEW_NORMAL, VIEW_HIGH_GRANULARITY */
- dulint undo_no; /* (0, 0) or if type is VIEW_HIGH_GRANULARITY
+ ulint type; /*!< VIEW_NORMAL, VIEW_HIGH_GRANULARITY */
+ undo_no_t undo_no;/*!< ut_dulint_zero or if type is
+ VIEW_HIGH_GRANULARITY
transaction undo_no when this high-granularity
consistent read view was created */
- dulint low_limit_no; /* The view does not need to see the undo
+ trx_id_t low_limit_no;
+ /*!< The view does not need to see the undo
logs for transactions whose transaction number
is strictly smaller (<) than this value: they
can be removed in purge if not needed by other
views */
- dulint low_limit_id; /* The read should not see any transaction
- with trx id >= this value */
- dulint up_limit_id; /* The read should see all trx ids which
- are strictly smaller (<) than this value */
- ulint n_trx_ids; /* Number of cells in the trx_ids array */
- dulint* trx_ids; /* Additional trx ids which the read should
+ trx_id_t low_limit_id;
+ /*!< The read should not see any transaction
+ with trx id >= this value. In other words,
+ this is the "high water mark". */
+ trx_id_t up_limit_id;
+ /*!< The read should see all trx ids which
+ are strictly smaller (<) than this value.
+ In other words,
+ this is the "low water mark". */
+ ulint n_trx_ids;
+ /*!< Number of cells in the trx_ids array */
+ trx_id_t* trx_ids;/*!< Additional trx ids which the read should
not see: typically, these are the active
transactions at the time when the read is
serialized, except the reading transaction
itself; the trx ids in this array are in a
- descending order */
- dulint creator_trx_id; /* trx id of creating transaction, or
- (0, 0) used in purge */
+ descending order. These trx_ids should be
+ between the "low" and "high" water marks,
+ that is, up_limit_id and low_limit_id. */
+ trx_id_t creator_trx_id;
+ /*!< trx id of creating transaction, or
+ ut_dulint_zero used in purge */
UT_LIST_NODE_T(read_view_t) view_list;
- /* List of read views in trx_sys */
+ /*!< List of read views in trx_sys */
};
-/* Read view types */
-#define VIEW_NORMAL 1 /* Normal consistent read view
+/** Read view types @{ */
+#define VIEW_NORMAL 1 /*!< Normal consistent read view
where transaction does not see changes
made by active transactions except
creating transaction. */
-#define VIEW_HIGH_GRANULARITY 2 /* High-granularity read view where
+#define VIEW_HIGH_GRANULARITY 2 /*!< High-granularity read view where
transaction does not see changes
made by active transactions and own
changes after a point in time when this
read view was created. */
+/* @} */
-/* Implement InnoDB framework to support consistent read views in
+/** Implement InnoDB framework to support consistent read views in
cursors. This struct holds both heap where consistent read view
is allocated and pointer to a read view. */
struct cursor_view_struct{
mem_heap_t* heap;
- /* Memory heap for the cursor view */
+ /*!< Memory heap for the cursor view */
read_view_t* read_view;
- /* Consistent read view of the cursor*/
+ /*!< Consistent read view of the cursor*/
ulint n_mysql_tables_in_use;
- /* number of Innobase tables used in the
+ /*!< number of Innobase tables used in the
processing of this cursor */
};
diff --git a/storage/xtradb/include/read0read.ic b/storage/xtradb/include/read0read.ic
index 9fc6af04e88..9924967cc2d 100644
--- a/storage/xtradb/include/read0read.ic
+++ b/storage/xtradb/include/read0read.ic
@@ -16,51 +16,52 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/read0read.ic
Cursor read
Created 2/16/1997 Heikki Tuuri
*******************************************************/
-/*************************************************************************
-Gets the nth trx id in a read view. */
+/*********************************************************************//**
+Gets the nth trx id in a read view.
+@return trx id */
UNIV_INLINE
-dulint
+trx_id_t
read_view_get_nth_trx_id(
/*=====================*/
- /* out: trx id */
- read_view_t* view, /* in: read view */
- ulint n) /* in: position */
+ const read_view_t* view, /*!< in: read view */
+ ulint n) /*!< in: position */
{
ut_ad(n < view->n_trx_ids);
return(*(view->trx_ids + n));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the nth trx id in a read view. */
UNIV_INLINE
void
read_view_set_nth_trx_id(
/*=====================*/
- read_view_t* view, /* in: read view */
- ulint n, /* in: position */
- dulint trx_id) /* in: trx id to set */
+ read_view_t* view, /*!< in: read view */
+ ulint n, /*!< in: position */
+ trx_id_t trx_id) /*!< in: trx id to set */
{
ut_ad(n < view->n_trx_ids);
*(view->trx_ids + n) = trx_id;
}
-/*************************************************************************
-Checks if a read view sees the specified transaction. */
+/*********************************************************************//**
+Checks if a read view sees the specified transaction.
+@return TRUE if sees */
UNIV_INLINE
ibool
read_view_sees_trx_id(
/*==================*/
- /* out: TRUE if sees */
- read_view_t* view, /* in: read view */
- dulint trx_id) /* in: trx id */
+ const read_view_t* view, /*!< in: read view */
+ trx_id_t trx_id) /*!< in: trx id */
{
ulint n_ids;
int cmp;
diff --git a/storage/xtradb/include/read0types.h b/storage/xtradb/include/read0types.h
index 44849cbb498..caf69e3fb51 100644
--- a/storage/xtradb/include/read0types.h
+++ b/storage/xtradb/include/read0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/read0types.h
Cursor read
Created 2/16/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/rem0cmp.h b/storage/xtradb/include/rem0cmp.h
index 4687e0ee45e..421308af49b 100644
--- a/storage/xtradb/include/rem0cmp.h
+++ b/storage/xtradb/include/rem0cmp.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/rem0cmp.h
Comparison services for records
Created 7/1/1994 Heikki Tuuri
@@ -31,172 +32,160 @@ Created 7/1/1994 Heikki Tuuri
#include "dict0dict.h"
#include "rem0rec.h"
-/*****************************************************************
-Returns TRUE if two columns are equal for comparison purposes. */
+/*************************************************************//**
+Returns TRUE if two columns are equal for comparison purposes.
+@return TRUE if the columns are considered equal in comparisons */
UNIV_INTERN
ibool
cmp_cols_are_equal(
/*===============*/
- /* out: TRUE if the columns are
- considered equal in comparisons */
- const dict_col_t* col1, /* in: column 1 */
- const dict_col_t* col2, /* in: column 2 */
+ const dict_col_t* col1, /*!< in: column 1 */
+ const dict_col_t* col2, /*!< in: column 2 */
ibool check_charsets);
- /* in: whether to check charsets */
-/*****************************************************************
+ /*!< in: whether to check charsets */
+/*************************************************************//**
This function is used to compare two data fields for which we know the
-data type. */
+data type.
+@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
UNIV_INLINE
int
cmp_data_data(
/*==========*/
- /* out: 1, 0, -1, if data1 is greater, equal,
- less than data2, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* data1, /* in: data field (== a pointer to a memory
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* data1, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len1, /* in: data field length or UNIV_SQL_NULL */
- const byte* data2, /* in: data field (== a pointer to a memory
+ ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
+ const byte* data2, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len2); /* in: data field length or UNIV_SQL_NULL */
-/*****************************************************************
+ ulint len2); /*!< in: data field length or UNIV_SQL_NULL */
+/*************************************************************//**
This function is used to compare two data fields for which we know the
-data type. */
+data type.
+@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
UNIV_INTERN
int
cmp_data_data_slow(
/*===============*/
- /* out: 1, 0, -1, if data1 is greater, equal,
- less than data2, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* data1, /* in: data field (== a pointer to a memory
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* data1, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len1, /* in: data field length or UNIV_SQL_NULL */
- const byte* data2, /* in: data field (== a pointer to a memory
+ ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
+ const byte* data2, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len2); /* in: data field length or UNIV_SQL_NULL */
-/*****************************************************************
+ ulint len2); /*!< in: data field length or UNIV_SQL_NULL */
+/*************************************************************//**
This function is used to compare two dfields where at least the first
-has its data type field set. */
+has its data type field set.
+@return 1, 0, -1, if dfield1 is greater, equal, less than dfield2,
+respectively */
UNIV_INLINE
int
cmp_dfield_dfield(
/*==============*/
- /* out: 1, 0, -1, if dfield1 is greater, equal,
- less than dfield2, respectively */
- const dfield_t* dfield1,/* in: data field; must have type field set */
- const dfield_t* dfield2);/* in: data field */
-/*****************************************************************
+ const dfield_t* dfield1,/*!< in: data field; must have type field set */
+ const dfield_t* dfield2);/*!< in: data field */
+/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
-the the data tuple! If we denote by n = n_fields_cmp, then rec must
+the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
-made. */
+made.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared, or until
+the first externally stored field in rec */
UNIV_INTERN
int
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, or
- until the first externally stored field in
- rec */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record which differs from
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record which differs from
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() */
- ulint* matched_fields, /* in/out: number of already completely
+ 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
+ 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 */
-/******************************************************************
-Compares a data tuple to a physical record. */
+/**************************************************************//**
+Compares a data tuple to a physical record.
+@see cmp_dtuple_rec_with_match
+@return 1, 0, -1, if dtuple is greater, equal, less than rec, respectively */
UNIV_INTERN
int
cmp_dtuple_rec(
/*===========*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively; see the comments
- for cmp_dtuple_rec_with_match */
- 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 dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_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. */
+is allowed to be a prefix of the corresponding field in the record.
+@return TRUE if prefix */
UNIV_INTERN
ibool
cmp_dtuple_is_prefix_of_rec(
/*========================*/
- /* out: TRUE if prefix */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-#ifndef UNIV_HOTBACKUP
-/*****************************************************************
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* 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. */
+none of which are stored externally.
+@return 1, 0, -1 if rec1 is greater, equal, less, respectively, than rec2 */
UNIV_INTERN
int
cmp_rec_rec_simple(
/*===============*/
- /* out: 1, 0 , -1 if rec1 is greater,
- equal, less, respectively, than rec2 */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- const dict_index_t* index); /* in: data dictionary index */
-#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+ 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 dict_index_t* index); /*!< in: data dictionary index */
+/*************************************************************//**
This function is used to compare two physical records. Only the common
first fields are compared, and if an externally stored field is
-encountered, then 0 is returned. */
+encountered, then 0 is returned.
+@return 1, 0, -1 if rec1 is greater, equal, less, respectively */
UNIV_INTERN
int
cmp_rec_rec_with_match(
/*===================*/
- /* out: 1, 0 , -1 if rec1 is greater, equal,
- less, respectively, than rec2; only the common
- first fields are compared */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- dict_index_t* index, /* in: data dictionary index */
- ulint* matched_fields, /* in/out: number of already completely
+ const rec_t* rec1, /*!< in: physical record */
+ const rec_t* rec2, /*!< in: physical record */
+ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
+ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
+ dict_index_t* index, /*!< in: data dictionary index */
+ ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when the function returns,
contains the value the for current
comparison */
- ulint* matched_bytes, /* in/out: number of already matched
+ ulint* matched_bytes, /*!< in/out: number of already matched
bytes within the first field not completely
matched; when the function returns, contains
the value for the current comparison */
ulint stats_method);
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two physical records. Only the common
-first fields are compared. */
+first fields are compared.
+@return 1, 0 , -1 if rec1 is greater, equal, less, respectively, than
+rec2; only the common first fields are compared */
UNIV_INLINE
int
cmp_rec_rec(
/*========*/
- /* out: 1, 0 , -1 if rec1 is greater, equal,
- less, respectively, than rec2; only the common
- first fields are compared */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- dict_index_t* index); /* in: data dictionary index */
+ const rec_t* rec1, /*!< in: physical record */
+ const rec_t* rec2, /*!< in: physical record */
+ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
+ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
+ dict_index_t* index); /*!< in: data dictionary index */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/rem0cmp.ic b/storage/xtradb/include/rem0cmp.ic
index 1abf4142531..d5185ec94af 100644
--- a/storage/xtradb/include/rem0cmp.ic
+++ b/storage/xtradb/include/rem0cmp.ic
@@ -16,44 +16,44 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/rem0cmp.ic
Comparison services for records
Created 7/1/1994 Heikki Tuuri
************************************************************************/
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two data fields for which we know the
-data type. */
+data type.
+@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
UNIV_INLINE
int
cmp_data_data(
/*==========*/
- /* out: 1, 0, -1, if data1 is greater, equal,
- less than data2, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* data1, /* in: data field (== a pointer to a memory
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* data1, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len1, /* in: data field length or UNIV_SQL_NULL */
- const byte* data2, /* in: data field (== a pointer to a memory
+ ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
+ const byte* data2, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len2) /* in: data field length or UNIV_SQL_NULL */
+ ulint len2) /*!< in: data field length or UNIV_SQL_NULL */
{
return(cmp_data_data_slow(mtype, prtype, data1, len1, data2, len2));
}
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two dfields where at least the first
-has its data type field set. */
+has its data type field set.
+@return 1, 0, -1, if dfield1 is greater, equal, less than dfield2,
+respectively */
UNIV_INLINE
int
cmp_dfield_dfield(
/*==============*/
- /* out: 1, 0, -1, if dfield1 is greater, equal,
- less than dfield2, respectively */
- const dfield_t* dfield1,/* in: data field; must have type field set */
- const dfield_t* dfield2)/* in: data field */
+ const dfield_t* dfield1,/*!< in: data field; must have type field set */
+ const dfield_t* dfield2)/*!< in: data field */
{
const dtype_t* type;
@@ -68,21 +68,20 @@ cmp_dfield_dfield(
dfield_get_len(dfield2)));
}
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two physical records. Only the common
-first fields are compared. */
+first fields are compared.
+@return 1, 0 , -1 if rec1 is greater, equal, less, respectively, than
+rec2; only the common first fields are compared */
UNIV_INLINE
int
cmp_rec_rec(
/*========*/
- /* out: 1, 0 , -1 if rec1 is greater, equal,
- less, respectively, than rec2; only the common
- first fields are compared */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- dict_index_t* index) /* in: data dictionary index */
+ const rec_t* rec1, /*!< in: physical record */
+ const rec_t* rec2, /*!< in: physical record */
+ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
+ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
+ dict_index_t* index) /*!< in: data dictionary index */
{
ulint match_f = 0;
ulint match_b = 0;
diff --git a/storage/xtradb/include/rem0rec.h b/storage/xtradb/include/rem0rec.h
index cb72a5fa25b..17d08afabb9 100644
--- a/storage/xtradb/include/rem0rec.h
+++ b/storage/xtradb/include/rem0rec.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/rem0rec.h
Record manager
Created 5/30/1994 Heikki Tuuri
@@ -78,293 +79,289 @@ offsets[] array, first passed to rec_get_offsets() */
#define REC_OFFS_NORMAL_SIZE 100
#define REC_OFFS_SMALL_SIZE 10
-/**********************************************************
+/******************************************************//**
The following function is used to get the pointer of the next chained record
-on the same page. */
+on the same page.
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
const rec_t*
rec_get_next_ptr_const(
/*===================*/
- /* out: pointer to the next chained record, or
- NULL if none */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to get the pointer of the next chained record
-on the same page. */
+on the same page.
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
rec_t*
rec_get_next_ptr(
/*=============*/
- /* out: pointer to the next chained record, or
- NULL if none */
- rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to get the offset of the
-next chained record on the same page. */
+next chained record on the same page.
+@return the page offset of the next chained record, or 0 if none */
UNIV_INLINE
ulint
rec_get_next_offs(
/*==============*/
- /* out: the page offset of the next
- chained record, or 0 if none */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to set the next record offset field
of an old-style record. */
UNIV_INLINE
void
rec_set_next_offs_old(
/*==================*/
- rec_t* rec, /* in: old-style physical record */
- ulint next); /* in: offset of the next record */
-/**********************************************************
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint next); /*!< in: offset of the next record */
+/******************************************************//**
The following function is used to set the next record offset field
of a new-style record. */
UNIV_INLINE
void
rec_set_next_offs_new(
/*==================*/
- rec_t* rec, /* in/out: new-style physical record */
- ulint next); /* in: offset of the next record */
-/**********************************************************
+ rec_t* rec, /*!< in/out: new-style physical record */
+ ulint next); /*!< in: offset of the next record */
+/******************************************************//**
The following function is used to get the number of fields
-in an old-style record. */
+in an old-style record.
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields_old(
/*=================*/
- /* out: number of data fields */
- const rec_t* rec); /* in: physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: physical record */
+/******************************************************//**
The following function is used to get the number of fields
-in a record. */
+in a record.
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields(
/*=============*/
- /* out: number of data fields */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index); /* in: record descriptor */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index); /*!< in: record descriptor */
+/******************************************************//**
The following function is used to get the number of records owned by the
-previous directory record. */
+previous directory record.
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_old(
/*================*/
- /* out: number of owned records */
- const rec_t* rec); /* in: old-style physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: old-style physical record */
+/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_old(
/*================*/
- /* out: TRUE on success */
- rec_t* rec, /* in: old-style physical record */
- ulint n_owned); /* in: the number of owned */
-/**********************************************************
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint n_owned); /*!< in: the number of owned */
+/******************************************************//**
The following function is used to get the number of records owned by the
-previous directory record. */
+previous directory record.
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_new(
/*================*/
- /* out: number of owned records */
- const rec_t* rec); /* in: new-style physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: new-style physical record */
+/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_new(
/*================*/
- rec_t* rec, /* in/out: new-style physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint n_owned);/* in: the number of owned */
-/**********************************************************
+ rec_t* rec, /*!< in/out: new-style physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint n_owned);/*!< in: the number of owned */
+/******************************************************//**
The following function is used to retrieve the info bits of
-a record. */
+a record.
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_bits(
/*==============*/
- /* out: info bits */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_old(
/*==================*/
- rec_t* rec, /* in: old-style physical record */
- ulint bits); /* in: info bits */
-/**********************************************************
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint bits); /*!< in: info bits */
+/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_new(
/*==================*/
- rec_t* rec, /* in/out: new-style physical record */
- ulint bits); /* in: info bits */
-/**********************************************************
-The following function retrieves the status bits of a new-style record. */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ ulint bits); /*!< in: info bits */
+/******************************************************//**
+The following function retrieves the status bits of a new-style record.
+@return status bits */
UNIV_INLINE
ulint
rec_get_status(
/*===========*/
- /* out: status bits */
- const rec_t* rec); /* in: physical record */
+ const rec_t* rec); /*!< in: physical record */
-/**********************************************************
+/******************************************************//**
The following function is used to set the status bits of a new-style record. */
UNIV_INLINE
void
rec_set_status(
/*===========*/
- rec_t* rec, /* in/out: physical record */
- ulint bits); /* in: info bits */
+ rec_t* rec, /*!< in/out: physical record */
+ ulint bits); /*!< in: info bits */
-/**********************************************************
+/******************************************************//**
The following function is used to retrieve the info and status
-bits of a record. (Only compact records have status bits.) */
+bits of a record. (Only compact records have status bits.)
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_and_status_bits(
/*=========================*/
- /* out: info bits */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
UNIV_INLINE
void
rec_set_info_and_status_bits(
/*=========================*/
- rec_t* rec, /* in/out: compact physical record */
- ulint bits); /* in: info bits */
+ rec_t* rec, /*!< in/out: compact physical record */
+ ulint bits); /*!< in: info bits */
-/**********************************************************
-The following function tells if record is delete marked. */
+/******************************************************//**
+The following function tells if record is delete marked.
+@return nonzero if delete marked */
UNIV_INLINE
ulint
rec_get_deleted_flag(
/*=================*/
- /* out: nonzero if delete marked */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_old(
/*=====================*/
- rec_t* rec, /* in: old-style physical record */
- ulint flag); /* in: nonzero if delete marked */
-/**********************************************************
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint flag); /*!< in: nonzero if delete marked */
+/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_new(
/*=====================*/
- rec_t* rec, /* in/out: new-style physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint flag); /* in: nonzero if delete marked */
-/**********************************************************
-The following function tells if a new-style record is a node pointer. */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint flag); /*!< in: nonzero if delete marked */
+/******************************************************//**
+The following function tells if a new-style record is a node pointer.
+@return TRUE if node pointer */
UNIV_INLINE
ibool
rec_get_node_ptr_flag(
/*==================*/
- /* out: TRUE if node pointer */
- const rec_t* rec); /* in: physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: physical record */
+/******************************************************//**
The following function is used to get the order number
-of an old-style record in the heap of the index page. */
+of an old-style record in the heap of the index page.
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_old(
/*================*/
- /* out: heap order number */
- const rec_t* rec); /* in: physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: physical record */
+/******************************************************//**
The following function is used to set the heap number
field in an old-style record. */
UNIV_INLINE
void
rec_set_heap_no_old(
/*================*/
- rec_t* rec, /* in: physical record */
- ulint heap_no);/* in: the heap number */
-/**********************************************************
+ rec_t* rec, /*!< in: physical record */
+ ulint heap_no);/*!< in: the heap number */
+/******************************************************//**
The following function is used to get the order number
-of a new-style record in the heap of the index page. */
+of a new-style record in the heap of the index page.
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_new(
/*================*/
- /* out: heap order number */
- const rec_t* rec); /* in: physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: physical record */
+/******************************************************//**
The following function is used to set the heap number
field in a new-style record. */
UNIV_INLINE
void
rec_set_heap_no_new(
/*================*/
- rec_t* rec, /* in/out: physical record */
- ulint heap_no);/* in: the heap number */
-/**********************************************************
+ rec_t* rec, /*!< in/out: physical record */
+ ulint heap_no);/*!< in: the heap number */
+/******************************************************//**
The following function is used to test whether the data offsets
-in the record are stored in one-byte or two-byte format. */
+in the record are stored in one-byte or two-byte format.
+@return TRUE if 1-byte form */
UNIV_INLINE
ibool
rec_get_1byte_offs_flag(
/*====================*/
- /* out: TRUE if 1-byte form */
- const rec_t* rec); /* in: physical record */
+ const rec_t* rec); /*!< in: physical record */
-/**********************************************************
+/******************************************************//**
Determine how many of the first n columns in a compact
-physical record are stored externally. */
+physical record are stored externally.
+@return number of externally stored columns */
UNIV_INTERN
ulint
rec_get_n_extern_new(
/*=================*/
- /* out: number of externally stored columns */
- const rec_t* rec, /* in: compact physical record */
- dict_index_t* index, /* in: record descriptor */
- ulint n); /* in: number of columns to scan */
+ const rec_t* rec, /*!< in: compact physical record */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n); /*!< in: number of columns to scan */
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field
-in the record. It can reuse a previously allocated array. */
+in the record. It can reuse a previously allocated array.
+@return the new offsets */
UNIV_INTERN
ulint*
rec_get_offsets_func(
/*=================*/
- /* out: the new offsets */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets,/* in/out: array consisting of
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets,/*!< in/out: array consisting of
offsets[0] allocated elements,
or an array from rec_get_offsets(),
or NULL */
- ulint n_fields,/* in: maximum number of
+ ulint n_fields,/*!< in: maximum number of
initialized fields
(ULINT_UNDEFINED if all fields) */
- mem_heap_t** heap, /* in/out: memory heap */
- const char* file, /* in: file name where called */
- ulint line); /* in: line number where called */
+ mem_heap_t** heap, /*!< in/out: memory heap */
+ const char* file, /*!< in: file name where called */
+ ulint line); /*!< in: line number where called */
#define rec_get_offsets(rec,index,offsets,n,heap) \
rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
-/**********************************************************
+/******************************************************//**
Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT. This is a special case of
rec_init_offsets() and rec_get_offsets_func(). */
@@ -372,154 +369,154 @@ UNIV_INTERN
void
rec_init_offsets_comp_ordinary(
/*===========================*/
- const rec_t* rec, /* in: physical record in
+ const rec_t* rec, /*!< in: physical record in
ROW_FORMAT=COMPACT */
- ulint extra, /* in: number of bytes to reserve
+ ulint extra, /*!< in: number of bytes to reserve
between the record header and
the data payload
(usually REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets);/* in/out: array of offsets;
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets);/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field
in the record. It can reuse a previously allocated array. */
UNIV_INTERN
void
rec_get_offsets_reverse(
/*====================*/
- const byte* extra, /* in: the extra bytes of a
+ const byte* extra, /*!< in: the extra bytes of a
compact record in reverse order,
excluding the fixed-size
REC_N_NEW_EXTRA_BYTES */
- const dict_index_t* index, /* in: record descriptor */
- ulint node_ptr,/* in: nonzero=node pointer,
+ 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
+ ulint* offsets);/*!< in/out: array consisting of
offsets[0] allocated elements */
-/****************************************************************
-Validates offsets returned by rec_get_offsets(). */
+/************************************************************//**
+Validates offsets returned by rec_get_offsets().
+@return TRUE if valid */
UNIV_INLINE
ibool
rec_offs_validate(
/*==============*/
- /* out: TRUE if valid */
- 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_t* rec, /*!< in: record or NULL */
+ const dict_index_t* index, /*!< in: record descriptor or NULL */
+ const ulint* offsets);/*!< in: array returned by
rec_get_offsets() */
#ifdef UNIV_DEBUG
-/****************************************************************
+/************************************************************//**
Updates debug data in offsets, in order to avoid bogus
rec_offs_validate() failures. */
UNIV_INLINE
void
rec_offs_make_valid(
/*================*/
- const rec_t* rec, /* in: record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets);/* in: array returned by
+ const rec_t* rec, /*!< in: record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets);/*!< in: array returned by
rec_get_offsets() */
#else
# define rec_offs_make_valid(rec, index, offsets) ((void) 0)
#endif /* UNIV_DEBUG */
-/****************************************************************
+/************************************************************//**
The following function is used to get the offset to the nth
-data field in an old-style record. */
+data field in an old-style record.
+@return offset to the field */
UNIV_INTERN
ulint
rec_get_nth_field_offs_old(
/*=======================*/
- /* out: offset to the field */
- const rec_t* rec, /* in: record */
- ulint n, /* in: index of the field */
- ulint* len); /* out: length of the field; UNIV_SQL_NULL
+ const rec_t* rec, /*!< in: record */
+ ulint n, /*!< in: index of the field */
+ ulint* len); /*!< out: length of the field; UNIV_SQL_NULL
if SQL null */
#define rec_get_nth_field_old(rec, n, len) \
((rec) + rec_get_nth_field_offs_old(rec, n, len))
-/****************************************************************
+/************************************************************//**
Gets the physical size of an old-style field.
Also an SQL null may have a field of size > 0,
-if the data type is of a fixed size. */
+if the data type is of a fixed size.
+@return field size in bytes */
UNIV_INLINE
ulint
rec_get_nth_field_size(
/*===================*/
- /* out: field size in bytes */
- const rec_t* rec, /* in: record */
- ulint n); /* in: index of the field */
-/****************************************************************
+ const rec_t* rec, /*!< in: record */
+ ulint n); /*!< in: index of the field */
+/************************************************************//**
The following function is used to get an offset to the nth
-data field in a record. */
+data field in a record.
+@return offset from the origin of rec */
UNIV_INLINE
ulint
rec_get_nth_field_offs(
/*===================*/
- /* out: offset from the origin of rec */
- const ulint* 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
+ const ulint* 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 */
#define rec_get_nth_field(rec, offsets, n, len) \
((rec) + rec_get_nth_field_offs(offsets, n, len))
-/**********************************************************
+/******************************************************//**
Determine if the offsets are for a record in the new
-compact format. */
+compact format.
+@return nonzero if compact format */
UNIV_INLINE
ulint
rec_offs_comp(
/*==========*/
- /* out: nonzero if compact format */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**********************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/******************************************************//**
Determine if the offsets are for a record containing
-externally stored columns. */
+externally stored columns.
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_any_extern(
/*================*/
- /* out: nonzero if externally stored */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**********************************************************
-Returns nonzero if the extern bit is set in nth field of rec. */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/******************************************************//**
+Returns nonzero if the extern bit is set in nth field of rec.
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_nth_extern(
/*================*/
- /* out: nonzero if externally stored */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n); /* in: nth field */
-/**********************************************************
-Returns nonzero if the SQL NULL bit is set in nth field of rec. */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n); /*!< in: nth field */
+/******************************************************//**
+Returns nonzero if the SQL NULL bit is set in nth field of rec.
+@return nonzero if SQL NULL */
UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
- /* out: nonzero if SQL NULL */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n); /* in: nth field */
-/**********************************************************
-Gets the physical size of a field. */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n); /*!< in: nth field */
+/******************************************************//**
+Gets the physical size of a field.
+@return length of field */
UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
- /* out: length of field */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n); /* in: nth field */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n); /*!< in: nth field */
-/**********************************************************
-Returns the number of extern bits set in a record. */
+/******************************************************//**
+Returns the number of extern bits set in a record.
+@return number of externally stored fields */
UNIV_INLINE
ulint
rec_offs_n_extern(
/*==============*/
- /* out: number of externally stored fields */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/***************************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***********************************************************//**
This is used to modify the value of an already existing field in a record.
The previous value must have exactly the same size as the new value. If len
is UNIV_SQL_NULL then the field is treated as an SQL null.
@@ -529,280 +526,285 @@ UNIV_INLINE
void
rec_set_nth_field(
/*==============*/
- rec_t* rec, /* in: record */
- const ulint* 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 */
-/**************************************************************
+ rec_t* rec, /*!< in: record */
+ const ulint* 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 */
+/**********************************************************//**
The following function returns the data size of an old-style physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
-is the distance from record origin to record end in bytes. */
+is the distance from record origin to record end in bytes.
+@return size */
UNIV_INLINE
ulint
rec_get_data_size_old(
/*==================*/
- /* out: size */
- const rec_t* rec); /* in: physical record */
-/**************************************************************
+ const rec_t* rec); /*!< in: physical record */
+/**********************************************************//**
The following function returns the number of allocated elements
-for an array of offsets. */
+for an array of offsets.
+@return number of elements */
UNIV_INLINE
ulint
rec_offs_get_n_alloc(
/*=================*/
- /* out: number of elements */
- const ulint* offsets);/* in: array for rec_get_offsets() */
-/**************************************************************
+ const ulint* offsets);/*!< in: array for rec_get_offsets() */
+/**********************************************************//**
The following function sets the number of allocated elements
for an array of offsets. */
UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
- ulint* offsets, /* out: array for rec_get_offsets(),
+ ulint* offsets, /*!< out: array for rec_get_offsets(),
must be allocated */
- ulint n_alloc); /* in: number of elements */
+ ulint n_alloc); /*!< in: number of elements */
#define rec_offs_init(offsets) \
rec_offs_set_n_alloc(offsets, (sizeof offsets) / sizeof *offsets)
-/**************************************************************
-The following function returns the number of fields in a record. */
+/**********************************************************//**
+The following function returns the number of fields in a record.
+@return number of fields */
UNIV_INLINE
ulint
rec_offs_n_fields(
/*==============*/
- /* out: number of fields */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
The following function returns the data size of a physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
-is the distance from record origin to record end in bytes. */
+is the distance from record origin to record end in bytes.
+@return size */
UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
- /* out: size */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
Returns the total size of record minus data size of record.
The value returned by the function is the distance from record
-start to record origin in bytes. */
+start to record origin in bytes.
+@return size */
UNIV_INLINE
ulint
rec_offs_extra_size(
/*================*/
- /* out: size */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
-Returns the total size of a physical record. */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
+Returns the total size of a physical record.
+@return size */
UNIV_INLINE
ulint
rec_offs_size(
/*==========*/
- /* out: size */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
-Returns a pointer to the start of the record. */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
+Returns a pointer to the start of the record.
+@return pointer to start */
UNIV_INLINE
byte*
rec_get_start(
/*==========*/
- /* out: pointer to start */
- rec_t* rec, /* in: pointer to record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
-Returns a pointer to the end of the record. */
+ rec_t* rec, /*!< in: pointer to record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
+Returns a pointer to the end of the record.
+@return pointer to end */
UNIV_INLINE
byte*
rec_get_end(
/*========*/
- /* out: pointer to end */
- rec_t* rec, /* in: pointer to record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
-Copies a physical record to a buffer. */
+ rec_t* rec, /*!< in: pointer to record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
+Copies a physical record to a buffer.
+@return pointer to the origin of the copy */
UNIV_INLINE
rec_t*
rec_copy(
/*=====*/
- /* out: pointer to the origin of the copy */
- void* buf, /* in: buffer */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/******************************************************************
+ void* buf, /*!< in: buffer */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+#ifndef UNIV_HOTBACKUP
+/**************************************************************//**
Copies the first n fields of a physical record to a new physical record in
-a buffer. */
+a buffer.
+@return own: copied record */
UNIV_INTERN
rec_t*
rec_copy_prefix_to_buf(
/*===================*/
- /* out, own: copied record */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint n_fields, /* in: number of fields
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint n_fields, /*!< in: number of fields
to copy */
- byte** buf, /* in/out: memory buffer
+ byte** buf, /*!< in/out: memory buffer
for the copied prefix,
or NULL */
- ulint* buf_size); /* in/out: buffer size */
-/****************************************************************
-Folds a prefix of a physical record to a ulint. */
+ ulint* buf_size); /*!< in/out: buffer size */
+/************************************************************//**
+Folds a prefix of a physical record to a ulint.
+@return the folded value */
UNIV_INLINE
ulint
rec_fold(
/*=====*/
- /* out: the folded value */
- const rec_t* rec, /* in: the physical record */
- const ulint* offsets, /* in: array returned by
+ const rec_t* rec, /*!< in: the physical record */
+ const ulint* offsets, /*!< in: array returned by
rec_get_offsets() */
- ulint n_fields, /* in: number of complete
+ ulint n_fields, /*!< in: number of complete
fields to fold */
- ulint n_bytes, /* in: number of bytes to fold
+ ulint n_bytes, /*!< in: number of bytes to fold
in an incomplete last field */
- dulint tree_id) /* in: index tree id */
+ dulint tree_id) /*!< in: index tree id */
__attribute__((pure));
-/*************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************//**
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
UNIV_INTERN
void
rec_convert_dtuple_to_rec_comp(
/*===========================*/
- rec_t* rec, /* in: origin of record */
- ulint extra, /* in: number of bytes to
+ rec_t* rec, /*!< in: origin of record */
+ ulint extra, /*!< in: number of bytes to
reserve between the record
header and the data payload
(normally REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /* in: record descriptor */
- ulint status, /* in: status bits of the record */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields);/* in: number of data fields */
-/*************************************************************
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint status, /*!< in: status bits of the record */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields);/*!< in: number of data fields */
+/*********************************************************//**
Builds a physical record out of a data tuple and
-stores it into the given buffer. */
+stores it into the given buffer.
+@return pointer to the origin of physical record */
UNIV_INTERN
rec_t*
rec_convert_dtuple_to_rec(
/*======================*/
- /* out: pointer to the origin
- of physical record */
- byte* buf, /* in: start address of the
+ byte* buf, /*!< in: start address of the
physical record */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext); /* in: number of
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext); /*!< in: number of
externally stored columns */
-/**************************************************************
+/**********************************************************//**
Returns the extra size of an old-style physical record if we know its
-data size and number of fields. */
+data size and number of fields.
+@return extra size */
UNIV_INLINE
ulint
rec_get_converted_extra_size(
/*=========================*/
- /* out: extra size */
- ulint data_size, /* in: data size */
- ulint n_fields, /* in: number of fields */
- ulint n_ext) /* in: number of externally stored columns */
+ ulint data_size, /*!< in: data size */
+ ulint n_fields, /*!< in: number of fields */
+ ulint n_ext) /*!< in: number of externally stored columns */
__attribute__((const));
-/**************************************************************
-Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. */
+/**********************************************************//**
+Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
+@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_comp_prefix(
/*===============================*/
- /* out: total size */
- const dict_index_t* index, /* in: record descriptor;
+ const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields,/* in: number of data fields */
- ulint* extra); /* out: extra size */
-/**************************************************************
-Determines the size of a data tuple in ROW_FORMAT=COMPACT. */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra); /*!< out: extra size */
+/**********************************************************//**
+Determines the size of a data tuple in ROW_FORMAT=COMPACT.
+@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_comp(
/*========================*/
- /* out: total size */
- const dict_index_t* index, /* in: record descriptor;
+ const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
- ulint status, /* in: status bits of the record */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields,/* in: number of data fields */
- ulint* extra); /* out: extra size */
-/**************************************************************
+ ulint status, /*!< in: status bits of the record */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra); /*!< out: extra size */
+/**********************************************************//**
The following function returns the size of a data tuple when converted to
-a physical record. */
+a physical record.
+@return size */
UNIV_INLINE
ulint
rec_get_converted_size(
/*===================*/
- /* out: size */
- dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext); /* in: number of externally stored columns */
-/******************************************************************
+ dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext); /*!< in: number of externally stored columns */
+#ifndef UNIV_HOTBACKUP
+/**************************************************************//**
Copies the first n fields of a physical record to a data tuple.
The fields are copied to the memory heap. */
UNIV_INTERN
void
rec_copy_prefix_to_dtuple(
/*======================*/
- dtuple_t* tuple, /* out: data tuple */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint n_fields, /* in: number of fields
+ dtuple_t* tuple, /*!< out: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint n_fields, /*!< in: number of fields
to copy */
- mem_heap_t* heap); /* in: memory heap */
-/*******************************************************************
-Validates the consistency of a physical record. */
+ mem_heap_t* heap); /*!< in: memory heap */
+#endif /* !UNIV_HOTBACKUP */
+/***************************************************************//**
+Validates the consistency of a physical record.
+@return TRUE if ok */
UNIV_INTERN
ibool
rec_validate(
/*=========*/
- /* out: TRUE if ok */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Prints an old-style physical record. */
UNIV_INTERN
void
rec_print_old(
/*==========*/
- FILE* file, /* in: file where to print */
- const rec_t* rec); /* in: physical record */
-/*******************************************************************
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec); /*!< in: physical record */
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Prints a physical record in ROW_FORMAT=COMPACT. Ignores the
record header. */
UNIV_INTERN
void
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() */
-/*******************************************************************
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Prints a physical record. */
UNIV_INTERN
void
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() */
-/*******************************************************************
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Prints a physical record. */
UNIV_INTERN
void
rec_print(
/*======*/
- FILE* file, /* in: file where to print */
- const rec_t* rec, /* in: physical record */
- dict_index_t* index); /* in: record descriptor */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ dict_index_t* index); /*!< in: record descriptor */
+#endif /* UNIV_HOTBACKUP */
#define REC_INFO_BITS 6 /* This is single byte bit-field */
diff --git a/storage/xtradb/include/rem0rec.ic b/storage/xtradb/include/rem0rec.ic
index 0b2b9f4a685..8e5bd9a7fcd 100644
--- a/storage/xtradb/include/rem0rec.ic
+++ b/storage/xtradb/include/rem0rec.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/rem0rec.ic
Record manager
Created 5/30/1994 Heikki Tuuri
@@ -64,7 +65,7 @@ most significant bytes and bits are written below less significant.
- offset_of_this_record) mod 64Ki,
where mod is the modulo as a non-negative
number;
- we can calculate the the offset of the next
+ we can calculate the offset of the next
record with the formula:
relative_offset + offset_of_this_record
mod UNIV_PAGE_SIZE
@@ -143,52 +144,52 @@ a field stored to another page: */
# error "sum of new-style masks != 0xFFFFFFUL"
#endif
-/***************************************************************
+/***********************************************************//**
Sets the value of the ith field SQL null bit of an old-style record. */
UNIV_INTERN
void
rec_set_nth_field_null_bit(
/*=======================*/
- rec_t* rec, /* in: record */
- ulint i, /* in: ith field */
- ibool val); /* in: value to set */
-/***************************************************************
+ rec_t* rec, /*!< in: record */
+ ulint i, /*!< in: ith field */
+ ibool val); /*!< in: value to set */
+/***********************************************************//**
Sets an old-style record field to SQL null.
The physical size of the field is not changed. */
UNIV_INTERN
void
rec_set_nth_field_sql_null(
/*=======================*/
- rec_t* rec, /* in: record */
- ulint n); /* in: index of the field */
+ rec_t* rec, /*!< in: record */
+ ulint n); /*!< in: index of the field */
-/**********************************************************
+/******************************************************//**
Gets a bit field from within 1 byte. */
UNIV_INLINE
ulint
rec_get_bit_field_1(
/*================*/
- const rec_t* rec, /* in: pointer to record origin */
- ulint offs, /* in: offset from the origin down */
- ulint mask, /* in: mask used to filter bits */
- ulint shift) /* in: shift right applied after masking */
+ const rec_t* rec, /*!< in: pointer to record origin */
+ ulint offs, /*!< in: offset from the origin down */
+ ulint mask, /*!< in: mask used to filter bits */
+ ulint shift) /*!< in: shift right applied after masking */
{
ut_ad(rec);
return((mach_read_from_1(rec - offs) & mask) >> shift);
}
-/**********************************************************
+/******************************************************//**
Sets a bit field within 1 byte. */
UNIV_INLINE
void
rec_set_bit_field_1(
/*================*/
- rec_t* rec, /* in: pointer to record origin */
- ulint val, /* in: value to set */
- ulint offs, /* in: offset from the origin down */
- ulint mask, /* in: mask used to filter bits */
- ulint shift) /* in: shift right applied after masking */
+ rec_t* rec, /*!< in: pointer to record origin */
+ ulint val, /*!< in: value to set */
+ ulint offs, /*!< in: offset from the origin down */
+ ulint mask, /*!< in: mask used to filter bits */
+ ulint shift) /*!< in: shift right applied after masking */
{
ut_ad(rec);
ut_ad(offs <= REC_N_OLD_EXTRA_BYTES);
@@ -202,33 +203,33 @@ rec_set_bit_field_1(
| (val << shift));
}
-/**********************************************************
+/******************************************************//**
Gets a bit field from within 2 bytes. */
UNIV_INLINE
ulint
rec_get_bit_field_2(
/*================*/
- const rec_t* rec, /* in: pointer to record origin */
- ulint offs, /* in: offset from the origin down */
- ulint mask, /* in: mask used to filter bits */
- ulint shift) /* in: shift right applied after masking */
+ const rec_t* rec, /*!< in: pointer to record origin */
+ ulint offs, /*!< in: offset from the origin down */
+ ulint mask, /*!< in: mask used to filter bits */
+ ulint shift) /*!< in: shift right applied after masking */
{
ut_ad(rec);
return((mach_read_from_2(rec - offs) & mask) >> shift);
}
-/**********************************************************
+/******************************************************//**
Sets a bit field within 2 bytes. */
UNIV_INLINE
void
rec_set_bit_field_2(
/*================*/
- rec_t* rec, /* in: pointer to record origin */
- ulint val, /* in: value to set */
- ulint offs, /* in: offset from the origin down */
- ulint mask, /* in: mask used to filter bits */
- ulint shift) /* in: shift right applied after masking */
+ rec_t* rec, /*!< in: pointer to record origin */
+ ulint val, /*!< in: value to set */
+ ulint offs, /*!< in: offset from the origin down */
+ ulint mask, /*!< in: mask used to filter bits */
+ ulint shift) /*!< in: shift right applied after masking */
{
ut_ad(rec);
ut_ad(offs <= REC_N_OLD_EXTRA_BYTES);
@@ -244,17 +245,16 @@ rec_set_bit_field_2(
| (val << shift));
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the pointer of the next chained record
-on the same page. */
+on the same page.
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
const rec_t*
rec_get_next_ptr_const(
/*===================*/
- /* out: pointer to the next chained record, or
- NULL if none */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
ulint field_value;
@@ -301,32 +301,30 @@ rec_get_next_ptr_const(
}
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the pointer of the next chained record
-on the same page. */
+on the same page.
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
rec_t*
rec_get_next_ptr(
/*=============*/
- /* out: pointer to the next chained record, or
- NULL if none */
- rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
return((rec_t*) rec_get_next_ptr_const(rec, comp));
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the offset of the next chained record
-on the same page. */
+on the same page.
+@return the page offset of the next chained record, or 0 if none */
UNIV_INLINE
ulint
rec_get_next_offs(
/*==============*/
- /* out: the page offset of the next
- chained record, or 0 if none */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
ulint field_value;
#if REC_NEXT_MASK != 0xFFFFUL
@@ -374,15 +372,15 @@ rec_get_next_offs(
}
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the next record offset field
of an old-style record. */
UNIV_INLINE
void
rec_set_next_offs_old(
/*==================*/
- rec_t* rec, /* in: old-style physical record */
- ulint next) /* in: offset of the next record */
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint next) /*!< in: offset of the next record */
{
ut_ad(rec);
ut_ad(UNIV_PAGE_SIZE > next);
@@ -396,15 +394,15 @@ rec_set_next_offs_old(
mach_write_to_2(rec - REC_NEXT, next);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the next record offset field
of a new-style record. */
UNIV_INLINE
void
rec_set_next_offs_new(
/*==================*/
- rec_t* rec, /* in/out: new-style physical record */
- ulint next) /* in: offset of the next record */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ ulint next) /*!< in: offset of the next record */
{
ulint field_value;
@@ -427,15 +425,15 @@ rec_set_next_offs_new(
mach_write_to_2(rec - REC_NEXT, field_value);
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the number of fields
-in an old-style record. */
+in an old-style record.
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields_old(
/*=================*/
- /* out: number of data fields */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
ulint ret;
@@ -450,15 +448,15 @@ rec_get_n_fields_old(
return(ret);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the number of fields
in an old-style record. */
UNIV_INLINE
void
rec_set_n_fields_old(
/*=================*/
- rec_t* rec, /* in: physical record */
- ulint n_fields) /* in: the number of fields */
+ rec_t* rec, /*!< in: physical record */
+ ulint n_fields) /*!< in: the number of fields */
{
ut_ad(rec);
ut_ad(n_fields <= REC_MAX_N_FIELDS);
@@ -468,14 +466,14 @@ rec_set_n_fields_old(
REC_OLD_N_FIELDS_MASK, REC_OLD_N_FIELDS_SHIFT);
}
-/**********************************************************
-The following function retrieves the status bits of a new-style record. */
+/******************************************************//**
+The following function retrieves the status bits of a new-style record.
+@return status bits */
UNIV_INLINE
ulint
rec_get_status(
/*===========*/
- /* out: status bits */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
ulint ret;
@@ -488,16 +486,16 @@ rec_get_status(
return(ret);
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the number of fields
-in a record. */
+in a record.
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields(
/*=============*/
- /* out: number of data fields */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index) /* in: record descriptor */
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index) /*!< in: record descriptor */
{
ut_ad(rec);
ut_ad(index);
@@ -520,57 +518,56 @@ rec_get_n_fields(
}
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the number of records owned by the
-previous directory record. */
+previous directory record.
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_old(
/*================*/
- /* out: number of owned records */
- const rec_t* rec) /* in: old-style physical record */
+ const rec_t* rec) /*!< in: old-style physical record */
{
return(rec_get_bit_field_1(rec, REC_OLD_N_OWNED,
REC_N_OWNED_MASK, REC_N_OWNED_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_old(
/*================*/
- /* out: TRUE on success */
- rec_t* rec, /* in: old-style physical record */
- ulint n_owned) /* in: the number of owned */
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint n_owned) /*!< in: the number of owned */
{
rec_set_bit_field_1(rec, n_owned, REC_OLD_N_OWNED,
REC_N_OWNED_MASK, REC_N_OWNED_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the number of records owned by the
-previous directory record. */
+previous directory record.
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_new(
/*================*/
- /* out: number of owned records */
- const rec_t* rec) /* in: new-style physical record */
+ const rec_t* rec) /*!< in: new-style physical record */
{
return(rec_get_bit_field_1(rec, REC_NEW_N_OWNED,
REC_N_OWNED_MASK, REC_N_OWNED_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_new(
/*================*/
- rec_t* rec, /* in/out: new-style physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint n_owned)/* in: the number of owned */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint n_owned)/*!< in: the number of owned */
{
rec_set_bit_field_1(rec, n_owned, REC_NEW_N_OWNED,
REC_N_OWNED_MASK, REC_N_OWNED_SHIFT);
@@ -581,69 +578,69 @@ rec_set_n_owned_new(
}
}
-/**********************************************************
-The following function is used to retrieve the info bits of a record. */
+/******************************************************//**
+The following function is used to retrieve the info bits of a record.
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_bits(
/*==============*/
- /* out: info bits */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
return(rec_get_bit_field_1(
rec, comp ? REC_NEW_INFO_BITS : REC_OLD_INFO_BITS,
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_old(
/*==================*/
- rec_t* rec, /* in: old-style physical record */
- ulint bits) /* in: info bits */
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint bits) /*!< in: info bits */
{
rec_set_bit_field_1(rec, bits, REC_OLD_INFO_BITS,
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_new(
/*==================*/
- rec_t* rec, /* in/out: new-style physical record */
- ulint bits) /* in: info bits */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ ulint bits) /*!< in: info bits */
{
rec_set_bit_field_1(rec, bits, REC_NEW_INFO_BITS,
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the status bits of a new-style record. */
UNIV_INLINE
void
rec_set_status(
/*===========*/
- rec_t* rec, /* in/out: physical record */
- ulint bits) /* in: info bits */
+ rec_t* rec, /*!< in/out: physical record */
+ ulint bits) /*!< in: info bits */
{
rec_set_bit_field_1(rec, bits, REC_NEW_STATUS,
REC_NEW_STATUS_MASK, REC_NEW_STATUS_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to retrieve the info and status
-bits of a record. (Only compact records have status bits.) */
+bits of a record. (Only compact records have status bits.)
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_and_status_bits(
/*=========================*/
- /* out: info bits */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
ulint bits;
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
@@ -658,15 +655,15 @@ rec_get_info_and_status_bits(
}
return(bits);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
UNIV_INLINE
void
rec_set_info_and_status_bits(
/*=========================*/
- rec_t* rec, /* in/out: physical record */
- ulint bits) /* in: info bits */
+ rec_t* rec, /*!< in/out: physical record */
+ ulint bits) /*!< in: info bits */
{
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
& (REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)
@@ -676,15 +673,15 @@ rec_set_info_and_status_bits(
rec_set_info_bits_new(rec, bits & ~REC_NEW_STATUS_MASK);
}
-/**********************************************************
-The following function tells if record is delete marked. */
+/******************************************************//**
+The following function tells if record is delete marked.
+@return nonzero if delete marked */
UNIV_INLINE
ulint
rec_get_deleted_flag(
/*=================*/
- /* out: nonzero if delete marked */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
return(UNIV_UNLIKELY(
@@ -699,14 +696,14 @@ rec_get_deleted_flag(
}
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_old(
/*=====================*/
- rec_t* rec, /* in: old-style physical record */
- ulint flag) /* in: nonzero if delete marked */
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint flag) /*!< in: nonzero if delete marked */
{
ulint val;
@@ -721,15 +718,15 @@ rec_set_deleted_flag_old(
rec_set_info_bits_old(rec, val);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_new(
/*=====================*/
- rec_t* rec, /* in/out: new-style physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint flag) /* in: nonzero if delete marked */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint flag) /*!< in: nonzero if delete marked */
{
ulint val;
@@ -748,83 +745,83 @@ rec_set_deleted_flag_new(
}
}
-/**********************************************************
-The following function tells if a new-style record is a node pointer. */
+/******************************************************//**
+The following function tells if a new-style record is a node pointer.
+@return TRUE if node pointer */
UNIV_INLINE
ibool
rec_get_node_ptr_flag(
/*==================*/
- /* out: TRUE if node pointer */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
return(REC_STATUS_NODE_PTR == rec_get_status(rec));
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the order number
-of an old-style record in the heap of the index page. */
+of an old-style record in the heap of the index page.
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_old(
/*================*/
- /* out: heap order number */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
return(rec_get_bit_field_2(rec, REC_OLD_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the heap number
field in an old-style record. */
UNIV_INLINE
void
rec_set_heap_no_old(
/*================*/
- rec_t* rec, /* in: physical record */
- ulint heap_no)/* in: the heap number */
+ rec_t* rec, /*!< in: physical record */
+ ulint heap_no)/*!< in: the heap number */
{
rec_set_bit_field_2(rec, heap_no, REC_OLD_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the order number
-of a new-style record in the heap of the index page. */
+of a new-style record in the heap of the index page.
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_new(
/*================*/
- /* out: heap order number */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
return(rec_get_bit_field_2(rec, REC_NEW_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the heap number
field in a new-style record. */
UNIV_INLINE
void
rec_set_heap_no_new(
/*================*/
- rec_t* rec, /* in/out: physical record */
- ulint heap_no)/* in: the heap number */
+ rec_t* rec, /*!< in/out: physical record */
+ ulint heap_no)/*!< in: the heap number */
{
rec_set_bit_field_2(rec, heap_no, REC_NEW_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to test whether the data offsets in the record
-are stored in one-byte or two-byte format. */
+are stored in one-byte or two-byte format.
+@return TRUE if 1-byte form */
UNIV_INLINE
ibool
rec_get_1byte_offs_flag(
/*====================*/
- /* out: TRUE if 1-byte form */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
#if TRUE != 1
#error "TRUE != 1"
@@ -834,14 +831,14 @@ rec_get_1byte_offs_flag(
REC_OLD_SHORT_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the 1-byte offsets flag. */
UNIV_INLINE
void
rec_set_1byte_offs_flag(
/*====================*/
- rec_t* rec, /* in: physical record */
- ibool flag) /* in: TRUE if 1byte form */
+ rec_t* rec, /*!< in: physical record */
+ ibool flag) /*!< in: TRUE if 1byte form */
{
#if TRUE != 1
#error "TRUE != 1"
@@ -852,18 +849,17 @@ rec_set_1byte_offs_flag(
REC_OLD_SHORT_SHIFT);
}
-/**********************************************************
+/******************************************************//**
Returns the offset of nth field end if the record is stored in the 1-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
-value. */
+value.
+@return offset of the start of the field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_1_get_field_end_info(
/*=====================*/
- /* out: offset of the start of the
- field, SQL null flag ORed */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(rec_get_1byte_offs_flag(rec));
ut_ad(n < rec_get_n_fields_old(rec));
@@ -871,19 +867,18 @@ rec_1_get_field_end_info(
return(mach_read_from_1(rec - (REC_N_OLD_EXTRA_BYTES + n + 1)));
}
-/**********************************************************
+/******************************************************//**
Returns the offset of nth field end if the record is stored in the 2-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
-value. */
+value.
+@return offset of the start of the field, SQL null flag and extern
+storage flag ORed */
UNIV_INLINE
ulint
rec_2_get_field_end_info(
/*=====================*/
- /* out: offset of the start of the
- field, SQL null flag and extern
- storage flag ORed */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(!rec_get_1byte_offs_flag(rec));
ut_ad(n < rec_get_n_fields_old(rec));
@@ -896,15 +891,15 @@ this position, and following positions hold the end offsets of
the fields. */
#define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE)
-/**************************************************************
+/**********************************************************//**
The following function returns the number of allocated elements
-for an array of offsets. */
+for an array of offsets.
+@return number of elements */
UNIV_INLINE
ulint
rec_offs_get_n_alloc(
/*=================*/
- /* out: number of elements */
- const ulint* offsets)/* in: array for rec_get_offsets() */
+ const ulint* offsets)/*!< in: array for rec_get_offsets() */
{
ulint n_alloc;
ut_ad(offsets);
@@ -914,16 +909,16 @@ rec_offs_get_n_alloc(
return(n_alloc);
}
-/**************************************************************
+/**********************************************************//**
The following function sets the number of allocated elements
for an array of offsets. */
UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
- ulint* offsets, /* out: array for rec_get_offsets(),
+ ulint* offsets, /*!< out: array for rec_get_offsets(),
must be allocated */
- ulint n_alloc) /* in: number of elements */
+ ulint n_alloc) /*!< in: number of elements */
{
ut_ad(offsets);
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
@@ -931,14 +926,14 @@ rec_offs_set_n_alloc(
offsets[0] = n_alloc;
}
-/**************************************************************
-The following function returns the number of fields in a record. */
+/**********************************************************//**
+The following function returns the number of fields in a record.
+@return number of fields */
UNIV_INLINE
ulint
rec_offs_n_fields(
/*==============*/
- /* out: number of fields */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
ut_ad(offsets);
@@ -950,16 +945,16 @@ rec_offs_n_fields(
return(n_fields);
}
-/****************************************************************
-Validates offsets returned by rec_get_offsets(). */
+/************************************************************//**
+Validates offsets returned by rec_get_offsets().
+@return TRUE if valid */
UNIV_INLINE
ibool
rec_offs_validate(
/*==============*/
- /* out: TRUE if valid */
- 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_t* rec, /*!< in: record or NULL */
+ const dict_index_t* index, /*!< in: record descriptor or NULL */
+ const ulint* offsets)/*!< in: array returned by
rec_get_offsets() */
{
ulint i = rec_offs_n_fields(offsets);
@@ -1006,16 +1001,16 @@ rec_offs_validate(
return(TRUE);
}
#ifdef UNIV_DEBUG
-/****************************************************************
+/************************************************************//**
Updates debug data in offsets, in order to avoid bogus
rec_offs_validate() failures. */
UNIV_INLINE
void
rec_offs_make_valid(
/*================*/
- const rec_t* rec, /* in: record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets)/* in: array returned by
+ const rec_t* rec, /*!< in: record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in: array returned by
rec_get_offsets() */
{
ut_ad(rec);
@@ -1027,17 +1022,17 @@ rec_offs_make_valid(
}
#endif /* UNIV_DEBUG */
-/****************************************************************
+/************************************************************//**
The following function is used to get an offset to the nth
-data field in a record. */
+data field in a record.
+@return offset from the origin of rec */
UNIV_INLINE
ulint
rec_get_nth_field_offs(
/*===================*/
- /* out: offset from the origin of rec */
- const ulint* 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
+ const ulint* 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;
@@ -1064,43 +1059,43 @@ rec_get_nth_field_offs(
return(offs);
}
-/**********************************************************
+/******************************************************//**
Determine if the offsets are for a record in the new
-compact format. */
+compact format.
+@return nonzero if compact format */
UNIV_INLINE
ulint
rec_offs_comp(
/*==========*/
- /* out: nonzero if compact format */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);
}
-/**********************************************************
+/******************************************************//**
Determine if the offsets are for a record containing
-externally stored columns. */
+externally stored columns.
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_any_extern(
/*================*/
- /* out: nonzero if externally stored */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
return(UNIV_UNLIKELY(*rec_offs_base(offsets) & REC_OFFS_EXTERNAL));
}
-/**********************************************************
-Returns nonzero if the extern bit is set in nth field of rec. */
+/******************************************************//**
+Returns nonzero if the extern bit is set in nth field of rec.
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_nth_extern(
/*================*/
- /* out: nonzero if externally stored */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n) /* in: nth field */
+ const ulint* 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));
@@ -1108,15 +1103,15 @@ rec_offs_nth_extern(
& REC_OFFS_EXTERNAL));
}
-/**********************************************************
-Returns nonzero if the SQL NULL bit is set in nth field of rec. */
+/******************************************************//**
+Returns nonzero if the SQL NULL bit is set in nth field of rec.
+@return nonzero if SQL NULL */
UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
- /* out: nonzero if SQL NULL */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n) /* in: nth field */
+ const ulint* 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));
@@ -1124,15 +1119,15 @@ rec_offs_nth_sql_null(
& REC_OFFS_SQL_NULL));
}
-/**********************************************************
-Gets the physical size of a field. */
+/******************************************************//**
+Gets the physical size of a field.
+@return length of field */
UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
- /* out: length of field */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n) /* in: nth field */
+ const ulint* 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));
@@ -1143,14 +1138,14 @@ rec_offs_nth_size(
& REC_OFFS_MASK);
}
-/**********************************************************
-Returns the number of extern bits set in a record. */
+/******************************************************//**
+Returns the number of extern bits set in a record.
+@return number of externally stored fields */
UNIV_INLINE
ulint
rec_offs_n_extern(
/*==============*/
- /* out: number of externally stored fields */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n = 0;
@@ -1167,20 +1162,19 @@ rec_offs_n_extern(
return(n);
}
-/**********************************************************
+/******************************************************//**
Returns the offset of n - 1th field end if the record is stored in the 1-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
value. This function and the 2-byte counterpart are defined here because the
C-compiler was not able to sum negative and positive constant offsets, and
-warned of constant arithmetic overflow within the compiler. */
+warned of constant arithmetic overflow within the compiler.
+@return offset of the start of the PREVIOUS field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_1_get_prev_field_end_info(
/*==========================*/
- /* out: offset of the start of the
- PREVIOUS field, SQL null flag ORed */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(rec_get_1byte_offs_flag(rec));
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1188,18 +1182,17 @@ rec_1_get_prev_field_end_info(
return(mach_read_from_1(rec - (REC_N_OLD_EXTRA_BYTES + n)));
}
-/**********************************************************
+/******************************************************//**
Returns the offset of n - 1th field end if the record is stored in the 2-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
-value. */
+value.
+@return offset of the start of the PREVIOUS field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_2_get_prev_field_end_info(
/*==========================*/
- /* out: offset of the start of the
- PREVIOUS field, SQL null flag ORed */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(!rec_get_1byte_offs_flag(rec));
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1207,16 +1200,16 @@ rec_2_get_prev_field_end_info(
return(mach_read_from_2(rec - (REC_N_OLD_EXTRA_BYTES + 2 * n)));
}
-/**********************************************************
+/******************************************************//**
Sets the field end info for the nth field if the record is stored in the
1-byte format. */
UNIV_INLINE
void
rec_1_set_field_end_info(
/*=====================*/
- rec_t* rec, /* in: record */
- ulint n, /* in: field index */
- ulint info) /* in: value to set */
+ rec_t* rec, /*!< in: record */
+ ulint n, /*!< in: field index */
+ ulint info) /*!< in: value to set */
{
ut_ad(rec_get_1byte_offs_flag(rec));
ut_ad(n < rec_get_n_fields_old(rec));
@@ -1224,16 +1217,16 @@ rec_1_set_field_end_info(
mach_write_to_1(rec - (REC_N_OLD_EXTRA_BYTES + n + 1), info);
}
-/**********************************************************
+/******************************************************//**
Sets the field end info for the nth field if the record is stored in the
2-byte format. */
UNIV_INLINE
void
rec_2_set_field_end_info(
/*=====================*/
- rec_t* rec, /* in: record */
- ulint n, /* in: field index */
- ulint info) /* in: value to set */
+ rec_t* rec, /*!< in: record */
+ ulint n, /*!< in: field index */
+ ulint info) /*!< in: value to set */
{
ut_ad(!rec_get_1byte_offs_flag(rec));
ut_ad(n < rec_get_n_fields_old(rec));
@@ -1241,16 +1234,16 @@ rec_2_set_field_end_info(
mach_write_to_2(rec - (REC_N_OLD_EXTRA_BYTES + 2 * n + 2), info);
}
-/**********************************************************
+/******************************************************//**
Returns the offset of nth field start if the record is stored in the 1-byte
-offsets form. */
+offsets form.
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_1_get_field_start_offs(
/*=======================*/
- /* out: offset of the start of the field */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(rec_get_1byte_offs_flag(rec));
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1264,16 +1257,16 @@ rec_1_get_field_start_offs(
& ~REC_1BYTE_SQL_NULL_MASK);
}
-/**********************************************************
+/******************************************************//**
Returns the offset of nth field start if the record is stored in the 2-byte
-offsets form. */
+offsets form.
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_2_get_field_start_offs(
/*=======================*/
- /* out: offset of the start of the field */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(!rec_get_1byte_offs_flag(rec));
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1287,18 +1280,18 @@ rec_2_get_field_start_offs(
& ~(REC_2BYTE_SQL_NULL_MASK | REC_2BYTE_EXTERN_MASK));
}
-/**********************************************************
+/******************************************************//**
The following function is used to read the offset of the start of a data field
in the record. The start of an SQL null field is the end offset of the
previous non-null field, or 0, if none exists. If n is the number of the last
-field + 1, then the end offset of the last field is returned. */
+field + 1, then the end offset of the last field is returned.
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_get_field_start_offs(
/*=====================*/
- /* out: offset of the start of the field */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(rec);
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1316,17 +1309,17 @@ rec_get_field_start_offs(
return(rec_2_get_field_start_offs(rec, n));
}
-/****************************************************************
+/************************************************************//**
Gets the physical size of an old-style field.
Also an SQL null may have a field of size > 0,
-if the data type is of a fixed size. */
+if the data type is of a fixed size.
+@return field size in bytes */
UNIV_INLINE
ulint
rec_get_nth_field_size(
/*===================*/
- /* out: field size in bytes */
- const rec_t* rec, /* in: record */
- ulint n) /* in: index of the field */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: index of the field */
{
ulint os;
ulint next_os;
@@ -1339,7 +1332,7 @@ rec_get_nth_field_size(
return(next_os - os);
}
-/***************************************************************
+/***********************************************************//**
This is used to modify the value of an already existing field in a record.
The previous value must have exactly the same size as the new value. If len
is UNIV_SQL_NULL then the field is treated as an SQL null.
@@ -1349,12 +1342,12 @@ UNIV_INLINE
void
rec_set_nth_field(
/*==============*/
- rec_t* rec, /* in: record */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n, /* in: index number of the field */
- const void* data, /* in: pointer to the data
+ rec_t* rec, /*!< in: record */
+ const ulint* 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 */
+ ulint len) /*!< in: length of the data or UNIV_SQL_NULL */
{
byte* data2;
ulint len2;
@@ -1383,32 +1376,32 @@ rec_set_nth_field(
ut_memcpy(data2, data, len);
}
-/**************************************************************
+/**********************************************************//**
The following function returns the data size of an old-style physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
-is the distance from record origin to record end in bytes. */
+is the distance from record origin to record end in bytes.
+@return size */
UNIV_INLINE
ulint
rec_get_data_size_old(
/*==================*/
- /* out: size */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
ut_ad(rec);
return(rec_get_field_start_offs(rec, rec_get_n_fields_old(rec)));
}
-/**************************************************************
+/**********************************************************//**
The following function sets the number of fields in offsets. */
UNIV_INLINE
void
rec_offs_set_n_fields(
/*==================*/
- ulint* offsets, /* in/out: array returned by
+ ulint* 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);
@@ -1418,17 +1411,17 @@ rec_offs_set_n_fields(
offsets[1] = n_fields;
}
-/**************************************************************
+/**********************************************************//**
The following function returns the data size of a physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
-is the distance from record origin to record end in bytes. */
+is the distance from record origin to record end in bytes.
+@return size */
UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
- /* out: size */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint size;
@@ -1439,16 +1432,16 @@ rec_offs_data_size(
return(size);
}
-/**************************************************************
+/**********************************************************//**
Returns the total size of record minus data size of record. The value
returned by the function is the distance from record start to record origin
-in bytes. */
+in bytes.
+@return size */
UNIV_INLINE
ulint
rec_offs_extra_size(
/*================*/
- /* out: size */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint size;
ut_ad(rec_offs_validate(NULL, NULL, offsets));
@@ -1457,56 +1450,56 @@ rec_offs_extra_size(
return(size);
}
-/**************************************************************
-Returns the total size of a physical record. */
+/**********************************************************//**
+Returns the total size of a physical record.
+@return size */
UNIV_INLINE
ulint
rec_offs_size(
/*==========*/
- /* out: size */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
return(rec_offs_data_size(offsets) + rec_offs_extra_size(offsets));
}
-/**************************************************************
-Returns a pointer to the end of the record. */
+/**********************************************************//**
+Returns a pointer to the end of the record.
+@return pointer to end */
UNIV_INLINE
byte*
rec_get_end(
/*========*/
- /* out: pointer to end */
- rec_t* rec, /* in: pointer to record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: pointer to record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
return(rec + rec_offs_data_size(offsets));
}
-/**************************************************************
-Returns a pointer to the start of the record. */
+/**********************************************************//**
+Returns a pointer to the start of the record.
+@return pointer to start */
UNIV_INLINE
byte*
rec_get_start(
/*==========*/
- /* out: pointer to start */
- rec_t* rec, /* in: pointer to record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: pointer to record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
return(rec - rec_offs_extra_size(offsets));
}
-/*******************************************************************
-Copies a physical record to a buffer. */
+/***************************************************************//**
+Copies a physical record to a buffer.
+@return pointer to the origin of the copy */
UNIV_INLINE
rec_t*
rec_copy(
/*=====*/
- /* out: pointer to the origin of the copy */
- void* buf, /* in: buffer */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ void* buf, /*!< in: buffer */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint extra_len;
ulint data_len;
@@ -1523,17 +1516,17 @@ rec_copy(
return((byte*)buf + extra_len);
}
-/**************************************************************
+/**********************************************************//**
Returns the extra size of an old-style physical record if we know its
-data size and number of fields. */
+data size and number of fields.
+@return extra size */
UNIV_INLINE
ulint
rec_get_converted_extra_size(
/*=========================*/
- /* out: extra size */
- ulint data_size, /* in: data size */
- ulint n_fields, /* in: number of fields */
- ulint n_ext) /* in: number of externally stored columns */
+ ulint data_size, /*!< in: data size */
+ ulint n_fields, /*!< in: number of fields */
+ ulint n_ext) /*!< in: number of externally stored columns */
{
if (!n_ext && data_size <= REC_1BYTE_OFFS_LIMIT) {
@@ -1543,17 +1536,17 @@ rec_get_converted_extra_size(
return(REC_N_OLD_EXTRA_BYTES + 2 * n_fields);
}
-/**************************************************************
+/**********************************************************//**
The following function returns the size of a data tuple when converted to
-a physical record. */
+a physical record.
+@return size */
UNIV_INLINE
ulint
rec_get_converted_size(
/*===================*/
- /* out: size */
- dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext) /* in: number of externally stored columns */
+ dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext) /*!< in: number of externally stored columns */
{
ulint data_size;
ulint extra_size;
@@ -1577,7 +1570,7 @@ rec_get_converted_size(
dtuple->n_fields, NULL));
}
- data_size = dtuple_get_data_size(dtuple);
+ data_size = dtuple_get_data_size(dtuple, 0);
extra_size = rec_get_converted_extra_size(
data_size, dtuple_get_n_fields(dtuple), n_ext);
@@ -1585,22 +1578,23 @@ rec_get_converted_size(
return(data_size + extra_size);
}
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Folds a prefix of a physical record to a ulint. Folds only existing fields,
-that is, checks that we do not run out of the record. */
+that is, checks that we do not run out of the record.
+@return the folded value */
UNIV_INLINE
ulint
rec_fold(
/*=====*/
- /* out: the folded value */
- const rec_t* rec, /* in: the physical record */
- const ulint* offsets, /* in: array returned by
+ const rec_t* rec, /*!< in: the physical record */
+ const ulint* offsets, /*!< in: array returned by
rec_get_offsets() */
- ulint n_fields, /* in: number of complete
+ ulint n_fields, /*!< in: number of complete
fields to fold */
- ulint n_bytes, /* in: number of bytes to fold
+ ulint n_bytes, /*!< in: number of bytes to fold
in an incomplete last field */
- dulint tree_id) /* in: index tree id */
+ dulint tree_id) /*!< in: index tree id */
{
ulint i;
const byte* data;
@@ -1650,3 +1644,4 @@ rec_fold(
return(fold);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/rem0types.h b/storage/xtradb/include/rem0types.h
index d0b11b92495..8b84d4af233 100644
--- a/storage/xtradb/include/rem0types.h
+++ b/storage/xtradb/include/rem0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/rem0types.h
Record manager global types
Created 5/30/1994 Heikki Tuuri
diff --git a/storage/xtradb/include/row0ext.h b/storage/xtradb/include/row0ext.h
index 08ebafa4d98..43d82d644e6 100644
--- a/storage/xtradb/include/row0ext.h
+++ b/storage/xtradb/include/row0ext.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0ext.h
Caching of externally stored column prefixes
Created September 2006 Marko Makela
@@ -30,65 +31,61 @@ Created September 2006 Marko Makela
#include "data0types.h"
#include "mem0mem.h"
-/************************************************************************
-Creates a cache of column prefixes of externally stored columns. */
+/********************************************************************//**
+Creates a cache of column prefixes of externally stored columns.
+@return own: column prefix cache */
UNIV_INTERN
row_ext_t*
row_ext_create(
/*===========*/
- /* out,own: column prefix cache */
- ulint n_ext, /* in: number of externally stored columns */
- const ulint* ext, /* in: col_no's of externally stored columns
+ ulint n_ext, /*!< in: number of externally stored columns */
+ const ulint* ext, /*!< in: col_no's of externally stored columns
in the InnoDB table object, as reported by
dict_col_get_no(); NOT relative to the records
in the clustered index */
- const dtuple_t* tuple, /* in: data tuple containing the field
+ const dtuple_t* tuple, /*!< in: data tuple containing the field
references of the externally stored
columns; must be indexed by col_no;
the clustered index record must be
covered by a lock or a page latch
to prevent deletion (rollback or purge). */
- ulint zip_size,/* compressed page size in bytes, or 0 */
- mem_heap_t* heap); /* in: heap where created */
+ ulint zip_size,/*!< compressed page size in bytes, or 0 */
+ mem_heap_t* heap); /*!< in: heap where created */
-/************************************************************************
-Looks up a column prefix of an externally stored column. */
+/********************************************************************//**
+Looks up a column prefix of an externally stored column.
+@return column prefix, or NULL if the column is not stored externally,
+or pointer to field_ref_zero if the BLOB pointer is unset */
UNIV_INLINE
const byte*
row_ext_lookup_ith(
/*===============*/
- /* out: column prefix, or NULL if
- the column is not stored externally,
- or pointer to field_ref_zero
- if the BLOB pointer is unset */
- const row_ext_t* ext, /* in/out: column prefix cache */
- ulint i, /* in: index of ext->ext[] */
- ulint* len); /* out: length of prefix, in bytes,
+ const row_ext_t* ext, /*!< in/out: column prefix cache */
+ ulint i, /*!< in: index of ext->ext[] */
+ ulint* len); /*!< out: length of prefix, in bytes,
at most REC_MAX_INDEX_COL_LEN */
-/************************************************************************
-Looks up a column prefix of an externally stored column. */
+/********************************************************************//**
+Looks up a column prefix of an externally stored column.
+@return column prefix, or NULL if the column is not stored externally,
+or pointer to field_ref_zero if the BLOB pointer is unset */
UNIV_INLINE
const byte*
row_ext_lookup(
/*===========*/
- /* out: column prefix, or NULL if
- the column is not stored externally,
- or pointer to field_ref_zero
- if the BLOB pointer is unset */
- const row_ext_t* ext, /* in: column prefix cache */
- ulint col, /* in: column number in the InnoDB
+ const row_ext_t* ext, /*!< in: column prefix cache */
+ ulint col, /*!< in: column number in the InnoDB
table object, as reported by
dict_col_get_no(); NOT relative to the
records in the clustered index */
- ulint* len); /* out: length of prefix, in bytes,
+ ulint* len); /*!< out: length of prefix, in bytes,
at most REC_MAX_INDEX_COL_LEN */
-/* Prefixes of externally stored columns */
+/** Prefixes of externally stored columns */
struct row_ext_struct{
- ulint n_ext; /* number of externally stored columns */
- const ulint* ext; /* col_no's of externally stored columns */
- byte* buf; /* backing store of the column prefix cache */
- ulint len[1]; /* prefix lengths; 0 if not cached */
+ ulint n_ext; /*!< number of externally stored columns */
+ const ulint* ext; /*!< col_no's of externally stored columns */
+ byte* buf; /*!< backing store of the column prefix cache */
+ ulint len[1]; /*!< prefix lengths; 0 if not cached */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/row0ext.ic b/storage/xtradb/include/row0ext.ic
index e56fc175764..82771a9312a 100644
--- a/storage/xtradb/include/row0ext.ic
+++ b/storage/xtradb/include/row0ext.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0ext.ic
Caching of externally stored column prefixes
Created September 2006 Marko Makela
@@ -25,19 +26,17 @@ Created September 2006 Marko Makela
#include "rem0types.h"
#include "btr0types.h"
-/************************************************************************
-Looks up a column prefix of an externally stored column. */
+/********************************************************************//**
+Looks up a column prefix of an externally stored column.
+@return column prefix, or NULL if the column is not stored externally,
+or pointer to field_ref_zero if the BLOB pointer is unset */
UNIV_INLINE
const byte*
row_ext_lookup_ith(
/*===============*/
- /* out: column prefix, or NULL if
- the column is not stored externally,
- or pointer to field_ref_zero
- if the BLOB pointer is unset */
- const row_ext_t* ext, /* in/out: column prefix cache */
- ulint i, /* in: index of ext->ext[] */
- ulint* len) /* out: length of prefix, in bytes,
+ const row_ext_t* ext, /*!< in/out: column prefix cache */
+ ulint i, /*!< in: index of ext->ext[] */
+ ulint* len) /*!< out: length of prefix, in bytes,
at most REC_MAX_INDEX_COL_LEN */
{
ut_ad(ext);
@@ -54,22 +53,20 @@ row_ext_lookup_ith(
}
}
-/************************************************************************
-Looks up a column prefix of an externally stored column. */
+/********************************************************************//**
+Looks up a column prefix of an externally stored column.
+@return column prefix, or NULL if the column is not stored externally,
+or pointer to field_ref_zero if the BLOB pointer is unset */
UNIV_INLINE
const byte*
row_ext_lookup(
/*===========*/
- /* out: column prefix, or NULL if
- the column is not stored externally,
- or pointer to field_ref_zero
- if the BLOB pointer is unset */
- const row_ext_t* ext, /* in: column prefix cache */
- ulint col, /* in: column number in the InnoDB
+ const row_ext_t* ext, /*!< in: column prefix cache */
+ ulint col, /*!< in: column number in the InnoDB
table object, as reported by
dict_col_get_no(); NOT relative to the
records in the clustered index */
- ulint* len) /* out: length of prefix, in bytes,
+ ulint* len) /*!< out: length of prefix, in bytes,
at most REC_MAX_INDEX_COL_LEN */
{
ulint i;
diff --git a/storage/xtradb/include/row0ins.h b/storage/xtradb/include/row0ins.h
index 6aa83bed0f6..9f93565ddb7 100644
--- a/storage/xtradb/include/row0ins.h
+++ b/storage/xtradb/include/row0ins.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0ins.h
Insert into a table
Created 4/20/1996 Heikki Tuuri
@@ -32,38 +33,37 @@ Created 4/20/1996 Heikki Tuuri
#include "trx0types.h"
#include "row0types.h"
-/*******************************************************************
+/***************************************************************//**
Checks if foreign key constraint fails for an index entry. Sets shared locks
which lock either the success or the failure of the constraint. NOTE that
-the caller must have a shared latch on dict_foreign_key_check_lock. */
+the caller must have a shared latch on dict_foreign_key_check_lock.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_NO_REFERENCED_ROW, or
+DB_ROW_IS_REFERENCED */
UNIV_INTERN
ulint
row_ins_check_foreign_constraint(
/*=============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_NO_REFERENCED_ROW,
- or DB_ROW_IS_REFERENCED */
- ibool check_ref,/* in: TRUE If we want to check that
+ ibool check_ref,/*!< in: TRUE If we want to check that
the referenced table is ok, FALSE if we
- want to to check the foreign key table */
- dict_foreign_t* foreign,/* in: foreign constraint; NOTE that the
+ want to check the foreign key table */
+ dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
- dict_table_t* table, /* in: if check_ref is TRUE, then the foreign
+ dict_table_t* table, /*!< in: if check_ref is TRUE, then the foreign
table, else the referenced table */
- dtuple_t* entry, /* in: index entry for index */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
-Creates an insert node struct. */
+ dtuple_t* entry, /*!< in: index entry for index */
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
+Creates an insert node struct.
+@return own: insert node struct */
UNIV_INTERN
ins_node_t*
ins_node_create(
/*============*/
- /* out, own: insert node struct */
- ulint ins_type, /* in: INS_VALUES, ... */
- dict_table_t* table, /* in: table where to insert */
- mem_heap_t* heap); /* in: mem heap where created */
-/*************************************************************************
+ ulint ins_type, /*!< in: INS_VALUES, ... */
+ dict_table_t* table, /*!< in: table where to insert */
+ mem_heap_t* heap); /*!< in: mem heap where created */
+/*********************************************************************//**
Sets a new row to insert for an INS_DIRECT node. This function is only used
if we have constructed the row separately, which is a rare case; this
function is quite slow. */
@@ -71,61 +71,60 @@ UNIV_INTERN
void
ins_node_set_new_row(
/*=================*/
- ins_node_t* node, /* in: insert node */
- dtuple_t* row); /* in: new row (or first row) for the node */
-/*******************************************************************
+ ins_node_t* node, /*!< in: insert node */
+ dtuple_t* row); /*!< in: new row (or first row) for the node */
+/***************************************************************//**
Inserts an index entry to index. Tries first optimistic, then pessimistic
descent down the tree. If the entry matches enough to a delete marked record,
performs the insert by updating or delete unmarking the delete marked
-record. */
+record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
UNIV_INTERN
ulint
row_ins_index_entry(
/*================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DUPLICATE_KEY, or some other error code */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry to insert */
- ulint n_ext, /* in: number of externally stored columns */
- ibool foreign,/* in: TRUE=check foreign key constraints */
- que_thr_t* thr); /* in: query thread */
-/***************************************************************
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ ibool foreign,/*!< in: TRUE=check foreign key constraints */
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************//**
Inserts a row to a table. This is a high-level function used in
-SQL execution graphs. */
+SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_ins_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/***************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************//**
Creates an entry template for each index of a table. */
UNIV_INTERN
void
ins_node_create_entry_list(
/*=======================*/
- ins_node_t* node); /* in: row insert node */
+ ins_node_t* node); /*!< in: row insert node */
/* Insert node structure */
struct ins_node_struct{
- que_common_t common; /* node type: QUE_NODE_INSERT */
+ 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 */
- sel_node_t* select; /* select in searched insert */
+ dtuple_t* row; /*!< row to insert */
+ dict_table_t* table; /*!< table where to insert */
+ sel_node_t* select; /*!< select in searched insert */
que_node_t* values_list;/* list of expressions to evaluate and
insert in an INS_VALUES insert */
- ulint state; /* node execution state */
- dict_index_t* index; /* NULL, or the next index where the index
+ 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;
+ dtuple_t* 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 */
byte* row_id_buf;/* buffer for the row id sys field in row */
- dulint trx_id; /* trx id or the last trx which executed the
+ trx_id_t trx_id; /*!< trx id or the last trx which executed the
node */
byte* trx_id_buf;/* buffer for the trx id sys field in row */
mem_heap_t* entry_sys_heap;
diff --git a/storage/xtradb/include/row0ins.ic b/storage/xtradb/include/row0ins.ic
index b7aeaf97834..84f6da255bf 100644
--- a/storage/xtradb/include/row0ins.ic
+++ b/storage/xtradb/include/row0ins.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0ins.ic
Insert into a table
Created 4/20/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/row0merge.h b/storage/xtradb/include/row0merge.h
index 9975497cbeb..62a5efd11f7 100644
--- a/storage/xtradb/include/row0merge.h
+++ b/storage/xtradb/include/row0merge.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0merge.h
Index build routines using a merge sort
Created 13/06/2005 Jan Lindstrom
@@ -38,38 +39,40 @@ Created 13/06/2005 Jan Lindstrom
#include "row0mysql.h"
#include "lock0types.h"
-/* This structure holds index field definitions */
-
+/** Index field definition */
struct merge_index_field_struct {
- ulint prefix_len; /* Prefix len */
- const char* field_name; /* Field name */
+ ulint prefix_len; /*!< column prefix length, or 0
+ if indexing the whole column */
+ const char* field_name; /*!< field name */
};
+/** Index field definition */
typedef struct merge_index_field_struct merge_index_field_t;
-/* This structure holds index definitions */
-
+/** Definition of an index being created */
struct merge_index_def_struct {
- const char* name; /* Index name */
- ulint ind_type; /* 0, DICT_UNIQUE,
+ const char* name; /*!< index name */
+ ulint ind_type; /*!< 0, DICT_UNIQUE,
or DICT_CLUSTERED */
- ulint n_fields; /* Number of fields in index */
- merge_index_field_t* fields; /* Field definitions */
+ ulint n_fields; /*!< number of fields
+ in index */
+ merge_index_field_t* fields; /*!< field definitions */
};
+/** Definition of an index being created */
typedef struct merge_index_def_struct merge_index_def_t;
-/*************************************************************************
-Sets an exclusive lock on a table, for the duration of creating indexes. */
+/*********************************************************************//**
+Sets an exclusive lock on a table, for the duration of creating indexes.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_merge_lock_table(
/*=================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in/out: transaction */
- dict_table_t* table, /* in: table to lock */
- enum lock_mode mode); /* in: LOCK_X or LOCK_S */
-/*************************************************************************
+ trx_t* trx, /*!< in/out: transaction */
+ dict_table_t* table, /*!< in: table to lock */
+ enum lock_mode mode); /*!< in: LOCK_X or LOCK_S */
+/*********************************************************************//**
Drop an index from the InnoDB system tables. The data dictionary must
have been locked exclusively by the caller, because the transaction
will not be committed. */
@@ -77,10 +80,10 @@ UNIV_INTERN
void
row_merge_drop_index(
/*=================*/
- dict_index_t* index, /* in: index to be removed */
- dict_table_t* table, /* in: table */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
+ dict_index_t* index, /*!< in: index to be removed */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
Drop those indexes which were created before an error occurred when
building an index. The data dictionary must have been locked
exclusively by the caller, because the transaction will not be
@@ -89,110 +92,106 @@ UNIV_INTERN
void
row_merge_drop_indexes(
/*===================*/
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table containing the indexes */
- dict_index_t** index, /* in: indexes to drop */
- ulint num_created); /* in: number of elements in index[] */
-/*************************************************************************
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table containing the indexes */
+ dict_index_t** index, /*!< in: indexes to drop */
+ ulint num_created); /*!< in: number of elements in index[] */
+/*********************************************************************//**
Drop all partially created indexes during crash recovery. */
UNIV_INTERN
void
row_merge_drop_temp_indexes(void);
/*=============================*/
-/*************************************************************************
+/*********************************************************************//**
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. */
+will not be committed.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_merge_rename_tables(
/*====================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* old_table, /* in/out: old table, renamed to
+ dict_table_t* old_table, /*!< in/out: old table, renamed to
tmp_name */
- dict_table_t* new_table, /* in/out: new table, renamed to
+ dict_table_t* new_table, /*!< in/out: new table, renamed to
old_table->name */
- const char* tmp_name, /* in: new name for old_table */
- trx_t* trx); /* in: transaction handle */
+ const char* tmp_name, /*!< in: new name for old_table */
+ trx_t* trx); /*!< in: transaction handle */
-/*************************************************************************
+/*********************************************************************//**
Create a temporary table for creating a primary key, using the definition
-of an existing table. */
+of an existing table.
+@return table, or NULL on error */
UNIV_INTERN
dict_table_t*
row_merge_create_temporary_table(
/*=============================*/
- /* out: table,
- or NULL on error */
- const char* table_name, /* in: new table name */
- const merge_index_def_t*index_def, /* in: the index definition
+ const char* table_name, /*!< in: new table name */
+ const merge_index_def_t*index_def, /*!< in: the index definition
of the primary key */
- const dict_table_t* table, /* in: old table definition */
- trx_t* trx); /* in/out: transaction
+ const dict_table_t* table, /*!< in: old table definition */
+ trx_t* trx); /*!< in/out: transaction
(sets error_state) */
-/*************************************************************************
+/*********************************************************************//**
Rename the temporary indexes in the dictionary to permanent ones. The
data dictionary must have been locked exclusively by the caller,
-because the transaction will not be committed. */
+because the transaction will not be committed.
+@return DB_SUCCESS if all OK */
UNIV_INTERN
ulint
row_merge_rename_indexes(
/*=====================*/
- /* out: DB_SUCCESS if all OK */
- trx_t* trx, /* in/out: transaction */
- dict_table_t* table); /* in/out: table with new indexes */
-/*************************************************************************
-Create the index and load in to the dictionary. */
+ trx_t* trx, /*!< in/out: transaction */
+ dict_table_t* table); /*!< in/out: table with new indexes */
+/*********************************************************************//**
+Create the index and load in to the dictionary.
+@return index, or NULL on error */
UNIV_INTERN
dict_index_t*
row_merge_create_index(
/*===================*/
- /* out: index, or NULL on error */
- trx_t* trx, /* in/out: trx (sets error_state) */
- dict_table_t* table, /* in: the index is on this table */
- const merge_index_def_t* /* in: the index definition */
- index_def);
-#ifdef ROW_MERGE_IS_INDEX_USABLE
-/*************************************************************************
-Check if a transaction can use an index. */
+ trx_t* trx, /*!< in/out: trx (sets error_state) */
+ dict_table_t* table, /*!< in: the index is on this table */
+ const merge_index_def_t*index_def);
+ /*!< in: the index definition */
+/*********************************************************************//**
+Check if a transaction can use an index.
+@return TRUE if index can be used by the transaction else FALSE */
UNIV_INTERN
ibool
row_merge_is_index_usable(
/*======================*/
- /* out: TRUE if index can be used by
- the transaction else FALSE*/
- const trx_t* trx, /* in: transaction */
- const dict_index_t* index); /* in: index to check */
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
-/*************************************************************************
+ const trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index); /*!< in: index to check */
+/*********************************************************************//**
If there are views that refer to the old table name then we "attach" to
-the new instance of the table else we drop it immediately. */
+the new instance of the table else we drop it immediately.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_merge_drop_table(
/*=================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: transaction */
- dict_table_t* table); /* in: table instance to drop */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table); /*!< in: table instance to drop */
-/*************************************************************************
+/*********************************************************************//**
Build indexes on a table by reading a clustered index,
creating a temporary file containing index entries, merge sorting
-these index entries and inserting sorted index entries to indexes. */
+these index entries and inserting sorted index entries to indexes.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_merge_build_indexes(
/*====================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: transaction */
- dict_table_t* old_table, /* in: table where rows are
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* old_table, /*!< in: table where rows are
read from */
- dict_table_t* new_table, /* in: table where indexes are
+ dict_table_t* new_table, /*!< in: table where indexes are
created; identical to old_table
unless creating a PRIMARY KEY */
- dict_index_t** indexes, /* in: indexes to be created */
- ulint n_indexes, /* in: size of indexes[] */
- TABLE* table); /* in/out: MySQL table, for
+ dict_index_t** indexes, /*!< in: indexes to be created */
+ ulint n_indexes, /*!< in: size of indexes[] */
+ TABLE* table); /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
#endif /* row0merge.h */
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index 3c64a568f3f..261ab239cd8 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0mysql.h
Interface between Innobase row operations and MySQL.
Contains also create table and other data dictionary operations.
@@ -39,238 +40,239 @@ extern ibool row_rollback_on_timeout;
typedef struct row_prebuilt_struct row_prebuilt_t;
-/***********************************************************************
+/*******************************************************************//**
Frees the blob heap in prebuilt when no longer needed. */
UNIV_INTERN
void
row_mysql_prebuilt_free_blob_heap(
/*==============================*/
- row_prebuilt_t* prebuilt); /* in: prebuilt struct of a
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct of a
ha_innobase:: table handle */
-/***********************************************************************
+/*******************************************************************//**
Stores a >= 5.0.3 format true VARCHAR length to dest, in the MySQL row
-format. */
+format.
+@return pointer to the data, we skip the 1 or 2 bytes at the start
+that are used to store the len */
UNIV_INTERN
byte*
row_mysql_store_true_var_len(
/*=========================*/
- /* out: pointer to the data, we skip the 1 or 2 bytes
- at the start that are used to store the len */
- byte* dest, /* in: where to store */
- ulint len, /* in: length, must fit in two bytes */
- ulint lenlen);/* in: storage length of len: either 1 or 2 bytes */
-/***********************************************************************
+ byte* dest, /*!< in: where to store */
+ ulint len, /*!< in: length, must fit in two bytes */
+ ulint lenlen);/*!< in: storage length of len: either 1 or 2 bytes */
+/*******************************************************************//**
Reads a >= 5.0.3 format true VARCHAR length, in the MySQL row format, and
-returns a pointer to the data. */
-
+returns a pointer to the data.
+@return pointer to the data, we skip the 1 or 2 bytes at the start
+that are used to store the len */
+UNIV_INTERN
const byte*
row_mysql_read_true_varchar(
/*========================*/
- /* out: pointer to the data, we skip
- the 1 or 2 bytes at the start that are
- used to store the len */
- ulint* len, /* out: variable-length field length */
- const byte* field, /* in: field in the MySQL format */
- ulint lenlen);/* in: storage length of len: either 1
+ ulint* len, /*!< out: variable-length field length */
+ const byte* field, /*!< in: field in the MySQL format */
+ ulint lenlen);/*!< in: storage length of len: either 1
or 2 bytes */
-/***********************************************************************
+/*******************************************************************//**
Stores a reference to a BLOB in the MySQL format. */
UNIV_INTERN
void
row_mysql_store_blob_ref(
/*=====================*/
- byte* dest, /* in: where to store */
- ulint col_len,/* in: dest buffer size: determines into
+ byte* dest, /*!< in: where to store */
+ ulint col_len,/*!< in: dest buffer size: determines into
how many bytes the BLOB length is stored,
the space for the length may vary from 1
to 4 bytes */
- const void* data, /* in: BLOB data; if the value to store
+ const void* data, /*!< in: BLOB data; if the value to store
is SQL NULL this should be NULL pointer */
- ulint len); /* in: BLOB length; if the value to store
+ ulint len); /*!< in: BLOB length; if the value to store
is SQL NULL this should be 0; remember
also to set the NULL bit in the MySQL record
header! */
-/***********************************************************************
-Reads a reference to a BLOB in the MySQL format. */
-
+/*******************************************************************//**
+Reads a reference to a BLOB in the MySQL format.
+@return pointer to BLOB data */
+UNIV_INTERN
const byte*
row_mysql_read_blob_ref(
/*====================*/
- /* out: pointer to BLOB data */
- ulint* len, /* out: BLOB length */
- const byte* ref, /* in: BLOB reference in the
+ ulint* len, /*!< out: BLOB length */
+ const byte* ref, /*!< in: BLOB reference in the
MySQL format */
- ulint col_len); /* in: BLOB reference length
+ ulint col_len); /*!< in: BLOB reference length
(not BLOB length) */
-/******************************************************************
+/**************************************************************//**
Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
The counterpart of this function is row_sel_field_store_in_mysql_format() in
-row0sel.c. */
+row0sel.c.
+@return up to which byte we used buf in the conversion */
UNIV_INTERN
byte*
row_mysql_store_col_in_innobase_format(
/*===================================*/
- /* out: up to which byte we used
- buf in the conversion */
- dfield_t* dfield, /* in/out: dfield where dtype
+ dfield_t* dfield, /*!< in/out: dfield where dtype
information must be already set when
this function is called! */
- byte* buf, /* in/out: buffer for a converted
+ byte* buf, /*!< in/out: buffer for a converted
integer value; this must be at least
col_len long then! */
- ibool row_format_col, /* TRUE if the mysql_data is from
+ ibool row_format_col, /*!< TRUE if the mysql_data is from
a MySQL row, FALSE if from a MySQL
key value;
in MySQL, a true VARCHAR storage
format differs in a row and in a
key value: in a key value the length
is always stored in 2 bytes! */
- const byte* mysql_data, /* in: MySQL column value, not
+ const byte* mysql_data, /*!< in: MySQL column value, not
SQL NULL; NOTE that dfield may also
get a pointer to mysql_data,
therefore do not discard this as long
as dfield is used! */
- ulint col_len, /* in: MySQL column length; NOTE that
+ ulint col_len, /*!< in: MySQL column length; NOTE that
this is the storage length of the
column in the MySQL format row, not
necessarily the length of the actual
payload data; if the column is a true
VARCHAR then this is irrelevant */
- ulint comp); /* in: nonzero=compact format */
-/********************************************************************
-Handles user errors and lock waits detected by the database engine. */
+ ulint comp); /*!< in: nonzero=compact format */
+/****************************************************************//**
+Handles user errors and lock waits detected by the database engine.
+@return TRUE if it was a lock wait and we should continue running the
+query thread */
UNIV_INTERN
ibool
row_mysql_handle_errors(
/*====================*/
- /* out: TRUE if it was a lock wait and
- we should continue running the query thread */
- ulint* new_err,/* out: possible new error encountered in
+ ulint* new_err,/*!< out: possible new error encountered in
rollback, or the old error which was
during the function entry */
- trx_t* trx, /* in: transaction */
- que_thr_t* thr, /* in: query thread */
- trx_savept_t* savept);/* in: savepoint */
-/************************************************************************
-Create a prebuilt struct for a MySQL table handle. */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t* thr, /*!< in: query thread */
+ trx_savept_t* savept);/*!< in: savepoint */
+/********************************************************************//**
+Create a prebuilt struct for a MySQL table handle.
+@return own: a prebuilt struct */
UNIV_INTERN
row_prebuilt_t*
row_create_prebuilt(
/*================*/
- /* out, own: a prebuilt struct */
- dict_table_t* table); /* in: Innobase table handle */
-/************************************************************************
+ dict_table_t* table); /*!< in: Innobase table handle */
+/********************************************************************//**
Free a prebuilt struct for a MySQL table handle. */
UNIV_INTERN
void
row_prebuilt_free(
/*==============*/
- row_prebuilt_t* prebuilt, /* in, own: prebuilt struct */
- ibool dict_locked); /* in: TRUE=data dictionary locked */
-/*************************************************************************
+ row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */
+ ibool dict_locked); /*!< in: TRUE=data dictionary locked */
+/*********************************************************************//**
Updates the transaction pointers in query graphs stored in the prebuilt
struct. */
UNIV_INTERN
void
row_update_prebuilt_trx(
/*====================*/
- /* out: prebuilt dtuple */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
- handle */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
+ in MySQL handle */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
/*===============================*/
- trx_t* trx); /* in/out: transaction */
-/*************************************************************************
+ trx_t* trx); /*!< in/out: transaction */
+/*********************************************************************//**
Sets an AUTO_INC type lock on the table mentioned in prebuilt. The
AUTO_INC lock gives exclusive access to the auto-inc counter of the
table. The lock is reserved only for the duration of an SQL statement.
It is not compatible with another AUTO_INC or exclusive lock on the
-table. */
+table.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_lock_table_autoinc_for_mysql(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in the MySQL
table handle */
-/*************************************************************************
-Sets a table lock on the table mentioned in prebuilt. */
+/*********************************************************************//**
+Sets a table lock on the table mentioned in prebuilt.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_lock_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in the MySQL
table handle */
- dict_table_t* table, /* in: table to lock, or NULL
+ dict_table_t* table, /*!< in: table to lock, or NULL
if prebuilt->table should be
locked as
prebuilt->select_lock_type */
- ulint mode); /* in: lock mode of table
+ ulint mode); /*!< in: lock mode of table
(ignored if table==NULL) */
-/*************************************************************************
-Does an insert for MySQL. */
+/*********************************************************************//**
+Does an insert for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_insert_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- byte* mysql_rec, /* in: row in the MySQL format */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ byte* mysql_rec, /*!< in: row in the MySQL format */
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-/*************************************************************************
+/*********************************************************************//**
Builds a dummy query graph used in selects. */
UNIV_INTERN
void
row_prebuild_sel_graph(
/*===================*/
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-/*************************************************************************
+/*********************************************************************//**
Gets pointer to a prebuilt update vector used in updates. If the update
graph has not yet been built in the prebuilt struct, then this function
-first builds it. */
+first builds it.
+@return prebuilt update vector */
UNIV_INTERN
upd_t*
row_get_prebuilt_update_vector(
/*===========================*/
- /* out: prebuilt update vector */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-/*************************************************************************
+/*********************************************************************//**
Checks if a table is such that we automatically created a clustered
-index on it (on row id). */
+index on it (on row id).
+@return TRUE if the clustered index was generated automatically */
UNIV_INTERN
ibool
row_table_got_default_clust_index(
/*==============================*/
- const dict_table_t* table);
-/*************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/*********************************************************************//**
Calculates the key number used inside MySQL for an Innobase index. We have
-to take into account if we generated a default clustered index for the table */
+to take into account if we generated a default clustered index for the table
+@return the key number used inside MySQL */
UNIV_INTERN
ulint
row_get_mysql_key_number_for_index(
/*===============================*/
- const dict_index_t* index);
-/*************************************************************************
-Does an update or delete of a row for MySQL. */
+ const dict_index_t* index); /*!< in: index */
+/*********************************************************************//**
+Does an update or delete of a row for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_update_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- byte* mysql_rec, /* in: the row to be updated, in
+ byte* mysql_rec, /*!< in: the row to be updated, in
the MySQL format */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-/*************************************************************************
+/*********************************************************************//**
This can only be used when srv_locks_unsafe_for_binlog is TRUE or
session is using a READ COMMITTED isolation level. Before
calling this function we must use trx_reset_new_rec_lock_info() and
@@ -280,238 +282,235 @@ and also under prebuilt->clust_pcur. Currently, this is only used and tested
in the case of an UPDATE or a DELETE statement, where the row lock is of the
LOCK_X type.
Thus, this implements a 'mini-rollback' that releases the latest record
-locks we set. */
+locks we set.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_unlock_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
handle */
- ibool has_latches_on_recs);/* TRUE if called so that we have
+ ibool has_latches_on_recs);/*!< TRUE if called so that we have
the latches on the records under pcur
and clust_pcur, and we do not need to
reposition the cursors. */
-/*************************************************************************
+/*********************************************************************//**
Creates an query graph node of 'update' type to be used in the MySQL
-interface. */
+interface.
+@return own: update node */
UNIV_INTERN
upd_node_t*
row_create_update_node_for_mysql(
/*=============================*/
- /* out, own: update node */
- dict_table_t* table, /* in: table to update */
- mem_heap_t* heap); /* in: mem heap from which allocated */
-/**************************************************************************
-Does a cascaded delete or set null in a foreign key operation. */
+ dict_table_t* table, /*!< in: table to update */
+ mem_heap_t* heap); /*!< in: mem heap from which allocated */
+/**********************************************************************//**
+Does a cascaded delete or set null in a foreign key operation.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_update_cascade_for_mysql(
/*=========================*/
- /* out: error code or DB_SUCCESS */
- que_thr_t* thr, /* in: query thread */
- upd_node_t* node, /* in: update node used in the cascade
+ que_thr_t* thr, /*!< in: query thread */
+ upd_node_t* node, /*!< in: update node used in the cascade
or set null operation */
- dict_table_t* table); /* in: table where we do the operation */
-/*************************************************************************
+ dict_table_t* table); /*!< in: table where we do the operation */
+/*********************************************************************//**
Locks the data dictionary exclusively for performing a table create or other
data dictionary modification operation. */
UNIV_INTERN
void
row_mysql_lock_data_dictionary_func(
/*================================*/
- trx_t* trx, /* in/out: transaction */
- const char* file, /* in: file name */
- ulint line); /* in: line number */
+ trx_t* trx, /*!< in/out: transaction */
+ const char* file, /*!< in: file name */
+ ulint line); /*!< in: line number */
#define row_mysql_lock_data_dictionary(trx) \
row_mysql_lock_data_dictionary_func(trx, __FILE__, __LINE__)
-/*************************************************************************
+/*********************************************************************//**
Unlocks the data dictionary exclusive lock. */
UNIV_INTERN
void
row_mysql_unlock_data_dictionary(
/*=============================*/
- trx_t* trx); /* in/out: transaction */
-/*************************************************************************
+ trx_t* trx); /*!< in/out: transaction */
+/*********************************************************************//**
Locks the data dictionary in shared mode from modifications, for performing
foreign key check, rollback, or other operation invisible to MySQL. */
UNIV_INTERN
void
row_mysql_freeze_data_dictionary_func(
/*==================================*/
- trx_t* trx, /* in/out: transaction */
- const char* file, /* in: file name */
- ulint line); /* in: line number */
+ trx_t* trx, /*!< in/out: transaction */
+ const char* file, /*!< in: file name */
+ ulint line); /*!< in: line number */
#define row_mysql_freeze_data_dictionary(trx) \
row_mysql_freeze_data_dictionary_func(trx, __FILE__, __LINE__)
-/*************************************************************************
+/*********************************************************************//**
Unlocks the data dictionary shared lock. */
UNIV_INTERN
void
row_mysql_unfreeze_data_dictionary(
/*===============================*/
- trx_t* trx); /* in/out: transaction */
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+ trx_t* trx); /*!< in/out: transaction */
+/*********************************************************************//**
Creates a table for MySQL. If the name of the table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also start the printing of monitor
output by the master thread. If the table name ends in "innodb_mem_validate",
-InnoDB will try to invoke mem_validate(). */
+InnoDB will try to invoke mem_validate().
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_create_table_for_mysql(
/*=======================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* table, /* in, own: table definition
+ dict_table_t* table, /*!< in, own: table definition
(will be freed) */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
Does an index creation operation for MySQL. TODO: currently failure
to create an index results in dropping the whole table! This is no problem
-currently as all indexes must be created at the same time as the table. */
+currently as all indexes must be created at the same time as the table.
+@return error number or DB_SUCCESS */
UNIV_INTERN
int
row_create_index_for_mysql(
/*=======================*/
- /* out: error number or DB_SUCCESS */
- dict_index_t* index, /* in, own: index definition
+ dict_index_t* index, /*!< in, own: index definition
(will be freed) */
- trx_t* trx, /* in: transaction handle */
- const ulint* field_lengths); /* in: if not NULL, must contain
+ trx_t* trx, /*!< in: transaction handle */
+ const ulint* field_lengths); /*!< in: if not NULL, must contain
dict_index_get_n_fields(index)
actual field lengths for the
index columns, which are
then checked for not being too
large. */
-/*************************************************************************
+/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
Each foreign key constraint must be accompanied with indexes in
bot participating tables. The indexes are allowed to contain more
-fields than mentioned in the constraint. */
+fields than mentioned in the constraint.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_table_add_foreign_constraints(
/*==============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- const char* sql_string, /* in: table create statement where
+ trx_t* trx, /*!< in: transaction */
+ const char* sql_string, /*!< in: table create statement where
foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the
database name before it: test.table2 */
- const char* name, /* in: table full name in the
+ const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
- ibool reject_fks); /* in: if TRUE, fail with error
+ ibool reject_fks); /*!< in: if TRUE, fail with error
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
-/*************************************************************************
+/*********************************************************************//**
The master thread in srv0srv.c calls this regularly to drop tables which
we must drop in background after queries to them have ended. Such lazy
-dropping of tables is needed in ALTER TABLE on Unix. */
+dropping of tables is needed in ALTER TABLE on Unix.
+@return how many tables dropped + remaining tables in list */
UNIV_INTERN
ulint
row_drop_tables_for_mysql_in_background(void);
/*=========================================*/
- /* out: how many tables dropped
- + remaining tables in list */
-/*************************************************************************
+/*********************************************************************//**
Get the background drop list length. NOTE: the caller must own the kernel
-mutex! */
+mutex!
+@return how many tables in list */
UNIV_INTERN
ulint
row_get_background_drop_list_len_low(void);
/*======================================*/
- /* out: how many tables in list */
-/*************************************************************************
-Truncates a table for MySQL. */
+/*********************************************************************//**
+Truncates a table for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_truncate_table_for_mysql(
/*=========================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* table, /* in: table handle */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
+ dict_table_t* table, /*!< in: table handle */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
Drops a table for MySQL. If the name of the dropped table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also stop the printing of monitor
output by the master thread. If the data dictionary was not already locked
by the transaction, the transaction will be committed. Otherwise, the
-data dictionary will remain locked. */
+data dictionary will remain locked.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_drop_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx, /* in: transaction handle */
- ibool drop_db);/* in: TRUE=dropping whole database */
+ const char* name, /*!< in: table name */
+ trx_t* trx, /*!< in: transaction handle */
+ ibool drop_db);/*!< in: TRUE=dropping whole database */
-/*************************************************************************
+/*********************************************************************//**
Discards the tablespace of a table which stored in an .ibd file. Discarding
means that this function deletes the .ibd file and assigns a new table id for
-the table. Also the flag table->ibd_file_missing is set TRUE. */
+the table. Also the flag table->ibd_file_missing is set TRUE.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_discard_tablespace_for_mysql(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx); /* in: transaction handle */
-/*********************************************************************
+ const char* name, /*!< in: table name */
+ trx_t* trx); /*!< in: transaction handle */
+/*****************************************************************//**
Imports a tablespace. The space id in the .ibd file must match the space id
-of the table in the data dictionary. */
+of the table in the data dictionary.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_import_tablespace_for_mysql(
/*============================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
-Drops a database for MySQL. */
+ const char* name, /*!< in: table name */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
+Drops a database for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_drop_database_for_mysql(
/*========================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: database name which ends to '/' */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
-Renames a table for MySQL. */
+ const char* name, /*!< in: database name which ends to '/' */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
+Renames a table for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_rename_table_for_mysql(
/*=======================*/
- /* out: error code or DB_SUCCESS */
- const char* old_name, /* in: old table name */
- const char* new_name, /* in: new table name */
- trx_t* trx, /* in: transaction handle */
- ibool commit); /* in: if TRUE then commit trx */
-/*************************************************************************
-Checks a table for corruption. */
+ const char* old_name, /*!< in: old table name */
+ const char* new_name, /*!< in: new table name */
+ trx_t* trx, /*!< in: transaction handle */
+ ibool commit); /*!< in: if TRUE then commit trx */
+/*********************************************************************//**
+Checks a table for corruption.
+@return DB_ERROR or DB_SUCCESS */
UNIV_INTERN
ulint
row_check_table_for_mysql(
/*======================*/
- /* out: DB_ERROR or DB_SUCCESS */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Determines if a table is a magic monitor table. */
+/*********************************************************************//**
+Determines if a table is a magic monitor table.
+@return TRUE if monitor table */
UNIV_INTERN
ibool
row_is_magic_monitor_table(
/*=======================*/
- /* out: TRUE if monitor table */
- const char* table_name); /* in: name of the table, in the
+ const char* table_name); /*!< in: name of the table, in the
form database/table_name */
/* A struct describing a place for an individual column in the MySQL
@@ -521,24 +520,24 @@ Innobase and MySQL. */
typedef struct mysql_row_templ_struct mysql_row_templ_t;
struct mysql_row_templ_struct {
- ulint col_no; /* column number of the column */
- ulint rec_field_no; /* field number of the column in an
+ ulint col_no; /*!< column number of the column */
+ ulint rec_field_no; /*!< field number of the column in an
Innobase record in the current index;
not defined if template_type is
ROW_MYSQL_WHOLE_ROW */
- ulint mysql_col_offset; /* offset of the column in the MySQL
+ ulint mysql_col_offset; /*!< offset of the column in the MySQL
row format */
- ulint mysql_col_len; /* length of the column in the MySQL
+ ulint mysql_col_len; /*!< length of the column in the MySQL
row format */
- ulint mysql_null_byte_offset; /* MySQL NULL bit byte offset in a
+ ulint mysql_null_byte_offset; /*!< MySQL NULL bit byte offset in a
MySQL record */
- ulint mysql_null_bit_mask; /* bit mask to get the NULL bit,
+ ulint mysql_null_bit_mask; /*!< bit mask to get the NULL bit,
zero if column cannot be NULL */
- ulint type; /* column type in Innobase mtype
+ ulint type; /*!< column type in Innobase mtype
numbers DATA_CHAR... */
- ulint mysql_type; /* MySQL type code; this is always
+ ulint mysql_type; /*!< MySQL type code; this is always
< 256 */
- ulint mysql_length_bytes; /* if mysql_type
+ ulint mysql_length_bytes; /*!< if mysql_type
== DATA_MYSQL_TRUE_VARCHAR, this tells
whether we should use 1 or 2 bytes to
store the MySQL true VARCHAR data
@@ -546,13 +545,13 @@ struct mysql_row_templ_struct {
format (NOTE that the MySQL key value
format always uses 2 bytes for the data
len) */
- ulint charset; /* MySQL charset-collation code
+ ulint charset; /*!< MySQL charset-collation code
of the column, or zero */
- ulint mbminlen; /* minimum length of a char, in bytes,
+ ulint mbminlen; /*!< minimum length of a char, in bytes,
or zero if not a char type */
- ulint mbmaxlen; /* maximum length of a char, in bytes,
+ ulint mbmaxlen; /*!< maximum length of a char, in bytes,
or zero if not a char type */
- ulint is_unsigned; /* if a column type is an integer
+ ulint is_unsigned; /*!< if a column type is an integer
type and this field is != 0, then
it is an unsigned integer type */
};
@@ -565,80 +564,82 @@ struct mysql_row_templ_struct {
#define ROW_PREBUILT_FREED 26423527
typedef int (*index_cond_func_t)(void *param);
+/** A struct for (sometimes lazily) prebuilt structures in an Innobase table
-/* A struct for (sometimes lazily) prebuilt structures in an Innobase table
handle used within MySQL; these are used to save CPU time. */
struct row_prebuilt_struct {
- ulint magic_n; /* this magic number is set to
+ ulint magic_n; /*!< this magic number is set to
ROW_PREBUILT_ALLOCATED when created,
or ROW_PREBUILT_FREED when the
struct has been freed */
- dict_table_t* table; /* Innobase table handle */
- trx_t* trx; /* current transaction handle */
- ibool sql_stat_start; /* TRUE when we start processing of
+ dict_table_t* table; /*!< Innobase table handle */
+ dict_index_t* index; /*!< current index for a search, if
+ any */
+ trx_t* trx; /*!< current transaction handle */
+ unsigned sql_stat_start:1;/*!< TRUE when we start processing of
an SQL statement: we may have to set
an intention lock on the table,
create a consistent read view etc. */
- ibool mysql_has_locked; /* this is set TRUE when MySQL
+ unsigned mysql_has_locked:1;/*!< this is set TRUE when MySQL
calls external_lock on this handle
with a lock flag, and set FALSE when
with the F_UNLOCK flag */
- ibool clust_index_was_generated;
- /* if the user did not define a
+ unsigned clust_index_was_generated:1;
+ /*!< if the user did not define a
primary key in MySQL, then Innobase
automatically generated a clustered
index where the ordering column is
the row id: in this case this flag
is set to TRUE */
- dict_index_t* index; /* current index for a search, if
- any */
- ulint read_just_key; /* set to 1 when MySQL calls
+ unsigned index_usable:1; /*!< caches the value of
+ row_merge_is_index_usable(trx,index) */
+ unsigned read_just_key:1;/*!< set to 1 when MySQL calls
ha_innobase::extra with the
argument HA_EXTRA_KEYREAD; it is enough
to read just columns defined in
the index (i.e., no read of the
clustered index record necessary) */
- ibool used_in_HANDLER;/* TRUE if we have been using this
+ unsigned used_in_HANDLER:1;/*!< TRUE if we have been using this
handle in a MySQL HANDLER low level
index cursor command: then we must
store the pcur position even in a
unique search from a clustered index,
because HANDLER allows NEXT and PREV
in such a situation */
- ulint template_type; /* ROW_MYSQL_WHOLE_ROW,
+ unsigned template_type:2;/*!< ROW_MYSQL_WHOLE_ROW,
ROW_MYSQL_REC_FIELDS,
ROW_MYSQL_DUMMY_TEMPLATE, or
ROW_MYSQL_NO_TEMPLATE */
- ulint n_template; /* number of elements in the
+ unsigned n_template:10; /*!< number of elements in the
template */
- ulint null_bitmap_len;/* number of bytes in the SQL NULL
+ unsigned null_bitmap_len:10;/*!< number of bytes in the SQL NULL
bitmap at the start of a row in the
MySQL format */
- ibool need_to_access_clustered; /* if we are fetching
+ unsigned need_to_access_clustered:1; /*!< if we are fetching
columns through a secondary index
and at least one column is not in
the secondary index, then this is
set to TRUE */
- ibool templ_contains_blob;/* TRUE if the template contains
+ unsigned templ_contains_blob:1;/*!< TRUE if the template contains
BLOB column(s) */
- mysql_row_templ_t* mysql_template;/* template used to transform
+ mysql_row_templ_t* mysql_template;/*!< template used to transform
rows fast between MySQL and Innobase
formats; memory for this template
is not allocated from 'heap' */
- mem_heap_t* heap; /* memory heap from which
+ mem_heap_t* heap; /*!< memory heap from which
these auxiliary structures are
allocated when needed */
- ins_node_t* ins_node; /* Innobase SQL insert node
+ ins_node_t* ins_node; /*!< Innobase SQL insert node
used to perform inserts
to the table */
- byte* ins_upd_rec_buff;/* buffer for storing data converted
+ byte* ins_upd_rec_buff;/*!< buffer for storing data converted
to the Innobase format from the MySQL
format */
- const byte* default_rec; /* the default values of all columns
+ const byte* default_rec; /*!< the default values of all columns
(a "default row") in MySQL format */
ulint hint_need_to_fetch_extra_cols;
- /* normally this is set to 0; if this
+ /*!< normally this is set to 0; if this
is set to ROW_RETRIEVE_PRIMARY_KEY,
then we should at least retrieve all
columns in the primary key; if this
@@ -646,33 +647,33 @@ struct row_prebuilt_struct {
we must retrieve all columns in the
key (if read_just_key == 1), or all
columns in the table */
- upd_node_t* upd_node; /* Innobase SQL update node used
+ upd_node_t* upd_node; /*!< Innobase SQL update node used
to perform updates and deletes */
- que_fork_t* ins_graph; /* Innobase SQL query graph used
+ que_fork_t* ins_graph; /*!< Innobase SQL query graph used
in inserts */
- que_fork_t* upd_graph; /* Innobase SQL query graph used
+ que_fork_t* upd_graph; /*!< Innobase SQL query graph used
in updates or deletes */
- btr_pcur_t* pcur; /* persistent cursor used in selects
+ btr_pcur_t* pcur; /*!< persistent cursor used in selects
and updates */
- btr_pcur_t* clust_pcur; /* persistent cursor used in
+ btr_pcur_t* clust_pcur; /*!< persistent cursor used in
some selects and updates */
- que_fork_t* sel_graph; /* dummy query graph used in
+ que_fork_t* sel_graph; /*!< dummy query graph used in
selects */
- dtuple_t* search_tuple; /* prebuilt dtuple used in selects */
+ dtuple_t* search_tuple; /*!< prebuilt dtuple used in selects */
byte row_id[DATA_ROW_ID_LEN];
- /* if the clustered index was
+ /*!< if the clustered index was
generated, the row id of the
last row fetched is stored
here */
- dtuple_t* clust_ref; /* prebuilt dtuple used in
+ dtuple_t* clust_ref; /*!< prebuilt dtuple used in
sel/upd/del */
- ulint select_lock_type;/* LOCK_NONE, LOCK_S, or LOCK_X */
- ulint stored_select_lock_type;/* this field is used to
+ ulint select_lock_type;/*!< LOCK_NONE, LOCK_S, or LOCK_X */
+ ulint stored_select_lock_type;/*!< this field is used to
remember the original select_lock_type
that was decided in ha_innodb.cc,
::store_lock(), ::external_lock(),
etc. */
- ulint row_read_type; /* ROW_READ_WITH_LOCKS if row locks
+ ulint row_read_type; /*!< ROW_READ_WITH_LOCKS if row locks
should be the obtained for records
under an UPDATE or DELETE cursor.
If innodb_locks_unsafe_for_binlog
@@ -697,7 +698,7 @@ struct row_prebuilt_struct {
This eliminates lock waits in some
cases; note that this breaks
serializability. */
- ulint new_rec_locks; /* normally 0; if
+ ulint new_rec_locks; /*!< normally 0; if
srv_locks_unsafe_for_binlog is
TRUE or session is using READ
COMMITTED isolation level, in a
@@ -712,15 +713,15 @@ struct row_prebuilt_struct {
these can be used to implement a
'mini-rollback' that releases
the latest record locks */
- ulint mysql_prefix_len;/* byte offset of the end of
+ ulint mysql_prefix_len;/*!< byte offset of the end of
the last requested column */
- ulint mysql_row_len; /* length in bytes of a row in the
+ ulint mysql_row_len; /*!< length in bytes of a row in the
MySQL format */
- ulint n_rows_fetched; /* number of rows fetched after
+ ulint n_rows_fetched; /*!< number of rows fetched after
positioning the current cursor */
- ulint fetch_direction;/* ROW_SEL_NEXT or ROW_SEL_PREV */
+ ulint fetch_direction;/*!< ROW_SEL_NEXT or ROW_SEL_PREV */
byte* fetch_cache[MYSQL_FETCH_CACHE_SIZE];
- /* a cache for fetched rows if we
+ /*!< a cache for fetched rows if we
fetch many rows from the same cursor:
it saves CPU time to fetch them in a
batch; we reserve mysql_row_len
@@ -729,35 +730,36 @@ struct row_prebuilt_struct {
allocated mem buf start, because
there is a 4 byte magic number at the
start and at the end */
- ibool keep_other_fields_on_keyread; /* when using fetch
+ ibool keep_other_fields_on_keyread; /*!< when using fetch
cache with HA_EXTRA_KEYREAD, don't
overwrite other fields in mysql row
row buffer.*/
- ulint fetch_cache_first;/* position of the first not yet
+ ulint fetch_cache_first;/*!< position of the first not yet
fetched row in fetch_cache */
- ulint n_fetch_cached; /* number of not yet fetched rows
+ ulint n_fetch_cached; /*!< number of not yet fetched rows
in fetch_cache */
- mem_heap_t* blob_heap; /* in SELECTS BLOB fields are copied
+ mem_heap_t* blob_heap; /*!< in SELECTS BLOB fields are copied
to this heap */
- mem_heap_t* old_vers_heap; /* memory heap where a previous
+ mem_heap_t* old_vers_heap; /*!< memory heap where a previous
version is built in consistent read */
/*----------------------*/
- ulonglong autoinc_last_value;/* last value of AUTO-INC interval */
- ulonglong autoinc_increment;/* The increment step of the auto
+ ulonglong autoinc_last_value;
+ /*!< last value of AUTO-INC interval */
+ ulonglong autoinc_increment;/*!< The increment step of the auto
increment column. Value must be
greater than or equal to 1. Required to
calculate the next value */
- ulonglong autoinc_offset; /* The offset passed to
+ ulonglong autoinc_offset; /*!< The offset passed to
get_auto_increment() by MySQL. Required
to calculate the next value */
- ulint autoinc_error; /* The actual error code encountered
+ ulint autoinc_error; /*!< The actual error code encountered
while trying to init or read the
autoinc value from the table. We
store it here so that we can return
it to MySQL */
/*----------------------*/
- UT_LIST_NODE_T(row_prebuilt_t) prebuilts;
- /* list node of table->prebuilts */
+ ulint magic_n2; /*!< this should be the same as
+ magic_n */
/*----------------------*/
index_cond_func_t idx_cond_func;/* Index Condition Pushdown function,
or NULL if there is none set */
@@ -766,8 +768,6 @@ struct row_prebuilt_struct {
mysql_template. Valid only when using
ICP. */
/*----------------------*/
- ulint magic_n2; /* this should be the same as
- magic_n */
};
#define ROW_PREBUILT_FETCH_MAGIC_N 465765687
diff --git a/storage/xtradb/include/row0mysql.ic b/storage/xtradb/include/row0mysql.ic
index 5260ae17924..35033aa2ad1 100644
--- a/storage/xtradb/include/row0mysql.ic
+++ b/storage/xtradb/include/row0mysql.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0mysql.ic
MySQL interface for Innobase
Created 1/23/2001 Heikki Tuuri
diff --git a/storage/xtradb/include/row0purge.h b/storage/xtradb/include/row0purge.h
index fbc12f8d389..89ec54fb54a 100644
--- a/storage/xtradb/include/row0purge.h
+++ b/storage/xtradb/include/row0purge.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0purge.h
Purge obsolete records
Created 3/14/1997 Heikki Tuuri
@@ -34,56 +35,56 @@ Created 3/14/1997 Heikki Tuuri
#include "que0types.h"
#include "row0types.h"
-/************************************************************************
-Creates a purge node to a query graph. */
+/********************************************************************//**
+Creates a purge node to a query graph.
+@return own: purge node */
UNIV_INTERN
purge_node_t*
row_purge_node_create(
/*==================*/
- /* out, own: purge node */
- que_thr_t* parent, /* in: parent node, i.e., a thr node */
- mem_heap_t* heap); /* in: memory heap where created */
-/***************************************************************
+ que_thr_t* parent, /*!< in: parent node, i.e., a thr node */
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/***********************************************************//**
Does the purge operation for a single undo log record. This is a high-level
-function used in an SQL execution graph. */
+function used in an SQL execution graph.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_purge_step(
/*===========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
/* Purge node structure */
struct purge_node_struct{
- que_common_t common; /* node type: QUE_NODE_PURGE */
+ que_common_t common; /*!< node type: QUE_NODE_PURGE */
/*----------------------*/
/* Local storage for this graph node */
- dulint roll_ptr;/* roll pointer to undo log record */
+ roll_ptr_t roll_ptr;/* roll pointer to undo log record */
trx_undo_rec_t* undo_rec;/* undo log record */
trx_undo_inf_t* reservation;/* reservation for the undo log record in
the purge array */
- dulint undo_no;/* undo number of the record */
+ undo_no_t undo_no;/* undo number of the record */
ulint rec_type;/* undo log record type: TRX_UNDO_INSERT_REC,
... */
- btr_pcur_t pcur; /* persistent cursor used in searching the
+ btr_pcur_t pcur; /*!< persistent cursor used in searching the
clustered index record */
ibool found_clust;/* TRUE if the clustered index record
determined by ref was found in the clustered
index, and we were able to position pcur on
it */
- dict_table_t* table; /* table where purge is done */
+ dict_table_t* table; /*!< table where purge is done */
ulint cmpl_info;/* compiler analysis info of an update */
- upd_t* update; /* update vector for a clustered index
+ upd_t* update; /*!< update vector for a clustered index
record */
- dtuple_t* ref; /* NULL, or row reference to the next row to
+ dtuple_t* ref; /*!< NULL, or row reference to the next row to
handle */
- dtuple_t* row; /* NULL, or a copy (also fields copied to
+ dtuple_t* row; /*!< NULL, or a copy (also fields copied to
heap) of the indexed fields of the row to
handle */
- dict_index_t* index; /* NULL, or the next index whose record should
+ dict_index_t* index; /*!< NULL, or the next index whose record should
be handled */
- mem_heap_t* heap; /* memory heap used as auxiliary storage for
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage for
row; this must be emptied after a successful
purge of a row */
};
diff --git a/storage/xtradb/include/row0purge.ic b/storage/xtradb/include/row0purge.ic
index 5fc665e9d20..23d7d3845a4 100644
--- a/storage/xtradb/include/row0purge.ic
+++ b/storage/xtradb/include/row0purge.ic
@@ -17,7 +17,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0purge.ic
Purge obsolete records
Created 3/14/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/row0row.h b/storage/xtradb/include/row0row.h
index 26c4b5e4e71..723b7b53395 100644
--- a/storage/xtradb/include/row0row.h
+++ b/storage/xtradb/include/row0row.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0row.h
General row routines
Created 4/20/1996 Heikki Tuuri
@@ -36,74 +37,71 @@ Created 4/20/1996 Heikki Tuuri
#include "row0types.h"
#include "btr0types.h"
-/*************************************************************************
+/*********************************************************************//**
Gets the offset of the trx id field, in bytes relative to the origin of
-a clustered index record. */
+a clustered index record.
+@return offset of DATA_TRX_ID */
UNIV_INTERN
ulint
row_get_trx_id_offset(
/*==================*/
- /* out: offset of DATA_TRX_ID */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*************************************************************************
-Reads the trx id field from a clustered index record. */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*********************************************************************//**
+Reads the trx id field from a clustered index record.
+@return value of the field */
UNIV_INLINE
-dulint
+trx_id_t
row_get_rec_trx_id(
/*===============*/
- /* out: value of the field */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*************************************************************************
-Reads the roll pointer field from a clustered index record. */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*********************************************************************//**
+Reads the roll pointer field from a clustered index record.
+@return value of the field */
UNIV_INLINE
-dulint
+roll_ptr_t
row_get_rec_roll_ptr(
/*=================*/
- /* out: value of the field */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*********************************************************************
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*****************************************************************//**
When an insert or purge to a table is performed, this function builds
-the entry to be inserted into or purged from an index on the table. */
+the entry to be inserted into or purged from an index on the table.
+@return index entry which should be inserted or purged, or NULL if the
+externally stored columns in the clustered index record are
+unavailable and ext != NULL */
UNIV_INTERN
dtuple_t*
row_build_index_entry(
/*==================*/
- /* out: index entry which should be
- inserted or purged, or NULL if the
- externally stored columns in the
- clustered index record are unavailable
- and ext != NULL */
- const dtuple_t* row, /* in: row which should be
+ const dtuple_t* row, /*!< in: row which should be
inserted or purged */
- row_ext_t* ext, /* in: externally stored column prefixes,
+ row_ext_t* ext, /*!< in: externally stored column prefixes,
or NULL */
- dict_index_t* index, /* in: index on the table */
- mem_heap_t* heap); /* in: memory heap from which the memory for
+ dict_index_t* index, /*!< in: index on the table */
+ mem_heap_t* heap); /*!< in: memory heap from which the memory for
the index entry is allocated */
-/***********************************************************************
+/*******************************************************************//**
An inverse function to row_build_index_entry. Builds a row from a
-record in a clustered index. */
+record in a clustered index.
+@return own: row built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_build(
/*======*/
- /* out, own: row built;
- see the NOTE below! */
- ulint type, /* in: ROW_COPY_POINTERS or
+ ulint type, /*!< in: ROW_COPY_POINTERS or
ROW_COPY_DATA; the latter
copies also the data fields to
heap while the first only
places pointers to data fields
on the index page, and thus is
more efficient */
- const dict_index_t* index, /* in: clustered index */
- const rec_t* rec, /* in: record in the clustered
+ const dict_index_t* index, /*!< in: clustered index */
+ const rec_t* rec, /*!< in: record in the clustered
index; NOTE: in the case
ROW_COPY_POINTERS the data
fields in the row will point
@@ -112,11 +110,11 @@ 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 ulint* 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,
- /* in: table, to check which
+ /*!< in: table, to check which
externally stored columns
occur in the ordering columns
of an index, or NULL if
@@ -124,43 +122,41 @@ row_build(
consulted instead; the user
columns in this table should be
the same columns as in index->table */
- row_ext_t** ext, /* out, own: cache of
+ row_ext_t** ext, /*!< out, own: cache of
externally stored column
prefixes, or NULL */
- mem_heap_t* heap); /* in: memory heap from which
+ mem_heap_t* heap); /*!< in: memory heap from which
the memory needed is allocated */
-/***********************************************************************
-Converts an index record to a typed data tuple. */
+/*******************************************************************//**
+Converts an index record to a typed data tuple.
+@return index entry built; does not set info_bits, and the data fields
+in the entry will point directly to rec */
UNIV_INTERN
dtuple_t*
row_rec_to_index_entry_low(
/*=======================*/
- /* out: index entry built; does not
- set info_bits, and the data fields in
- the entry will point directly to rec */
- 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
+ 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 */
- mem_heap_t* heap); /* in: memory heap from which
+ mem_heap_t* heap); /*!< in: memory heap from which
the memory needed is allocated */
-/***********************************************************************
+/*******************************************************************//**
Converts an index record to a typed data tuple. NOTE that externally
-stored (often big) fields are NOT copied to heap. */
+stored (often big) fields are NOT copied to heap.
+@return own: index entry built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_rec_to_index_entry(
/*===================*/
- /* out, own: index entry
- built; see the NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or
+ ulint type, /*!< in: ROW_COPY_DATA, or
ROW_COPY_POINTERS: the former
copies also the data fields to
heap as the latter only places
pointers to data fields on the
index page */
- const rec_t* rec, /* in: record in the index;
+ const rec_t* rec, /*!< in: record in the index;
NOTE: in the case
ROW_COPY_POINTERS the data
fields in the row will point
@@ -169,45 +165,44 @@ row_rec_to_index_entry(
this record must be at least
s-latched and the latch held
as long as the dtuple is used! */
- const dict_index_t* index, /* in: index */
- ulint* offsets,/* in/out: rec_get_offsets(rec) */
- ulint* n_ext, /* out: number of externally
+ const dict_index_t* index, /*!< in: index */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec) */
+ ulint* n_ext, /*!< out: number of externally
stored columns */
- mem_heap_t* heap); /* in: memory heap from which
+ mem_heap_t* heap); /*!< in: memory heap from which
the memory needed is allocated */
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
-search the clustered index record. */
+search the clustered index record.
+@return own: row reference built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_build_row_ref(
/*==============*/
- /* out, own: row reference built; see the
- NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
+ ulint type, /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
the former copies also the data fields to
heap, whereas the latter only places pointers
to data fields on the index page */
- dict_index_t* index, /* in: secondary index */
- const rec_t* rec, /* in: record in the index;
+ dict_index_t* index, /*!< in: secondary index */
+ const rec_t* rec, /*!< in: record in the index;
NOTE: in the case ROW_COPY_POINTERS
the data fields in the row will point
directly into this record, therefore,
the buffer page of this record must be
at least s-latched and the latch held
as long as the row reference is used! */
- mem_heap_t* heap); /* in: memory heap from which the memory
+ mem_heap_t* heap); /*!< in: memory heap from which the memory
needed is allocated */
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INTERN
void
row_build_row_ref_in_tuple(
/*=======================*/
- dtuple_t* ref, /* in/out: row reference built;
+ dtuple_t* ref, /*!< in/out: row reference built;
see the NOTE below! */
- const rec_t* rec, /* in: record in the index;
+ const rec_t* rec, /*!< in: record in the index;
NOTE: the data fields in ref
will point directly into this
record, therefore, the buffer
@@ -215,81 +210,66 @@ row_build_row_ref_in_tuple(
least s-latched and the latch
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)
+ const dict_index_t* index, /*!< in: secondary index */
+ ulint* offsets,/*!< in: rec_get_offsets(rec, index)
or NULL */
- trx_t* trx); /* in: transaction */
-/***********************************************************************
-From a row build a row reference with which we can search the clustered
-index record. */
-UNIV_INTERN
-void
-row_build_row_ref_from_row(
-/*=======================*/
- dtuple_t* ref, /* in/out: row reference built;
- see the NOTE below!
- ref must have the right number
- of fields! */
- const dict_table_t* table, /* in: table */
- const dtuple_t* row); /* in: row
- NOTE: the data fields in ref will point
- directly into data of this row */
-/***********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INLINE
void
row_build_row_ref_fast(
/*===================*/
- dtuple_t* ref, /* in/out: typed data tuple where the
+ dtuple_t* ref, /*!< in/out: typed data tuple where the
reference is built */
- const ulint* map, /* in: array of field numbers in rec
+ const ulint* map, /*!< in: array of field numbers in rec
telling how ref should be built from
the fields of rec */
- const rec_t* rec, /* in: record in the index; must be
+ 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 ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Searches the clustered index record for a row, if we have the row
-reference. */
+reference.
+@return TRUE if found */
UNIV_INTERN
ibool
row_search_on_row_ref(
/*==================*/
- /* out: TRUE if found */
- btr_pcur_t* pcur, /* out: persistent cursor, which must
+ btr_pcur_t* pcur, /*!< out: persistent cursor, which must
be closed by the caller */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- const dict_table_t* table, /* in: table */
- const dtuple_t* ref, /* in: row reference */
- mtr_t* mtr); /* in/out: mtr */
-/*************************************************************************
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ const dict_table_t* table, /*!< in: table */
+ const dtuple_t* ref, /*!< in: row reference */
+ mtr_t* mtr); /*!< in/out: mtr */
+/*********************************************************************//**
Fetches the clustered index record for a secondary index record. The latches
-on the secondary index record are preserved. */
+on the secondary index record are preserved.
+@return record or NULL, if no record found */
UNIV_INTERN
rec_t*
row_get_clust_rec(
/*==============*/
- /* out: record or NULL, if no record found */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- const rec_t* rec, /* in: record in a secondary index */
- dict_index_t* index, /* in: secondary index */
- dict_index_t** clust_index,/* out: clustered index */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
-Searches an index record. */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ const rec_t* rec, /*!< in: record in a secondary index */
+ dict_index_t* index, /*!< in: secondary index */
+ dict_index_t** clust_index,/*!< out: clustered index */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
+Searches an index record.
+@return TRUE if found */
UNIV_INTERN
ibool
row_search_index_entry(
/*===================*/
- /* out: TRUE if found */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: index entry */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- btr_pcur_t* pcur, /* in/out: persistent cursor, which must
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: index entry */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ btr_pcur_t* pcur, /*!< in/out: persistent cursor, which must
be closed by the caller */
- mtr_t* mtr); /* in: mtr */
+ mtr_t* mtr); /*!< in: mtr */
#define ROW_COPY_DATA 1
@@ -303,25 +283,24 @@ row_search_index_entry(
No new latches may be obtained while the kernel mutex is reserved.
However, the kernel mutex can be reserved while latches are owned. */
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) using
"dict_field" and writes the result to "buf".
Not more than "buf_size" bytes are written to "buf".
-The result is always '\0'-terminated (provided buf_size > 0) and the
+The result is always NUL-terminated (provided buf_size is positive) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating NUL).
+@return number of bytes that were written */
UNIV_INTERN
ulint
row_raw_format(
/*===========*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- const dict_field_t* dict_field, /* in: index field */
- char* buf, /* out: output buffer */
- ulint buf_size); /* in: output buffer size
+ const dict_field_t* dict_field, /*!< in: index field */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size); /*!< in: output buffer size
in bytes */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/row0row.ic b/storage/xtradb/include/row0row.ic
index 9947dd43257..05c007641af 100644
--- a/storage/xtradb/include/row0row.ic
+++ b/storage/xtradb/include/row0row.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0row.ic
General row routines
Created 4/20/1996 Heikki Tuuri
@@ -26,16 +27,16 @@ Created 4/20/1996 Heikki Tuuri
#include "rem0rec.h"
#include "trx0undo.h"
-/*************************************************************************
-Reads the trx id field from a clustered index record. */
+/*********************************************************************//**
+Reads the trx id field from a clustered index record.
+@return value of the field */
UNIV_INLINE
-dulint
+trx_id_t
row_get_rec_trx_id(
/*===============*/
- /* out: value of the field */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint offset;
@@ -51,16 +52,16 @@ row_get_rec_trx_id(
return(trx_read_trx_id(rec + offset));
}
-/*************************************************************************
-Reads the roll pointer field from a clustered index record. */
+/*********************************************************************//**
+Reads the roll pointer field from a clustered index record.
+@return value of the field */
UNIV_INLINE
-dulint
+roll_ptr_t
row_get_rec_roll_ptr(
/*=================*/
- /* out: value of the field */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint offset;
@@ -76,22 +77,22 @@ row_get_rec_roll_ptr(
return(trx_read_roll_ptr(rec + offset + DATA_TRX_ID_LEN));
}
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INLINE
void
row_build_row_ref_fast(
/*===================*/
- dtuple_t* ref, /* in/out: typed data tuple where the
+ dtuple_t* ref, /*!< in/out: typed data tuple where the
reference is built */
- const ulint* map, /* in: array of field numbers in rec
+ const ulint* map, /*!< in: array of field numbers in rec
telling how ref should be built from
the fields of rec */
- const rec_t* rec, /* in: record in the index; must be
+ 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 ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
dfield_t* dfield;
const byte* field;
diff --git a/storage/xtradb/include/row0sel.h b/storage/xtradb/include/row0sel.h
index 2f8574d0691..01a5afaa23e 100644
--- a/storage/xtradb/include/row0sel.h
+++ b/storage/xtradb/include/row0sel.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0sel.h
Select
Created 12/19/1997 Heikki Tuuri
@@ -37,92 +38,93 @@ Created 12/19/1997 Heikki Tuuri
#include "read0read.h"
#include "row0mysql.h"
-/*************************************************************************
-Creates a select node struct. */
+/*********************************************************************//**
+Creates a select node struct.
+@return own: select node struct */
UNIV_INTERN
sel_node_t*
sel_node_create(
/*============*/
- /* out, own: select node struct */
- mem_heap_t* heap); /* in: memory heap where created */
-/*************************************************************************
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/*********************************************************************//**
Frees the memory private to a select node when a query graph is freed,
does not free the heap where the node was originally created. */
UNIV_INTERN
void
sel_node_free_private(
/*==================*/
- sel_node_t* node); /* in: select node struct */
-/*************************************************************************
+ sel_node_t* node); /*!< in: select node struct */
+/*********************************************************************//**
Frees a prefetch buffer for a column, including the dynamically allocated
memory for data stored there. */
UNIV_INTERN
void
sel_col_prefetch_buf_free(
/*======================*/
- sel_buf_t* prefetch_buf); /* in, own: prefetch buffer */
-/*************************************************************************
-Gets the plan node for the nth table in a join. */
+ sel_buf_t* prefetch_buf); /*!< in, own: prefetch buffer */
+/*********************************************************************//**
+Gets the plan node for the nth table in a join.
+@return plan node */
UNIV_INLINE
plan_t*
sel_node_get_nth_plan(
/*==================*/
- sel_node_t* node,
- ulint i);
-/**************************************************************************
+ sel_node_t* node, /*!< in: select node */
+ ulint i); /*!< in: get ith plan node */
+/**********************************************************************//**
Performs a select step. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_sel_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of an open or close cursor statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of an open or close cursor statement node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
open_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs a fetch for a cursor. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs a fetch for a cursor.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
fetch_step(
/*=======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/********************************************************************
-Sample callback function for fetch that prints each row.*/
+ que_thr_t* thr); /*!< in: query thread */
+/****************************************************************//**
+Sample callback function for fetch that prints each row.
+@return always returns non-NULL */
UNIV_INTERN
void*
row_fetch_print(
/*============*/
- /* out: always returns non-NULL */
- void* row, /* in: sel_node_t* */
- void* user_arg); /* in: not used */
-/********************************************************************
+ void* row, /*!< in: sel_node_t* */
+ void* user_arg); /*!< in: not used */
+/****************************************************************//**
Callback function for fetch that stores an unsigned 4 byte integer to the
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
-= 4. */
+= 4.
+@return always returns NULL */
UNIV_INTERN
void*
row_fetch_store_uint4(
/*==================*/
- /* out: always returns NULL */
- void* row, /* in: sel_node_t* */
- void* user_arg); /* in: data pointer */
-/***************************************************************
-Prints a row in a select result. */
+ void* row, /*!< in: sel_node_t* */
+ void* user_arg); /*!< in: data pointer */
+/***********************************************************//**
+Prints a row in a select result.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_printf_step(
/*============*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/********************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/****************************************************************//**
Converts a key value stored in MySQL format to an Innobase dtuple. The last
field of the key value may be just a prefix of a fixed length field: hence
the parameter key_len. But currently we do not allow search keys where the
@@ -132,96 +134,92 @@ UNIV_INTERN
void
row_sel_convert_mysql_key_to_innobase(
/*==================================*/
- dtuple_t* tuple, /* in/out: tuple where to build;
+ dtuple_t* tuple, /*!< in/out: tuple where to build;
NOTE: we assume that the type info
in the tuple is already according
to index! */
- byte* buf, /* in: buffer to use in field
+ byte* buf, /*!< in: buffer to use in field
conversions */
- ulint buf_len, /* in: buffer length */
- dict_index_t* index, /* in: index of the key value */
- const byte* key_ptr, /* in: MySQL key value */
- ulint key_len, /* in: MySQL key value length */
- trx_t* trx); /* in: transaction */
-/************************************************************************
+ ulint buf_len, /*!< in: buffer length */
+ dict_index_t* index, /*!< in: index of the key value */
+ const byte* key_ptr, /*!< in: MySQL key value */
+ ulint key_len, /*!< in: MySQL key value length */
+ trx_t* trx); /*!< in: transaction */
+/********************************************************************//**
Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next
and fetch prev. NOTE that if we do a search with a full key value
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
-position and fetch next or fetch prev must not be tried to the cursor! */
+position and fetch next or fetch prev must not be tried to the cursor!
+@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK,
+DB_LOCK_TABLE_FULL, or DB_TOO_BIG_RECORD */
UNIV_INTERN
ulint
row_search_for_mysql(
/*=================*/
- /* out: DB_SUCCESS,
- DB_RECORD_NOT_FOUND,
- DB_END_OF_INDEX, DB_DEADLOCK,
- DB_LOCK_TABLE_FULL,
- or DB_TOO_BIG_RECORD */
- byte* buf, /* in/out: buffer for the fetched
+ byte* buf, /*!< in/out: buffer for the fetched
row in the MySQL format */
- ulint mode, /* in: search mode PAGE_CUR_L, ... */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct for the
+ ulint mode, /*!< in: search mode PAGE_CUR_L, ... */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct for the
table handle; this contains the info
of search_tuple, index; if search
tuple contains 0 fields then we
position the cursor at the start or
the end of the index, depending on
'mode' */
- ulint match_mode, /* in: 0 or ROW_SEL_EXACT or
+ ulint match_mode, /*!< in: 0 or ROW_SEL_EXACT or
ROW_SEL_EXACT_PREFIX */
- ulint direction); /* in: 0 or ROW_SEL_NEXT or
+ ulint direction); /*!< in: 0 or ROW_SEL_NEXT or
ROW_SEL_PREV; NOTE: if this is != 0,
then prebuilt must have a pcur
with stored position! In opening of a
cursor 'direction' should be 0. */
-/***********************************************************************
+/*******************************************************************//**
Checks if MySQL at the moment is allowed for this table to retrieve a
-consistent read result, or store it to the query cache. */
+consistent read result, or store it to the query cache.
+@return TRUE if storing or retrieving from the query cache is permitted */
UNIV_INTERN
ibool
row_search_check_if_query_cache_permitted(
/*======================================*/
- /* out: TRUE if storing or retrieving
- from the query cache is permitted */
- trx_t* trx, /* in: transaction object */
- const char* norm_name); /* in: concatenation of database name,
+ trx_t* trx, /*!< in: transaction object */
+ const char* norm_name); /*!< in: concatenation of database name,
'/' char, table name */
-/***********************************************************************
-Read the max AUTOINC value from an index. */
+/*******************************************************************//**
+Read the max AUTOINC value from an index.
+@return DB_SUCCESS if all OK else error code */
UNIV_INTERN
ulint
row_search_max_autoinc(
/*===================*/
- /* out: DB_SUCCESS if all OK else
- error code */
- dict_index_t* index, /* in: index to search */
- const char* col_name, /* in: autoinc column name */
- ib_uint64_t* value); /* out: AUTOINC value read */
+ dict_index_t* index, /*!< in: index to search */
+ const char* col_name, /*!< in: autoinc column name */
+ ib_uint64_t* value); /*!< out: AUTOINC value read */
-/* A structure for caching column values for prefetched rows */
+/** A structure for caching column values for prefetched rows */
struct sel_buf_struct{
- byte* data; /* data, or NULL; if not NULL, this field
+ byte* data; /*!< data, or NULL; if not NULL, this field
has allocated memory which must be explicitly
freed; can be != NULL even when len is
UNIV_SQL_NULL */
- ulint len; /* data length or UNIV_SQL_NULL */
+ ulint len; /*!< data length or UNIV_SQL_NULL */
ulint val_buf_size;
- /* size of memory buffer allocated for data:
+ /*!< size of memory buffer allocated for data:
this can be more than len; this is defined
when data != NULL */
};
+/** Query plan */
struct plan_struct{
- dict_table_t* table; /* table struct in the dictionary
+ dict_table_t* table; /*!< table struct in the dictionary
cache */
- dict_index_t* index; /* table index used in the search */
- btr_pcur_t pcur; /* persistent cursor used to search
+ dict_index_t* index; /*!< table index used in the search */
+ btr_pcur_t pcur; /*!< persistent cursor used to search
the index */
- ibool asc; /* TRUE if cursor traveling upwards */
- ibool pcur_is_open; /* TRUE if pcur has been positioned
+ ibool asc; /*!< TRUE if cursor traveling upwards */
+ ibool pcur_is_open; /*!< TRUE if pcur has been positioned
and we can try to fetch new rows */
- ibool cursor_at_end; /* TRUE if the cursor is open but
+ ibool cursor_at_end; /*!< TRUE if the cursor is open but
we know that there are no more
qualifying rows left to retrieve from
the index tree; NOTE though, that
@@ -229,31 +227,34 @@ struct plan_struct{
the prefetch stack; always FALSE when
pcur_is_open is FALSE */
ibool stored_cursor_rec_processed;
- /* TRUE if the pcur position has been
+ /*!< TRUE if the pcur position has been
stored and the record it is positioned
on has already been processed */
- que_node_t** tuple_exps; /* array of expressions which are used
- to calculate the field values in the
- search tuple: there is one expression
- for each field in the search tuple */
- dtuple_t* tuple; /* search tuple */
- ulint mode; /* search mode: PAGE_CUR_G, ... */
- ulint n_exact_match; /* number of first fields in the search
- tuple which must be exactly matched */
- ibool unique_search; /* TRUE if we are searching an
+ que_node_t** tuple_exps; /*!< array of expressions
+ which are used to calculate
+ the field values in the search
+ tuple: there is one expression
+ for each field in the search
+ tuple */
+ dtuple_t* tuple; /*!< search tuple */
+ ulint mode; /*!< search mode: PAGE_CUR_G, ... */
+ ulint n_exact_match; /*!< number of first fields in
+ the search tuple which must be
+ exactly matched */
+ ibool unique_search; /*!< TRUE if we are searching an
index record with a unique key */
- ulint n_rows_fetched; /* number of rows fetched using pcur
+ ulint n_rows_fetched; /*!< number of rows fetched using pcur
after it was opened */
- ulint n_rows_prefetched;/* number of prefetched rows cached
+ ulint n_rows_prefetched;/*!< number of prefetched rows cached
for fetch: fetching several rows in
the same mtr saves CPU time */
- ulint first_prefetched;/* index of the first cached row in
+ ulint first_prefetched;/*!< index of the first cached row in
select buffer arrays for each column */
- ibool no_prefetch; /* no prefetch for this table */
- sym_node_list_t columns; /* symbol table nodes for the columns
+ ibool no_prefetch; /*!< no prefetch for this table */
+ sym_node_list_t columns; /*!< symbol table nodes for the columns
to retrieve from the table */
UT_LIST_BASE_NODE_T(func_node_t)
- end_conds; /* conditions which determine the
+ end_conds; /*!< conditions which determine the
fetch limit of the index segment we
have to look at: when one of these
fails, the result set has been
@@ -262,9 +263,9 @@ struct plan_struct{
so that in a comparison the column
for this table is the first argument */
UT_LIST_BASE_NODE_T(func_node_t)
- other_conds; /* the rest of search conditions we can
+ other_conds; /*!< the rest of search conditions we can
test at this table in a join */
- ibool must_get_clust; /* TRUE if index is a non-clustered
+ ibool must_get_clust; /*!< TRUE if index is a non-clustered
index and we must also fetch the
clustered index record; this is the
case if the non-clustered record does
@@ -272,52 +273,63 @@ struct plan_struct{
if this is a single-table explicit
cursor, or a searched update or
delete */
- ulint* clust_map; /* map telling how clust_ref is built
+ ulint* clust_map; /*!< map telling how clust_ref is built
from the fields of a non-clustered
record */
- dtuple_t* clust_ref; /* the reference to the clustered
+ dtuple_t* clust_ref; /*!< the reference to the clustered
index entry is built here if index is
a non-clustered index */
- btr_pcur_t clust_pcur; /* if index is non-clustered, we use
+ btr_pcur_t clust_pcur; /*!< if index is non-clustered, we use
this pcur to search the clustered
index */
- mem_heap_t* old_vers_heap; /* memory heap used in building an old
+ mem_heap_t* old_vers_heap; /*!< memory heap used in building an old
version of a row, or NULL */
};
+/** Select node states */
+enum sel_node_state {
+ SEL_NODE_CLOSED, /*!< it is a declared cursor which is not
+ currently open */
+ SEL_NODE_OPEN, /*!< intention locks not yet set on tables */
+ SEL_NODE_FETCH, /*!< intention locks have been set */
+ SEL_NODE_NO_MORE_ROWS /*!< cursor has reached the result set end */
+};
+
+/** Select statement node */
struct sel_node_struct{
- que_common_t common; /* node type: QUE_NODE_SELECT */
- ulint state; /* node state */
- que_node_t* select_list; /* select list */
- sym_node_t* into_list; /* variables list or NULL */
- sym_node_t* table_list; /* table list */
- ibool asc; /* TRUE if the rows should be fetched
+ que_common_t common; /*!< node type: QUE_NODE_SELECT */
+ enum sel_node_state
+ state; /*!< node state */
+ que_node_t* select_list; /*!< select list */
+ sym_node_t* into_list; /*!< variables list or NULL */
+ sym_node_t* table_list; /*!< table list */
+ ibool asc; /*!< TRUE if the rows should be fetched
in an ascending order */
- ibool set_x_locks; /* TRUE if the cursor is for update or
+ ibool set_x_locks; /*!< TRUE if the cursor is for update or
delete, which means that a row x-lock
should be placed on the cursor row */
- ulint row_lock_mode; /* LOCK_X or LOCK_S */
- ulint n_tables; /* number of tables */
- ulint fetch_table; /* number of the next table to access
+ ulint row_lock_mode; /*!< LOCK_X or LOCK_S */
+ ulint n_tables; /*!< number of tables */
+ ulint fetch_table; /*!< number of the next table to access
in the join */
- plan_t* plans; /* array of n_tables many plan nodes
+ plan_t* plans; /*!< array of n_tables many plan nodes
containing the search plan and the
search data structures */
- que_node_t* search_cond; /* search condition */
- read_view_t* read_view; /* if the query is a non-locking
+ que_node_t* search_cond; /*!< search condition */
+ read_view_t* read_view; /*!< if the query is a non-locking
consistent read, its read view is
placed here, otherwise NULL */
- ibool consistent_read;/* TRUE if the select is a consistent,
+ ibool consistent_read;/*!< TRUE if the select is a consistent,
non-locking read */
- order_node_t* order_by; /* order by column definition, or
+ order_node_t* order_by; /*!< order by column definition, or
NULL */
- ibool is_aggregate; /* TRUE if the select list consists of
+ ibool is_aggregate; /*!< TRUE if the select list consists of
aggregate functions */
ibool aggregate_already_fetched;
- /* TRUE if the aggregate row has
+ /*!< TRUE if the aggregate row has
already been fetched for the current
cursor */
- ibool can_get_updated;/* this is TRUE if the select
+ ibool can_get_updated;/*!< this is TRUE if the select
is in a single-table explicit
cursor which can get updated
within the stored procedure,
@@ -328,31 +340,22 @@ struct sel_node_struct{
checks from a stored procedure
if it contains positioned
update or delete statements */
- sym_node_t* explicit_cursor;/* not NULL if an explicit cursor */
+ sym_node_t* explicit_cursor;/*!< not NULL if an explicit cursor */
UT_LIST_BASE_NODE_T(sym_node_t)
- copy_variables; /* variables whose values we have to
+ copy_variables; /*!< variables whose values we have to
copy when an explicit cursor is opened,
so that they do not change between
fetches */
};
-/* Select node states */
-#define SEL_NODE_CLOSED 0 /* it is a declared cursor which is not
- currently open */
-#define SEL_NODE_OPEN 1 /* intention locks not yet set on
- tables */
-#define SEL_NODE_FETCH 2 /* intention locks have been set */
-#define SEL_NODE_NO_MORE_ROWS 3 /* cursor has reached the result set
- end */
-
-/* Fetch statement node */
+/** Fetch statement node */
struct fetch_node_struct{
- que_common_t common; /* type: QUE_NODE_FETCH */
- sel_node_t* cursor_def; /* cursor definition */
- sym_node_t* into_list; /* variables to set */
+ que_common_t common; /*!< type: QUE_NODE_FETCH */
+ sel_node_t* cursor_def; /*!< cursor definition */
+ sym_node_t* into_list; /*!< variables to set */
pars_user_func_t*
- func; /* User callback function or NULL.
+ func; /*!< User callback function or NULL.
The first argument to the function
is a sel_node_t*, containing the
results of the SELECT operation for
@@ -366,33 +369,42 @@ struct fetch_node_struct{
(and a useful debugging tool). */
};
-/* Open or close cursor statement node */
+/** Open or close cursor operation type */
+enum open_node_op {
+ ROW_SEL_OPEN_CURSOR, /*!< open cursor */
+ ROW_SEL_CLOSE_CURSOR /*!< close cursor */
+};
+
+/** Open or close cursor statement node */
struct open_node_struct{
- que_common_t common; /* type: QUE_NODE_OPEN */
- ulint op_type; /* ROW_SEL_OPEN_CURSOR or
- ROW_SEL_CLOSE_CURSOR */
- sel_node_t* cursor_def; /* cursor definition */
+ que_common_t common; /*!< type: QUE_NODE_OPEN */
+ enum open_node_op
+ op_type; /*!< operation type: open or
+ close cursor */
+ sel_node_t* cursor_def; /*!< cursor definition */
};
-/* Row printf statement node */
+/** Row printf statement node */
struct row_printf_node_struct{
- que_common_t common; /* type: QUE_NODE_ROW_PRINTF */
- sel_node_t* sel_node; /* select */
+ que_common_t common; /*!< type: QUE_NODE_ROW_PRINTF */
+ sel_node_t* sel_node; /*!< select */
};
-#define ROW_SEL_OPEN_CURSOR 0
-#define ROW_SEL_CLOSE_CURSOR 1
-
-/* Flags for the MySQL interface */
-#define ROW_SEL_NEXT 1
-#define ROW_SEL_PREV 2
+/** Search direction for the MySQL interface */
+enum row_sel_direction {
+ ROW_SEL_NEXT = 1, /*!< ascending direction */
+ ROW_SEL_PREV = 2 /*!< descending direction */
+};
-#define ROW_SEL_EXACT 1 /* search using a complete key value */
-#define ROW_SEL_EXACT_PREFIX 2 /* search using a key prefix which
- must match to rows: the prefix may
- contain an incomplete field (the
- last field in prefix may be just
- a prefix of a fixed length column) */
+/** Match mode for the MySQL interface */
+enum row_sel_match_mode {
+ ROW_SEL_EXACT = 1, /*!< search using a complete key value */
+ ROW_SEL_EXACT_PREFIX /*!< search using a key prefix which
+ must match rows: the prefix may
+ contain an incomplete field (the last
+ field in prefix may be just a prefix
+ of a fixed length column) */
+};
#ifndef UNIV_NONINL
#include "row0sel.ic"
diff --git a/storage/xtradb/include/row0sel.ic b/storage/xtradb/include/row0sel.ic
index a21181e3237..5907f9913da 100644
--- a/storage/xtradb/include/row0sel.ic
+++ b/storage/xtradb/include/row0sel.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0sel.ic
Select
Created 12/19/1997 Heikki Tuuri
@@ -24,22 +25,22 @@ Created 12/19/1997 Heikki Tuuri
#include "que0que.h"
-/*************************************************************************
-Gets the plan node for the nth table in a join. */
+/*********************************************************************//**
+Gets the plan node for the nth table in a join.
+@return plan node */
UNIV_INLINE
plan_t*
sel_node_get_nth_plan(
/*==================*/
- /* out: plan node */
- sel_node_t* node, /* in: select node */
- ulint i) /* in: get ith plan node */
+ sel_node_t* node, /*!< in: select node */
+ ulint i) /*!< in: get ith plan node */
{
ut_ad(i < node->n_tables);
return(node->plans + i);
}
-/*************************************************************************
+/*********************************************************************//**
Resets the cursor defined by sel_node to the SEL_NODE_OPEN state, which means
that it will start fetching from the start of the result set again, regardless
of where it was before, and it will set intention locks on the tables. */
@@ -47,19 +48,19 @@ UNIV_INLINE
void
sel_node_reset_cursor(
/*==================*/
- sel_node_t* node) /* in: select node */
+ sel_node_t* node) /*!< in: select node */
{
node->state = SEL_NODE_OPEN;
}
-/**************************************************************************
-Performs an execution step of an open or close cursor statement node. */
+/**********************************************************************//**
+Performs an execution step of an open or close cursor statement node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
open_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
sel_node_t* sel_node;
open_node_t* node;
diff --git a/storage/xtradb/include/row0types.h b/storage/xtradb/include/row0types.h
index f0af7c2bf53..7920fd75061 100644
--- a/storage/xtradb/include/row0types.h
+++ b/storage/xtradb/include/row0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0types.h
Row operation global types
Created 12/27/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/row0uins.h b/storage/xtradb/include/row0uins.h
index 16bbbbd0d12..77b071c3a6b 100644
--- a/storage/xtradb/include/row0uins.h
+++ b/storage/xtradb/include/row0uins.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0uins.h
Fresh insert undo
Created 2/25/1997 Heikki Tuuri
@@ -33,18 +34,18 @@ Created 2/25/1997 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
-/***************************************************************
+/***********************************************************//**
Undoes a fresh insert of a row to a table. A fresh insert means that
the same clustered index unique key did not have any record, even delete
marked, at the time of the insert. InnoDB is eager in a rollback:
if it figures out that an index record will be removed in the purge
-anyway, it will remove it in the rollback. */
+anyway, it will remove it in the rollback.
+@return DB_SUCCESS */
UNIV_INTERN
ulint
row_undo_ins(
/*=========*/
- /* out: DB_SUCCESS */
- undo_node_t* node); /* in: row undo node */
+ undo_node_t* node); /*!< in: row undo node */
#ifndef UNIV_NONINL
#include "row0uins.ic"
diff --git a/storage/xtradb/include/row0uins.ic b/storage/xtradb/include/row0uins.ic
index 75bef8431eb..27606150d8e 100644
--- a/storage/xtradb/include/row0uins.ic
+++ b/storage/xtradb/include/row0uins.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0uins.ic
Fresh insert undo
Created 2/25/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/row0umod.h b/storage/xtradb/include/row0umod.h
index 3a4e8c2f9a3..ed44cc8d601 100644
--- a/storage/xtradb/include/row0umod.h
+++ b/storage/xtradb/include/row0umod.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0umod.h
Undo modify of a row
Created 2/27/1997 Heikki Tuuri
@@ -33,15 +34,15 @@ Created 2/27/1997 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
-/***************************************************************
-Undoes a modify operation on a row of a table. */
+/***********************************************************//**
+Undoes a modify operation on a row of a table.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_undo_mod(
/*=========*/
- /* out: DB_SUCCESS or error code */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr); /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr); /*!< in: query thread */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/row0umod.ic b/storage/xtradb/include/row0umod.ic
index 7ac7bc2fea7..ea3fd3b43c7 100644
--- a/storage/xtradb/include/row0umod.ic
+++ b/storage/xtradb/include/row0umod.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0umod.ic
Undo modify of a row
Created 2/27/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/row0undo.h b/storage/xtradb/include/row0undo.h
index a17cfb1babd..6eb4ca448b3 100644
--- a/storage/xtradb/include/row0undo.h
+++ b/storage/xtradb/include/row0undo.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0undo.h
Row undo
Created 1/8/1997 Heikki Tuuri
@@ -35,38 +36,37 @@ Created 1/8/1997 Heikki Tuuri
#include "que0types.h"
#include "row0types.h"
-/************************************************************************
-Creates a row undo node to a query graph. */
+/********************************************************************//**
+Creates a row undo node to a query graph.
+@return own: undo node */
UNIV_INTERN
undo_node_t*
row_undo_node_create(
/*=================*/
- /* out, own: undo node */
- trx_t* trx, /* in: transaction */
- que_thr_t* parent, /* in: parent node, i.e., a thr node */
- mem_heap_t* heap); /* in: memory heap where created */
-/***************************************************************
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t* parent, /*!< in: parent node, i.e., a thr node */
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/***********************************************************//**
Looks for the clustered index record when node has the row reference.
The pcur in node is used in the search. If found, stores the row to node,
and stores the position of pcur, and detaches it. The pcur must be closed
-by the caller in any case. */
+by the caller in any case.
+@return TRUE if found; NOTE the node->pcur must be closed by the
+caller, regardless of the return value */
UNIV_INTERN
ibool
row_undo_search_clust_to_pcur(
/*==========================*/
- /* out: TRUE if found; NOTE the node->pcur
- must be closed by the caller, regardless of
- the return value */
- undo_node_t* node); /* in: row undo node */
-/***************************************************************
+ undo_node_t* node); /*!< in: row undo node */
+/***********************************************************//**
Undoes a row operation in a table. This is a high-level function used
-in SQL execution graphs. */
+in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_undo_step(
/*==========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
/* A single query thread will try to perform the undo for all successive
versions of a clustered index record, if the transaction has modified it
@@ -83,51 +83,57 @@ just in the case where the transaction modified the same record several times
and another thread is currently doing the undo for successive versions of
that index record. */
-/* Undo node structure */
+/** Execution state of an undo node */
+enum undo_exec {
+ UNDO_NODE_FETCH_NEXT = 1, /*!< we should fetch the next
+ undo log record */
+ UNDO_NODE_PREV_VERS, /*!< the roll ptr to previous
+ version of a row is stored in
+ node, and undo should be done
+ based on it */
+ UNDO_NODE_INSERT, /*!< undo a fresh insert of a
+ row to a table */
+ UNDO_NODE_MODIFY /*!< undo a modify operation
+ (DELETE or UPDATE) on a row
+ of a table */
+};
+/** Undo node structure */
struct undo_node_struct{
- que_common_t common; /* node type: QUE_NODE_UNDO */
- ulint state; /* node execution state */
- trx_t* trx; /* trx for which undo is done */
- dulint roll_ptr;/* roll pointer to undo log record */
- trx_undo_rec_t* undo_rec;/* undo log record */
- dulint undo_no;/* undo number of the record */
- ulint rec_type;/* undo log record type: TRX_UNDO_INSERT_REC,
+ que_common_t common; /*!< node type: QUE_NODE_UNDO */
+ enum undo_exec state; /*!< node execution state */
+ trx_t* trx; /*!< trx for which undo is done */
+ roll_ptr_t roll_ptr;/*!< roll pointer to undo log record */
+ trx_undo_rec_t* undo_rec;/*!< undo log record */
+ undo_no_t undo_no;/*!< undo number of the record */
+ ulint rec_type;/*!< undo log record type: TRX_UNDO_INSERT_REC,
... */
- dulint new_roll_ptr; /* roll ptr to restore to clustered index
+ roll_ptr_t new_roll_ptr;
+ /*!< roll ptr to restore to clustered index
record */
- dulint new_trx_id; /* trx id to restore to clustered index
+ trx_id_t new_trx_id; /*!< trx id to restore to clustered index
record */
- btr_pcur_t pcur; /* persistent cursor used in searching the
+ btr_pcur_t pcur; /*!< persistent cursor used in searching the
clustered index record */
- dict_table_t* table; /* table where undo is done */
- ulint cmpl_info;/* compiler analysis of an update */
- upd_t* update; /* update vector for a clustered index
+ dict_table_t* table; /*!< table where undo is done */
+ ulint cmpl_info;/*!< compiler analysis of an update */
+ upd_t* update; /*!< update vector for a clustered index
record */
- dtuple_t* ref; /* row reference to the next row to handle */
- dtuple_t* row; /* a copy (also fields copied to heap) of the
+ dtuple_t* ref; /*!< row reference to the next row to handle */
+ dtuple_t* row; /*!< a copy (also fields copied to heap) of the
row to handle */
- row_ext_t* ext; /* NULL, or prefixes of the externally
+ row_ext_t* ext; /*!< NULL, or prefixes of the externally
stored columns of the row */
- dtuple_t* undo_row;/* NULL, or the row after undo */
- row_ext_t* undo_ext;/* NULL, or prefixes of the externally
+ dtuple_t* undo_row;/*!< NULL, or the row after undo */
+ row_ext_t* undo_ext;/*!< NULL, or prefixes of the externally
stored columns of undo_row */
- dict_index_t* index; /* the next index whose record should be
+ dict_index_t* index; /*!< the next index whose record should be
handled */
- mem_heap_t* heap; /* memory heap used as auxiliary storage for
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage for
row; this must be emptied after undo is tried
on a row */
};
-/* Execution states for an undo node */
-#define UNDO_NODE_FETCH_NEXT 1 /* we should fetch the next undo log
- record */
-#define UNDO_NODE_PREV_VERS 2 /* the roll ptr to previous version of
- a row is stored in node, and undo
- should be done based on it */
-#define UNDO_NODE_INSERT 3
-#define UNDO_NODE_MODIFY 4
-
#ifndef UNIV_NONINL
#include "row0undo.ic"
diff --git a/storage/xtradb/include/row0undo.ic b/storage/xtradb/include/row0undo.ic
index 921e3633b10..dc788debc14 100644
--- a/storage/xtradb/include/row0undo.ic
+++ b/storage/xtradb/include/row0undo.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0undo.ic
Row undo
Created 1/8/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/row0upd.h b/storage/xtradb/include/row0upd.h
index 71aa20d158c..635d746d5a1 100644
--- a/storage/xtradb/include/row0upd.h
+++ b/storage/xtradb/include/row0upd.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0upd.h
Update of a row
Created 12/27/1996 Heikki Tuuri
@@ -27,355 +28,360 @@ Created 12/27/1996 Heikki Tuuri
#include "univ.i"
#include "data0data.h"
+#include "row0types.h"
#include "btr0types.h"
-#include "btr0pcur.h"
#include "dict0types.h"
#include "trx0types.h"
-#include "que0types.h"
-#include "row0types.h"
-#include "pars0types.h"
-/*************************************************************************
-Creates an update vector object. */
+#ifndef UNIV_HOTBACKUP
+# include "btr0pcur.h"
+# include "que0types.h"
+# include "pars0types.h"
+#endif /* !UNIV_HOTBACKUP */
+
+/*********************************************************************//**
+Creates an update vector object.
+@return own: update vector object */
UNIV_INLINE
upd_t*
upd_create(
/*=======*/
- /* out, own: update vector object */
- ulint n, /* in: number of fields */
- mem_heap_t* heap); /* in: heap from which memory allocated */
-/*************************************************************************
+ ulint n, /*!< in: number of fields */
+ mem_heap_t* heap); /*!< in: heap from which memory allocated */
+/*********************************************************************//**
Returns the number of fields in the update vector == number of columns
-to be updated by an update vector. */
+to be updated by an update vector.
+@return number of fields */
UNIV_INLINE
ulint
upd_get_n_fields(
/*=============*/
- /* out: number of fields */
- const upd_t* update); /* in: update vector */
+ const upd_t* update); /*!< in: update vector */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Returns the nth field of an update vector. */
+/*********************************************************************//**
+Returns the nth field of an update vector.
+@return update vector field */
UNIV_INLINE
upd_field_t*
upd_get_nth_field(
/*==============*/
- /* out: update vector field */
- const upd_t* update, /* in: update vector */
- ulint n); /* in: field position in update vector */
+ const upd_t* update, /*!< in: update vector */
+ ulint n); /*!< in: field position in update vector */
#else
# define upd_get_nth_field(update, n) ((update)->fields + (n))
#endif
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Sets an index field number to be updated by an update vector field. */
UNIV_INLINE
void
upd_field_set_field_no(
/*===================*/
- upd_field_t* upd_field, /* in: update vector field */
- ulint field_no, /* in: field number in a clustered
+ upd_field_t* upd_field, /*!< in: update vector field */
+ ulint field_no, /*!< in: field number in a clustered
index */
- dict_index_t* index, /* in: index */
- trx_t* trx); /* in: transaction */
-/*************************************************************************
-Returns a field of an update vector by field_no. */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx); /*!< in: transaction */
+/*********************************************************************//**
+Returns a field of an update vector by field_no.
+@return update vector field, or NULL */
UNIV_INLINE
const upd_field_t*
upd_get_field_by_field_no(
/*======================*/
- /* out: update vector field, or NULL */
- const upd_t* update, /* in: update vector */
- ulint no) /* in: field_no */
+ const upd_t* update, /*!< in: update vector */
+ ulint no) /*!< in: field_no */
__attribute__((nonnull, pure));
-/*************************************************************************
+/*********************************************************************//**
Writes into the redo log the values of trx id and roll ptr and enough info
-to determine their positions within a clustered index record. */
+to determine their positions within a clustered index record.
+@return new pointer to mlog */
UNIV_INTERN
byte*
row_upd_write_sys_vals_to_log(
/*==========================*/
- /* out: new pointer to mlog */
- dict_index_t* index, /* in: clustered index */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr,/* in: roll ptr of the undo log record */
- byte* log_ptr,/* pointer to a buffer of size > 20 opened
+ dict_index_t* index, /*!< in: clustered index */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr,/*!< in: roll ptr of the undo log record */
+ byte* log_ptr,/*!< pointer to a buffer of size > 20 opened
in mlog */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************************//**
Updates the trx id and roll ptr field in a clustered index record when
a row is updated or marked deleted. */
UNIV_INLINE
void
row_upd_rec_sys_fields(
/*===================*/
- rec_t* rec, /* in/out: record */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ rec_t* rec, /*!< in/out: record */
+ 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) */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr);/* in: roll ptr of the undo log record */
-/*************************************************************************
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record */
+/*********************************************************************//**
Sets the trx id or roll ptr field of a clustered index entry. */
UNIV_INTERN
void
row_upd_index_entry_sys_field(
/*==========================*/
- const dtuple_t* entry, /* in: index entry, where the memory buffers
+ const dtuple_t* entry, /*!< in: index entry, where the memory buffers
for sys fields are already allocated:
the function just copies the new values to
them */
- dict_index_t* index, /* in: clustered index */
- ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
- dulint val); /* in: value to write */
-/*************************************************************************
-Creates an update node for a query graph. */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint type, /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */
+ dulint val); /*!< in: value to write */
+/*********************************************************************//**
+Creates an update node for a query graph.
+@return own: update node */
UNIV_INTERN
upd_node_t*
upd_node_create(
/*============*/
- /* out, own: update node */
- mem_heap_t* heap); /* in: mem heap where created */
-/***************************************************************
+ mem_heap_t* heap); /*!< in: mem heap where created */
+/***********************************************************//**
Writes to the redo log the new values of the fields occurring in the index. */
UNIV_INTERN
void
row_upd_index_write_log(
/*====================*/
- const upd_t* update, /* in: update vector */
- byte* log_ptr,/* in: pointer to mlog buffer: must
+ const upd_t* update, /*!< in: update vector */
+ byte* log_ptr,/*!< in: pointer to mlog buffer: must
contain at least MLOG_BUF_MARGIN bytes
of free space; the buffer is closed
within this function */
- mtr_t* mtr); /* in: mtr into whose log to write */
-/***************************************************************
+ mtr_t* mtr); /*!< in: mtr into whose log to write */
+/***********************************************************//**
Returns TRUE if row update changes size of some field in index or if some
-field to be updated is stored externally in rec or update. */
+field to be updated is stored externally in rec or update.
+@return TRUE if the update changes the size of some field in index or
+the field is external in rec or update */
UNIV_INTERN
ibool
row_upd_changes_field_size_or_external(
/*===================================*/
- /* out: TRUE if the update changes the size of
- some field in index or the field is external
- in rec or update */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- const upd_t* update);/* in: update vector */
-/***************************************************************
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update);/*!< in: update vector */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
Replaces the new column values stored in the update vector to the record
given. No field size changes are allowed. */
UNIV_INTERN
void
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 upd_t* update, /* in: update vector */
- page_zip_des_t* page_zip);/* in: compressed page with enough space
+ 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 upd_t* update, /*!< in: update vector */
+ page_zip_des_t* page_zip);/*!< in: compressed page with enough space
available, or NULL */
-/*******************************************************************
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Builds an update vector from those fields which in a secondary index entry
differ from a record that has the equal ordering fields. NOTE: we compare
-the fields as binary strings! */
+the fields as binary strings!
+@return own: update vector of differing fields */
UNIV_INTERN
upd_t*
row_upd_build_sec_rec_difference_binary(
/*====================================*/
- /* out, own: update vector of differing
- fields */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: entry to insert */
- const rec_t* rec, /* in: secondary index record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap); /* in: memory heap from which allocated */
-/*******************************************************************
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ const rec_t* rec, /*!< in: secondary index record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap); /*!< in: memory heap from which allocated */
+/***************************************************************//**
Builds an update vector from those fields, excluding the roll ptr and
trx id fields, which in an index entry differ from a record that has
-the equal ordering fields. NOTE: we compare the fields as binary strings! */
+the equal ordering fields. NOTE: we compare the fields as binary strings!
+@return own: update vector of differing fields, excluding roll ptr and
+trx id */
UNIV_INTERN
upd_t*
row_upd_build_difference_binary(
/*============================*/
- /* out, own: update vector of differing
- fields, excluding roll ptr and trx id */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* entry, /* in: entry to insert */
- const rec_t* rec, /* in: clustered index record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap); /* in: memory heap from which allocated */
-/***************************************************************
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ const rec_t* rec, /*!< in: clustered index record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap); /*!< in: memory heap from which allocated */
+/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
UNIV_INTERN
void
row_upd_index_replace_new_col_vals_index_pos(
/*=========================================*/
- dtuple_t* entry, /* in/out: index entry where replaced;
+ 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
+ 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 index so
+ const upd_t* update, /*!< in: an update vector built for the index so
that the field number in an upd_field is the
index position */
ibool order_only,
- /* in: if TRUE, limit the replacement to
+ /*!< in: if TRUE, limit the replacement to
ordering fields of index; note that this
does not work for non-clustered indexes. */
- mem_heap_t* heap) /* in: memory heap for allocating and
+ mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
__attribute__((nonnull));
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
UNIV_INTERN
void
row_upd_index_replace_new_col_vals(
/*===============================*/
- dtuple_t* entry, /* in/out: index entry where replaced;
+ 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
+ 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
+ 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
+ mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
__attribute__((nonnull));
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector. */
UNIV_INTERN
void
row_upd_replace(
/*============*/
- dtuple_t* row, /* in/out: row where replaced,
+ dtuple_t* row, /*!< in/out: row where replaced,
indexed by col_no;
the clustered index record must be
covered by a lock or a page latch to
prevent deletion (rollback or purge) */
- row_ext_t** ext, /* out, own: NULL, or externally
+ row_ext_t** ext, /*!< out, own: NULL, or externally
stored column prefixes */
- const dict_index_t* index, /* in: clustered index */
- const upd_t* update, /* in: an update vector built for the
+ const dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: an update vector built for the
clustered index */
- mem_heap_t* heap); /* in: memory heap */
-/***************************************************************
+ mem_heap_t* heap); /*!< in: memory heap */
+/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
+
This function is fast if the update vector is short or the number of ordering
fields in the index is small. Otherwise, this can be quadratic.
-NOTE: we compare the fields as binary strings! */
+NOTE: we compare the fields as binary strings!
+@return TRUE if update vector changes an ordering field in the index record */
UNIV_INTERN
ibool
row_upd_changes_ord_field_binary(
/*=============================*/
- /* out: TRUE if update vector changes
- an ordering field in the index record;
- NOTE: the fields are compared as binary
- strings */
- const dtuple_t* row, /* in: old value of row, or NULL if the
+ const dtuple_t* row, /*!< in: old value of row, or NULL if the
row and the data values in update are not
known when this function is called, e.g., at
compile time */
- dict_index_t* index, /* in: index of the record */
- const upd_t* update);/* in: update vector for the row; NOTE: the
+ dict_index_t* index, /*!< in: index of the record */
+ const upd_t* update);/*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
-/***************************************************************
+/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering
fields in the index is small. Otherwise, this can be quadratic.
-NOTE: we compare the fields as binary strings! */
+NOTE: we compare the fields as binary strings!
+@return TRUE if update vector may change an ordering field in an index
+record */
UNIV_INTERN
ibool
row_upd_changes_some_index_ord_field_binary(
/*========================================*/
- /* out: TRUE if update vector
- may change an ordering field
- in an index record */
- const dict_table_t* table, /* in: table */
- const upd_t* update);/* in: update vector for the row */
-/***************************************************************
+ const dict_table_t* table, /*!< in: table */
+ const upd_t* update);/*!< in: update vector for the row */
+/***********************************************************//**
Updates a row in a table. This is a high-level function used
-in SQL execution graphs. */
+in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_upd_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
-Parses the log data of system field values. */
+ que_thr_t* thr); /*!< in: query thread */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Parses the log data of system field values.
+@return log data end or NULL */
UNIV_INTERN
byte*
row_upd_parse_sys_vals(
/*===================*/
- /* out: log data end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint* pos, /* out: TRX_ID position in record */
- dulint* trx_id, /* out: trx id */
- dulint* roll_ptr);/* out: roll ptr */
-/*************************************************************************
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint* pos, /*!< out: TRX_ID position in record */
+ trx_id_t* trx_id, /*!< out: trx id */
+ roll_ptr_t* roll_ptr);/*!< out: roll ptr */
+/*********************************************************************//**
Updates the trx id and roll ptr field in a clustered index record in database
recovery. */
UNIV_INTERN
void
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() */
- ulint pos, /* in: TRX_ID position in rec */
- dulint trx_id, /* in: transaction id */
- dulint roll_ptr);/* in: roll ptr of the undo log record */
-/*************************************************************************
-Parses the log data written by row_upd_index_write_log. */
+ 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() */
+ 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 */
+/*********************************************************************//**
+Parses the log data written by row_upd_index_write_log.
+@return log data end or NULL */
UNIV_INTERN
byte*
row_upd_index_parse(
/*================*/
- /* out: log data end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- mem_heap_t* heap, /* in: memory heap where update vector is
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ mem_heap_t* heap, /*!< in: memory heap where update vector is
built */
- upd_t** update_out);/* out: update vector */
+ upd_t** update_out);/*!< out: update vector */
/* Update vector field */
struct upd_field_struct{
- unsigned field_no:16; /* field number in an index, usually
+ unsigned field_no:16; /*!< field number in an index, usually
the clustered index, but in updating
a secondary index record in btr0cur.c
this is the position in the secondary
index */
- unsigned orig_len:16; /* original length of the locally
+#ifndef UNIV_HOTBACKUP
+ unsigned orig_len:16; /*!< original length of the locally
stored part of an externally stored
column, or 0 */
- que_node_t* exp; /* expression for calculating a new
+ que_node_t* exp; /*!< expression for calculating a new
value: it refers to column values and
constants in the symbol table of the
query graph */
- dfield_t new_val; /* new value for the column */
+#endif /* !UNIV_HOTBACKUP */
+ dfield_t new_val; /*!< new value for the column */
};
/* Update vector structure */
struct upd_struct{
- ulint info_bits; /* new value of info bits to record;
+ ulint info_bits; /*!< new value of info bits to record;
default is 0 */
- ulint n_fields; /* number of update fields */
- upd_field_t* fields; /* array of update fields */
+ ulint n_fields; /*!< number of update fields */
+ upd_field_t* fields; /*!< array of update fields */
};
+#ifndef UNIV_HOTBACKUP
/* Update node structure which also implements the delete operation
of a row */
struct upd_node_struct{
- que_common_t common; /* node type: QUE_NODE_UPDATE */
+ que_common_t common; /*!< node type: QUE_NODE_UPDATE */
ibool is_delete;/* TRUE if delete, FALSE if update */
ibool searched_update;
/* TRUE if searched update, FALSE if
@@ -391,16 +397,16 @@ struct upd_node_struct{
or ... SET NULL for foreign keys */
mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade
node is created */
- sel_node_t* select; /* query graph subtree implementing a base
+ sel_node_t* select; /*!< query graph subtree implementing a base
table cursor: the rows returned will be
updated */
- btr_pcur_t* pcur; /* persistent cursor placed on the clustered
+ btr_pcur_t* pcur; /*!< persistent cursor placed on the clustered
index record which should be updated or
deleted; the cursor is stored in the graph
of 'select' field above, except in the case
of the MySQL interface */
- dict_table_t* table; /* table where updated */
- upd_t* update; /* update vector for the row */
+ dict_table_t* table; /*!< table where updated */
+ upd_t* update; /*!< update vector for the row */
ulint update_n_fields;
/* when this struct is used to implement
a cascade operation for foreign keys, we store
@@ -419,18 +425,18 @@ struct upd_node_struct{
UPD_NODE_NO_SIZE_CHANGE, ORed */
/*----------------------*/
/* Local storage for this graph node */
- ulint state; /* node execution state */
- dict_index_t* index; /* NULL, or the next index whose record should
+ ulint state; /*!< node execution state */
+ dict_index_t* index; /*!< NULL, or the next index whose record should
be updated */
- dtuple_t* row; /* NULL, or a copy (also fields copied to
+ dtuple_t* row; /*!< NULL, or a copy (also fields copied to
heap) of the row to update; this must be reset
to NULL after a successful update */
- row_ext_t* ext; /* NULL, or prefixes of the externally
+ row_ext_t* ext; /*!< NULL, or prefixes of the externally
stored columns in the old row */
dtuple_t* upd_row;/* NULL, or a copy of the updated row */
row_ext_t* upd_ext;/* NULL, or prefixes of the externally
stored columns in upd_row */
- mem_heap_t* heap; /* memory heap used as auxiliary storage;
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage;
this must be emptied after a successful
update */
/*----------------------*/
@@ -468,6 +474,8 @@ struct upd_node_struct{
#define UPD_NODE_NO_SIZE_CHANGE 2 /* no record field size will be
changed in the update */
+#endif /* !UNIV_HOTBACKUP */
+
#ifndef UNIV_NONINL
#include "row0upd.ic"
#endif
diff --git a/storage/xtradb/include/row0upd.ic b/storage/xtradb/include/row0upd.ic
index a0c23aa6b07..18e22f1eca9 100644
--- a/storage/xtradb/include/row0upd.ic
+++ b/storage/xtradb/include/row0upd.ic
@@ -16,28 +16,31 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0upd.ic
Update of a row
Created 12/27/1996 Heikki Tuuri
*******************************************************/
#include "mtr0log.h"
-#include "trx0trx.h"
-#include "trx0undo.h"
-#include "row0row.h"
-#include "btr0sea.h"
+#ifndef UNIV_HOTBACKUP
+# include "trx0trx.h"
+# include "trx0undo.h"
+# include "row0row.h"
+# include "btr0sea.h"
+#endif /* !UNIV_HOTBACKUP */
#include "page0zip.h"
-/*************************************************************************
-Creates an update vector object. */
+/*********************************************************************//**
+Creates an update vector object.
+@return own: update vector object */
UNIV_INLINE
upd_t*
upd_create(
/*=======*/
- /* out, own: update vector object */
- ulint n, /* in: number of fields */
- mem_heap_t* heap) /* in: heap from which memory allocated */
+ ulint n, /*!< in: number of fields */
+ mem_heap_t* heap) /*!< in: heap from which memory allocated */
{
upd_t* update;
@@ -51,15 +54,15 @@ upd_create(
return(update);
}
-/*************************************************************************
+/*********************************************************************//**
Returns the number of fields in the update vector == number of columns
-to be updated by an update vector. */
+to be updated by an update vector.
+@return number of fields */
UNIV_INLINE
ulint
upd_get_n_fields(
/*=============*/
- /* out: number of fields */
- const upd_t* update) /* in: update vector */
+ const upd_t* update) /*!< in: update vector */
{
ut_ad(update);
@@ -67,15 +70,15 @@ upd_get_n_fields(
}
#ifdef UNIV_DEBUG
-/*************************************************************************
-Returns the nth field of an update vector. */
+/*********************************************************************//**
+Returns the nth field of an update vector.
+@return update vector field */
UNIV_INLINE
upd_field_t*
upd_get_nth_field(
/*==============*/
- /* out: update vector field */
- const upd_t* update, /* in: update vector */
- ulint n) /* in: field position in update vector */
+ const upd_t* update, /*!< in: update vector */
+ ulint n) /*!< in: field position in update vector */
{
ut_ad(update);
ut_ad(n < update->n_fields);
@@ -84,17 +87,18 @@ upd_get_nth_field(
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Sets an index field number to be updated by an update vector field. */
UNIV_INLINE
void
upd_field_set_field_no(
/*===================*/
- upd_field_t* upd_field, /* in: update vector field */
- ulint field_no, /* in: field number in a clustered
+ upd_field_t* upd_field, /*!< in: update vector field */
+ ulint field_no, /*!< in: field number in a clustered
index */
- dict_index_t* index, /* in: index */
- trx_t* trx) /* in: transaction */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx) /*!< in: transaction */
{
upd_field->field_no = field_no;
upd_field->orig_len = 0;
@@ -113,15 +117,15 @@ upd_field_set_field_no(
dfield_get_type(&upd_field->new_val));
}
-/*************************************************************************
-Returns a field of an update vector by field_no. */
+/*********************************************************************//**
+Returns a field of an update vector by field_no.
+@return update vector field, or NULL */
UNIV_INLINE
const upd_field_t*
upd_get_field_by_field_no(
/*======================*/
- /* out: update vector field, or NULL */
- const upd_t* update, /* in: update vector */
- ulint no) /* in: field_no */
+ const upd_t* update, /*!< in: update vector */
+ ulint no) /*!< in: field_no */
{
ulint i;
for (i = 0; i < upd_get_n_fields(update); i++) {
@@ -136,20 +140,20 @@ upd_get_field_by_field_no(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the trx id and roll ptr field in a clustered index record when
a row is updated or marked deleted. */
UNIV_INLINE
void
row_upd_rec_sys_fields(
/*===================*/
- rec_t* rec, /* in/out: record */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ rec_t* rec, /*!< in/out: record */
+ 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) */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr)/* in: roll ptr of the undo log record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr)/*!< in: roll ptr of the undo log record */
{
ut_ad(dict_index_is_clust(index));
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -177,3 +181,4 @@ row_upd_rec_sys_fields(
trx_write_roll_ptr(rec + offset + DATA_TRX_ID_LEN, roll_ptr);
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/row0vers.h b/storage/xtradb/include/row0vers.h
index 0feae77e8b5..5a2e38230d5 100644
--- a/storage/xtradb/include/row0vers.h
+++ b/storage/xtradb/include/row0vers.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0vers.h
Row versions
Created 2/6/1997 Heikki Tuuri
@@ -34,103 +35,102 @@ Created 2/6/1997 Heikki Tuuri
#include "mtr0mtr.h"
#include "read0types.h"
-/*********************************************************************
+/*****************************************************************//**
Finds out if an active transaction has inserted or modified a secondary
index record. NOTE: the kernel mutex is temporarily released in this
-function! */
+function!
+@return NULL if committed, else the active transaction */
UNIV_INTERN
trx_t*
row_vers_impl_x_locked_off_kernel(
/*==============================*/
- /* out: NULL if committed, else the active
- transaction; NOTE that the kernel mutex is
- temporarily released! */
- const rec_t* rec, /* in: record in a secondary index */
- dict_index_t* index, /* in: the secondary index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*********************************************************************
+ const rec_t* rec, /*!< in: record in a secondary index */
+ dict_index_t* index, /*!< in: the secondary index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*****************************************************************//**
Finds out if we must preserve a delete marked earlier version of a clustered
-index record, because it is >= the purge view. */
+index record, because it is >= the purge view.
+@return TRUE if earlier version should be preserved */
UNIV_INTERN
ibool
row_vers_must_preserve_del_marked(
/*==============================*/
- /* out: TRUE if earlier version should be preserved */
- dulint trx_id, /* in: transaction id in the version */
- mtr_t* mtr); /* in: mtr holding the latch on the clustered index
- record; it will also hold the latch on purge_view */
-/*********************************************************************
+ trx_id_t trx_id, /*!< in: transaction id in the version */
+ mtr_t* mtr); /*!< in: mtr holding the latch on the
+ clustered index record; it will also
+ hold the latch on purge_view */
+/*****************************************************************//**
Finds out if a version of the record, where the version >= the current
purge view, should have ientry as its secondary index entry. We check
if there is any not delete marked version of the record where the trx
id >= purge view, and the secondary index entry == ientry; exactly in
-this case we return TRUE. */
+this case we return TRUE.
+@return TRUE if earlier version should have */
UNIV_INTERN
ibool
row_vers_old_has_index_entry(
/*=========================*/
- /* out: TRUE if earlier version should have */
- ibool also_curr,/* in: TRUE if also rec is included in the
+ ibool also_curr,/*!< in: TRUE if also rec is included in the
versions to search; otherwise only versions
prior to it are searched */
- const rec_t* rec, /* in: record in the clustered index; the
+ const rec_t* rec, /*!< in: record in the clustered index; the
caller must have a latch on the page */
- mtr_t* mtr, /* in: mtr holding the latch on rec; it will
+ 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 secondary index */
- const dtuple_t* ientry);/* in: the secondary index entry */
-/*********************************************************************
+ dict_index_t* index, /*!< in: the secondary index */
+ const dtuple_t* ientry);/*!< in: the secondary index entry */
+/*****************************************************************//**
Constructs the version of a clustered index record which a consistent
read should see. We assume that the trx id stored in rec is such that
-the consistent read should not see rec in its present version. */
+the consistent read should not see rec in its present version.
+@return DB_SUCCESS or DB_MISSING_HISTORY */
UNIV_INTERN
ulint
row_vers_build_for_consistent_read(
/*===============================*/
- /* out: DB_SUCCESS or DB_MISSING_HISTORY */
- const rec_t* rec, /* in: record in a clustered index; the
+ const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
of this records */
- mtr_t* mtr, /* in: mtr holding the latch on rec; it will
+ 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
+ dict_index_t* index, /*!< in: the clustered index */
+ ulint** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
- read_view_t* view, /* in: the consistent read view */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ read_view_t* view, /*!< in: the consistent read view */
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ mem_heap_t* in_heap,/*!< in: memory heap from which the memory for
*old_vers is allocated; memory for possible
intermediate versions is allocated and freed
locally within the function */
- rec_t** old_vers);/* out, own: old version, or NULL if the
+ rec_t** old_vers);/*!< out, own: old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
-/*********************************************************************
+/*****************************************************************//**
Constructs the last committed version of a clustered index record,
-which should be seen by a semi-consistent read. */
+which should be seen by a semi-consistent read.
+@return DB_SUCCESS or DB_MISSING_HISTORY */
UNIV_INTERN
ulint
row_vers_build_for_semi_consistent_read(
/*====================================*/
- /* out: DB_SUCCESS or DB_MISSING_HISTORY */
- const rec_t* rec, /* in: record in a clustered index; the
+ const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
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
+ 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_get_offsets(rec, index) */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ mem_heap_t* in_heap,/*!< in: memory heap from which the memory for
*old_vers is allocated; memory for possible
intermediate versions is allocated and freed
locally within the function */
- const rec_t** old_vers);/* out: rec, old version, or NULL if the
+ const rec_t** old_vers);/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
diff --git a/storage/xtradb/include/row0vers.ic b/storage/xtradb/include/row0vers.ic
index aac95ea6593..8bb3a5c0cb3 100644
--- a/storage/xtradb/include/row0vers.ic
+++ b/storage/xtradb/include/row0vers.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0vers.ic
Row versions
Created 2/6/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/srv0que.h b/storage/xtradb/include/srv0que.h
index 88db1a013f6..82ee7739ef7 100644
--- a/storage/xtradb/include/srv0que.h
+++ b/storage/xtradb/include/srv0que.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/srv0que.h
Server query execution
Created 6/5/1996 Heikki Tuuri
@@ -28,41 +29,14 @@ Created 6/5/1996 Heikki Tuuri
#include "univ.i"
#include "que0types.h"
-/**************************************************************************
-Checks if there is work to do in the server task queue. If there is, the
-thread starts processing a task. Before leaving, it again checks the task
-queue and picks a new task if any exists. This is called by a SRV_WORKER
-thread. */
-UNIV_INTERN
-void
-srv_que_task_queue_check(void);
-/*==========================*/
-/**************************************************************************
-Performs round-robin on the server tasks. This is called by a SRV_WORKER
-thread every second or so. */
-UNIV_INTERN
-que_thr_t*
-srv_que_round_robin(
-/*================*/
- /* out: the new (may be == thr) query thread
- to run */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Enqueues a task to server task queue and releases a worker thread, if
-there exists one suspended. */
-UNIV_INTERN
-void
-srv_que_task_enqueue(
-/*=================*/
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Enqueues a task to server task queue and releases a worker thread, if
-there exists one suspended. */
+/**********************************************************************//**
+Enqueues a task to server task queue and releases a worker thread, if there
+is a suspended one. */
UNIV_INTERN
void
srv_que_task_enqueue_low(
/*=====================*/
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
#endif
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 6e5e955f9a5..dc136d89b8c 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,8 +22,35 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free 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
-/******************************************************
+***********************************************************************/
+
+/**************************************************//**
+@file include/srv0srv.h
The server main program
Created 10/10/1995 Heikki Tuuri
@@ -33,6 +60,7 @@ Created 10/10/1995 Heikki Tuuri
#define srv0srv_h
#include "univ.i"
+#ifndef UNIV_HOTBACKUP
#include "sync0sync.h"
#include "os0sync.h"
#include "que0types.h"
@@ -40,7 +68,7 @@ Created 10/10/1995 Heikki Tuuri
extern const char* srv_main_thread_op_info;
-/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
+/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
extern const char srv_mysql50_table_name_prefix[9];
/* When this event is set the lock timeout and InnoDB monitor
@@ -52,6 +80,9 @@ at a time */
#define SRV_AUTO_EXTEND_INCREMENT \
(srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
+/* prototypes for new functions added to ha_innodb.cc */
+ibool innobase_get_slow_log();
+
/* This is set to TRUE if the MySQL user has set it in MySQL */
extern ibool srv_lower_case_table_names;
@@ -79,16 +110,23 @@ extern char* srv_data_home;
extern char* srv_arch_dir;
#endif /* UNIV_LOG_ARCHIVE */
-/* store to its own file each table created by an user; data
+/** store to its own file each table created by an user; data
dictionary tables are in the system tablespace 0 */
+#ifndef UNIV_HOTBACKUP
extern my_bool srv_file_per_table;
-/* The file format to use on new *.ibd files. */
+#else
+extern ibool srv_file_per_table;
+#endif /* UNIV_HOTBACKUP */
+/** The file format to use on new *.ibd files. */
extern ulint srv_file_format;
-/* Whether to check file format during startup.*/
+/** Whether to check file format during startup. A value of
+DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to
+set it to the highest format we support. */
extern ulint srv_check_file_format_at_startup;
-/* Place locks to records only i.e. do not use next-key locking except
+/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
extern ibool srv_locks_unsafe_for_binlog;
+#endif /* !UNIV_HOTBACKUP */
extern ulint srv_n_data_files;
extern char** srv_data_file_names;
@@ -98,23 +136,25 @@ extern ulint* srv_data_file_is_raw_partition;
extern ibool srv_extra_undoslots;
extern ibool srv_fast_recovery;
+extern ibool srv_recovery_stats;
+
+extern ulint srv_use_purge_thread;
extern ibool srv_auto_extend_last_data_file;
extern ulint srv_last_file_size_max;
+extern char** srv_log_group_home_dirs;
+#ifndef UNIV_HOTBACKUP
extern ulong srv_auto_extend_increment;
extern ibool srv_created_new_raw;
-#define SRV_NEW_RAW 1
-#define SRV_OLD_RAW 2
-
-extern char** srv_log_group_home_dirs;
-
extern ulint srv_n_log_groups;
extern ulint srv_n_log_files;
extern ulint srv_log_file_size;
extern ulint srv_log_buffer_size;
extern ulong srv_flush_log_at_trx_commit;
+extern char srv_adaptive_flushing;
+
extern ulong srv_show_locks_held;
extern ulong srv_show_verbose_locks;
@@ -122,19 +162,31 @@ extern ulong srv_show_verbose_locks;
/* The sort order table of the MySQL latin1_swedish_ci character set
collation */
extern const byte* srv_latin1_ordering;
+#ifndef UNIV_HOTBACKUP
extern my_bool srv_use_sys_malloc;
-extern ulint srv_buf_pool_size; /* requested size in bytes */
-extern ulint srv_buf_pool_old_size; /* previously requested size */
-extern ulint srv_buf_pool_curr_size; /* current size in bytes */
+#else
+extern ibool srv_use_sys_malloc;
+#endif /* UNIV_HOTBACKUP */
+extern ulint srv_buf_pool_size; /*!< requested size in bytes */
+extern ulint srv_buf_pool_old_size; /*!< previously requested size */
+extern ulint srv_buf_pool_curr_size; /*!< current size in bytes */
extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size;
extern ibool srv_thread_concurrency_timer_based;
extern ulint srv_n_file_io_threads;
+extern ulong srv_read_ahead_threshold;
extern ulint srv_n_read_io_threads;
extern ulint srv_n_write_io_threads;
+/* Number of IO operations per second the server can do */
+extern ulong srv_io_capacity;
+/* Returns the number of IO operations that is X percent of the
+capacity. PCT_IO(5) -> returns the number of IO operations that
+is 5% of the max where max is srv_io_capacity. */
+#define PCT_IO(p) ((ulong) (srv_io_capacity * ((double) p / 100.0)))
+
#ifdef UNIV_LOG_ARCHIVE
extern ibool srv_log_archive_on;
extern ibool srv_archive_recovery;
@@ -171,6 +223,7 @@ extern ulong srv_stats_method;
#define SRV_STATS_METHOD_NULLS_NOT_EQUAL 1
#define SRV_STATS_METHOD_IGNORE_NULLS 2
extern ulong srv_stats_auto_update;
+extern ulint srv_stats_update_need_lock;
extern ibool srv_use_doublewrite_buf;
extern ibool srv_use_checksums;
@@ -183,16 +236,17 @@ extern ulong srv_max_purge_lag;
extern ulong srv_replication_delay;
-extern ulong srv_io_capacity;
extern long long srv_ibuf_max_size;
extern ulong srv_ibuf_active_contract;
extern ulong srv_ibuf_accel_rate;
+extern ulint srv_checkpoint_age_target;
extern ulong srv_flush_neighbor_pages;
extern ulong srv_enable_unsafe_group_commit;
extern ulong srv_read_ahead;
extern ulong srv_adaptive_checkpoint;
extern ulong srv_expand_import;
+extern ulint srv_relax_table_creation;
extern ulong srv_extra_rsegments;
extern ulong srv_dict_size_limit;
@@ -215,7 +269,7 @@ extern ibool srv_error_monitor_active;
extern ulong srv_n_spin_wait_rounds;
extern ulong srv_n_free_tickets_to_enter;
extern ulong srv_thread_sleep_delay;
-extern ulint srv_spin_wait_delay;
+extern ulong srv_spin_wait_delay;
extern ibool srv_priority_boost;
extern ulint srv_mem_pool_size;
@@ -245,7 +299,7 @@ extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
same DRAM page as other hotspot semaphores */
#define kernel_mutex (*kernel_mutex_temp)
-#define SRV_MAX_N_IO_THREADS 100
+#define SRV_MAX_N_IO_THREADS 130
/* Array of English strings describing the current state of an
i/o handler thread */
@@ -294,61 +348,75 @@ extern ulint srv_buf_pool_wait_free;
buffer pool to disk */
extern ulint srv_buf_pool_flushed;
-/* variable to count the number of buffer pool reads that led to the
+/** Number of buffer pool reads that led to the
reading of a disk page */
extern ulint srv_buf_pool_reads;
-/* variable to count the number of sequential read-aheads were done */
-extern ulint srv_read_ahead_seq;
-
-/* variable to count the number of random read-aheads were done */
-extern ulint srv_read_ahead_rnd;
-
-/* In this structure we store status variables to be passed to MySQL */
+/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
+/** Status variables to be passed to MySQL */
extern export_struc export_vars;
+/** The server system */
typedef struct srv_sys_struct srv_sys_t;
-/* The server system */
+/** The server system */
extern srv_sys_t* srv_sys;
+#endif /* !UNIV_HOTBACKUP */
+
+/** Types of raw partitions in innodb_data_file_path */
+enum {
+ SRV_NOT_RAW = 0, /*!< Not a raw partition */
+ SRV_NEW_RAW, /*!< A 'newraw' partition, only to be
+ initialized */
+ SRV_OLD_RAW /*!< An initialized raw partition */
+};
-/* Alternatives for the file flush option in Unix; see the InnoDB manual
+/** Alternatives for the file flush option in Unix; see the InnoDB manual
about what these mean */
-#define SRV_UNIX_FSYNC 1 /* This is the default */
-#define SRV_UNIX_O_DSYNC 2
-#define SRV_UNIX_LITTLESYNC 3
-#define SRV_UNIX_NOSYNC 4
-#define SRV_UNIX_O_DIRECT 5
+enum {
+ SRV_UNIX_FSYNC = 1, /*!< fsync, the default */
+ SRV_UNIX_O_DSYNC, /*!< open log files in O_SYNC mode */
+ SRV_UNIX_LITTLESYNC, /*!< do not call os_file_flush()
+ when writing data files, but do flush
+ after writing to log files */
+ SRV_UNIX_NOSYNC, /*!< do not flush after writing */
+ SRV_UNIX_O_DIRECT /*!< invoke os_file_set_nocache() on
+ data files */
+};
-/* Alternatives for file i/o in Windows */
-#define SRV_WIN_IO_NORMAL 1
-#define SRV_WIN_IO_UNBUFFERED 2 /* This is the default */
+/** Alternatives for file i/o in Windows */
+enum {
+ SRV_WIN_IO_NORMAL = 1, /*!< buffered I/O */
+ SRV_WIN_IO_UNBUFFERED /*!< unbuffered I/O; this is the default */
+};
-/* Alternatives for srv_force_recovery. Non-zero values are intended
+/** Alternatives for srv_force_recovery. Non-zero values are intended
to help the user get a damaged database up so that he can dump intact
tables and rows with SELECT INTO OUTFILE. The database must not otherwise
be used with these options! A bigger number below means that all precautions
of lower numbers are included. */
-
-#define SRV_FORCE_IGNORE_CORRUPT 1 /* let the server run even if it
+enum {
+ SRV_FORCE_IGNORE_CORRUPT = 1, /*!< let the server run even if it
detects a corrupt page */
-#define SRV_FORCE_NO_BACKGROUND 2 /* prevent the main thread from
+ SRV_FORCE_NO_BACKGROUND = 2, /*!< prevent the main thread from
running: if a crash would occur
in purge, this prevents it */
-#define SRV_FORCE_NO_TRX_UNDO 3 /* do not run trx rollback after
+ SRV_FORCE_NO_TRX_UNDO = 3, /*!< do not run trx rollback after
recovery */
-#define SRV_FORCE_NO_IBUF_MERGE 4 /* prevent also ibuf operations:
+ SRV_FORCE_NO_IBUF_MERGE = 4, /*!< prevent also ibuf operations:
if they would cause a crash, better
not do them */
-#define SRV_FORCE_NO_UNDO_LOG_SCAN 5 /* do not look at undo logs when
+ SRV_FORCE_NO_UNDO_LOG_SCAN = 5, /*!< do not look at undo logs when
starting the database: InnoDB will
treat even incomplete transactions
as committed */
-#define SRV_FORCE_NO_LOG_REDO 6 /* do not do the log roll-forward
+ SRV_FORCE_NO_LOG_REDO = 6 /*!< do not do the log roll-forward
in connection with recovery */
+};
+#ifndef UNIV_HOTBACKUP
/** Types of threads existing in the system. */
enum srv_thread_type {
SRV_COM = 1, /**< threads serving communication and queries */
@@ -361,81 +429,97 @@ enum srv_thread_type {
SRV_RECOVERY, /**< threads finishing a recovery */
SRV_INSERT, /**< thread flushing the insert buffer to disk */
#endif
+ SRV_PURGE, /* thread purging undo records */
+ SRV_PURGE_WORKER, /* thread purging undo records */
SRV_MASTER /**< the master thread, (whose type number must
be biggest) */
};
-/*************************************************************************
-Boots Innobase server. */
+/*********************************************************************//**
+Boots Innobase server.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
srv_boot(void);
/*==========*/
- /* out: DB_SUCCESS or error code */
-/*************************************************************************
+/*********************************************************************//**
Initializes the server. */
UNIV_INTERN
void
srv_init(void);
/*==========*/
-/*************************************************************************
-Frees the OS fast mutex created in srv_boot(). */
+/*********************************************************************//**
+Frees the data structures created in srv_init(). */
UNIV_INTERN
void
srv_free(void);
/*==========*/
-/*************************************************************************
+/*********************************************************************//**
Initializes the synchronization primitives, memory system, and the thread
local storage. */
UNIV_INTERN
void
srv_general_init(void);
/*==================*/
-/*************************************************************************
-Gets the number of threads in the system. */
+/*********************************************************************//**
+Gets the number of threads in the system.
+@return sum of srv_n_threads[] */
UNIV_INTERN
ulint
srv_get_n_threads(void);
/*===================*/
-/*************************************************************************
-Returns the calling thread type. */
+/*********************************************************************//**
+Returns the calling thread type.
+@return SRV_COM, ... */
enum srv_thread_type
srv_get_thread_type(void);
/*=====================*/
- /* out: SRV_COM, ... */
-/*************************************************************************
+/*********************************************************************//**
Sets the info describing an i/o thread current state. */
UNIV_INTERN
void
srv_set_io_thread_op_info(
/*======================*/
- ulint i, /* in: the 'segment' of the i/o thread */
- const char* str); /* in: constant char string describing the
+ ulint i, /*!< in: the 'segment' of the i/o thread */
+ const char* str); /*!< in: constant char string describing the
state */
-/*************************************************************************
+/*********************************************************************//**
Releases threads of the type given from suspension in the thread table.
-NOTE! The server mutex has to be reserved by the caller! */
+NOTE! The server mutex has to be reserved by the caller!
+@return number of threads released: this may be less than n if not
+enough threads were suspended at the moment */
UNIV_INTERN
ulint
srv_release_threads(
/*================*/
- /* out: number of threads
- released: this may be < n if
- not enough threads were
- suspended at the moment */
- enum srv_thread_type type, /* in: thread type */
- ulint n); /* in: number of threads to release */
-/*************************************************************************
-The master thread controlling the server. */
+ enum srv_thread_type type, /*!< in: thread type */
+ ulint n); /*!< in: number of threads to release */
+/*********************************************************************//**
+The master thread controlling the server.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_master_thread(
/*==============*/
- /* out: a dummy parameter */
+ void* arg); /*!< in: a dummy parameter required by
+ os_thread_create */
+/*************************************************************************
+The undo purge thread. */
+UNIV_INTERN
+os_thread_ret_t
+srv_purge_thread(
+/*=============*/
void* arg); /* in: a dummy parameter required by
os_thread_create */
-/***********************************************************************
+/*************************************************************************
+The undo purge thread. */
+UNIV_INTERN
+os_thread_ret_t
+srv_purge_worker_thread(
+/*====================*/
+ void* arg);
+/*******************************************************************//**
Tells the Innobase server that there has been activity in the database
and wakes up the master thread if it is suspended (not sleeping). Used
in the MySQL interface. Note that there is a small chance that the master
@@ -445,48 +529,48 @@ UNIV_INTERN
void
srv_active_wake_master_thread(void);
/*===============================*/
-/***********************************************************************
+/*******************************************************************//**
Wakes up the master thread if it is suspended or being suspended. */
UNIV_INTERN
void
srv_wake_master_thread(void);
/*========================*/
-/*************************************************************************
+/*********************************************************************//**
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
UNIV_INTERN
void
srv_conc_enter_innodb(
/*==================*/
- trx_t* trx); /* in: transaction object associated with the
+ trx_t* trx); /*!< in: transaction object associated with the
thread */
-/*************************************************************************
+/*********************************************************************//**
This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
UNIV_INTERN
void
srv_conc_force_enter_innodb(
/*========================*/
- trx_t* trx); /* in: transaction object associated with the
+ trx_t* trx); /*!< in: transaction object associated with the
thread */
-/*************************************************************************
+/*********************************************************************//**
This must be called when a thread exits InnoDB in a lock wait or at the
end of an SQL statement. */
UNIV_INTERN
void
srv_conc_force_exit_innodb(
/*=======================*/
- trx_t* trx); /* in: transaction object associated with the
+ trx_t* trx); /*!< in: transaction object associated with the
thread */
-/*************************************************************************
+/*********************************************************************//**
This must be called when a thread exits InnoDB. */
UNIV_INTERN
void
srv_conc_exit_innodb(
/*=================*/
- trx_t* trx); /* in: transaction object associated with the
+ trx_t* trx); /*!< in: transaction object associated with the
thread */
-/*******************************************************************
+/***************************************************************//**
Puts a MySQL OS thread to wait for a lock to be released. If an error
occurs during the wait trx->error_state associated with thr is
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
@@ -496,124 +580,135 @@ UNIV_INTERN
void
srv_suspend_mysql_thread(
/*=====================*/
- que_thr_t* thr); /* in: query thread associated with the MySQL
+ que_thr_t* thr); /*!< in: query thread associated with the MySQL
OS thread */
-/************************************************************************
+/********************************************************************//**
Releases a MySQL OS thread waiting for a lock to be released, if the
thread is already suspended. */
UNIV_INTERN
void
srv_release_mysql_thread_if_suspended(
/*==================================*/
- que_thr_t* thr); /* in: query thread associated with the
+ que_thr_t* thr); /*!< in: query thread associated with the
MySQL OS thread */
-/*************************************************************************
+/*********************************************************************//**
A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+This also prints the info output by various InnoDB monitors.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_lock_timeout_and_monitor_thread(
/*================================*/
- /* out: a dummy parameter */
- void* arg); /* in: a dummy parameter required by
+ void* arg); /*!< in: a dummy parameter required by
os_thread_create */
-/*************************************************************************
+/*********************************************************************//**
A thread which prints warnings about semaphore waits which have lasted
-too long. These can be used to track bugs which cause hangs. */
+too long. These can be used to track bugs which cause hangs.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_error_monitor_thread(
/*=====================*/
- /* out: a dummy parameter */
- void* arg); /* in: a dummy parameter required by
+ void* arg); /*!< in: a dummy parameter required by
os_thread_create */
-/**********************************************************************
+/******************************************************************//**
Outputs to a file the output of the InnoDB Monitor. */
UNIV_INTERN
void
srv_printf_innodb_monitor(
/*======================*/
- FILE* file, /* in: output stream */
- ulint* trx_start, /* out: file position of the start of
+ FILE* file, /*!< in: output stream */
+ ulint* trx_start, /*!< out: file position of the start of
the list of active transactions */
- ulint* trx_end); /* out: file position of the end of
+ ulint* trx_end); /*!< out: file position of the end of
the list of active transactions */
-/**********************************************************************
+/******************************************************************//**
Function to pass InnoDB status variables to MySQL */
UNIV_INTERN
void
srv_export_innodb_status(void);
-/*=====================*/
+/*==========================*/
-/* Thread slot in the thread table */
+/** Thread slot in the thread table */
typedef struct srv_slot_struct srv_slot_t;
-/* Thread table is an array of slots */
+/** Thread table is an array of slots */
typedef srv_slot_t srv_table_t;
-/* In this structure we store status variables to be passed to MySQL */
+/** Status variables to be passed to MySQL */
struct export_var_struct{
- ulint innodb_data_pending_reads;
- ulint innodb_data_pending_writes;
- ulint innodb_data_pending_fsyncs;
- ulint innodb_data_fsyncs;
- ulint innodb_data_read;
- ulint innodb_data_writes;
- ulint innodb_data_written;
- ulint innodb_data_reads;
+ ulint innodb_data_pending_reads; /*!< Pending reads */
+ ulint innodb_data_pending_writes; /*!< Pending writes */
+ ulint innodb_data_pending_fsyncs; /*!< Pending fsyncs */
+ ulint innodb_data_fsyncs; /*!< Number of fsyncs so far */
+ ulint innodb_data_read; /*!< Data bytes read */
+ ulint innodb_data_writes; /*!< I/O write requests */
+ ulint innodb_data_written; /*!< Data bytes written */
+ ulint innodb_data_reads; /*!< I/O read requests */
ulint innodb_dict_tables;
- ulint innodb_buffer_pool_pages_total;
- ulint innodb_buffer_pool_pages_data;
- ulint innodb_buffer_pool_pages_dirty;
- ulint innodb_buffer_pool_pages_misc;
- ulint innodb_buffer_pool_pages_free;
+ ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
+ ulint innodb_buffer_pool_pages_data; /*!< Data pages */
+ ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */
+ ulint innodb_buffer_pool_pages_misc; /*!< Miscellanous pages */
+ ulint innodb_buffer_pool_pages_free; /*!< Free pages */
#ifdef UNIV_DEBUG
- ulint innodb_buffer_pool_pages_latched;
+ ulint innodb_buffer_pool_pages_latched; /*!< Latched pages */
#endif /* UNIV_DEBUG */
- ulint innodb_buffer_pool_read_requests;
- ulint innodb_buffer_pool_reads;
- ulint innodb_buffer_pool_wait_free;
- ulint innodb_buffer_pool_pages_flushed;
- ulint innodb_buffer_pool_write_requests;
- ulint innodb_buffer_pool_read_ahead_seq;
- ulint innodb_buffer_pool_read_ahead_rnd;
- ulint innodb_dblwr_pages_written;
- ulint innodb_dblwr_writes;
- ibool innodb_have_atomic_builtins;
- ulint innodb_log_waits;
- ulint innodb_log_write_requests;
- ulint innodb_log_writes;
- ulint innodb_os_log_written;
- ulint innodb_os_log_fsyncs;
- ulint innodb_os_log_pending_writes;
- ulint innodb_os_log_pending_fsyncs;
- ulint innodb_page_size;
- ulint innodb_pages_created;
- ulint innodb_pages_read;
- ulint innodb_pages_written;
- ulint innodb_row_lock_waits;
- ulint innodb_row_lock_current_waits;
- ib_int64_t innodb_row_lock_time;
- ulint innodb_row_lock_time_avg;
- ulint innodb_row_lock_time_max;
- ulint innodb_rows_read;
- ulint innodb_rows_inserted;
- ulint innodb_rows_updated;
- ulint innodb_rows_deleted;
+ ulint innodb_buffer_pool_read_requests; /*!< buf_pool->stat.n_page_gets */
+ ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */
+ ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */
+ ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */
+ ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
+ ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
+ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
+ ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
+ ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
+ ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
+ ulint innodb_log_waits; /*!< srv_log_waits */
+ ulint innodb_log_write_requests; /*!< srv_log_write_requests */
+ ulint innodb_log_writes; /*!< srv_log_writes */
+ ulint innodb_os_log_written; /*!< srv_os_log_written */
+ ulint innodb_os_log_fsyncs; /*!< fil_n_log_flushes */
+ ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */
+ ulint innodb_os_log_pending_fsyncs; /*!< fil_n_pending_log_flushes */
+ ulint innodb_page_size; /*!< UNIV_PAGE_SIZE */
+ ulint innodb_pages_created; /*!< buf_pool->stat.n_pages_created */
+ ulint innodb_pages_read; /*!< buf_pool->stat.n_pages_read */
+ ulint innodb_pages_written; /*!< buf_pool->stat.n_pages_written */
+ ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */
+ ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */
+ ib_int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time
+ / 1000 */
+ ulint innodb_row_lock_time_avg; /*!< srv_n_lock_wait_time
+ / 1000
+ / srv_n_lock_wait_count */
+ ulint innodb_row_lock_time_max; /*!< srv_n_lock_max_wait_time
+ / 1000 */
+ ulint innodb_rows_read; /*!< srv_n_rows_read */
+ ulint innodb_rows_inserted; /*!< srv_n_rows_inserted */
+ ulint innodb_rows_updated; /*!< srv_n_rows_updated */
+ ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */
};
-/* The server system struct */
+/** The server system struct */
struct srv_sys_struct{
- srv_table_t* threads; /* server thread table */
+ srv_table_t* threads; /*!< server thread table */
UT_LIST_BASE_NODE_T(que_thr_t)
- tasks; /* task queue */
- dict_index_t* dummy_ind1; /* dummy index for old-style
- supremum and infimum records */
- dict_index_t* dummy_ind2; /* dummy index for new-style
- supremum and infimum records */
+ tasks; /*!< task queue */
};
extern ulint srv_n_threads_active[];
+#else /* !UNIV_HOTBACKUP */
+# define srv_use_checksums TRUE
+# define srv_use_adaptive_hash_indexes FALSE
+# define srv_force_recovery 0UL
+# define srv_set_io_thread_op_info(t,info) ((void) 0)
+# define srv_is_being_started 0
+# define srv_win_file_flush_method SRV_WIN_IO_UNBUFFERED
+# define srv_unix_file_flush_method SRV_UNIX_O_DSYNC
+# define srv_start_raw_disk_in_use 0
+# define srv_file_per_table 1
+#endif /* !UNIV_HOTBACKUP */
#endif
diff --git a/storage/xtradb/include/srv0srv.ic b/storage/xtradb/include/srv0srv.ic
index 93d675f1dca..8a1a678a016 100644
--- a/storage/xtradb/include/srv0srv.ic
+++ b/storage/xtradb/include/srv0srv.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/srv0srv.ic
Server main program
Created 10/4/1995 Heikki Tuuri
diff --git a/storage/xtradb/include/srv0start.h b/storage/xtradb/include/srv0start.h
index 15fa3b8f95f..8abf15da9c1 100644
--- a/storage/xtradb/include/srv0start.h
+++ b/storage/xtradb/include/srv0start.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/srv0start.h
Starts the Innobase database server
Created 10/10/1995 Heikki Tuuri
@@ -28,64 +29,66 @@ Created 10/10/1995 Heikki Tuuri
#include "univ.i"
#include "ut0byte.h"
-/*************************************************************************
+/*********************************************************************//**
Normalizes a directory path for Windows: converts slashes to backslashes. */
UNIV_INTERN
void
srv_normalize_path_for_win(
/*=======================*/
- char* str); /* in/out: null-terminated character string */
-/*************************************************************************
+ char* str); /*!< in/out: null-terminated character string */
+/*********************************************************************//**
Reads the data files and their sizes from a character string given in
-the .cnf file. */
+the .cnf file.
+@return TRUE if ok, FALSE on parse error */
UNIV_INTERN
ibool
srv_parse_data_file_paths_and_sizes(
/*================================*/
- /* out: TRUE if ok, FALSE on parse error */
- char* str); /* in/out: the data file path string */
-/*************************************************************************
+ char* str); /*!< in/out: the data file path string */
+/*********************************************************************//**
Reads log group home directories from a character string given in
-the .cnf file. */
+the .cnf file.
+@return TRUE if ok, FALSE on parse error */
UNIV_INTERN
ibool
srv_parse_log_group_home_dirs(
/*==========================*/
- /* out: TRUE if ok, FALSE on parse error */
- char* str); /* in/out: character string */
-/*************************************************************************
+ char* str); /*!< in/out: character string */
+/*********************************************************************//**
Frees the memory allocated by srv_parse_data_file_paths_and_sizes()
and srv_parse_log_group_home_dirs(). */
UNIV_INTERN
void
srv_free_paths_and_sizes(void);
/*==========================*/
-/*************************************************************************
+/*********************************************************************//**
Adds a slash or a backslash to the end of a string if it is missing
-and the string is not empty. */
+and the string is not empty.
+@return string which has the separator if the string is not empty */
UNIV_INTERN
char*
srv_add_path_separator_if_needed(
/*=============================*/
- /* out: string which has the separator if the
- string is not empty */
- char* str); /* in: null-terminated character string */
-/********************************************************************
+ char* str); /*!< in: null-terminated character string */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Starts Innobase and creates a new database if database files
-are not found and the user wants. */
+are not found and the user wants.
+@return DB_SUCCESS or error code */
UNIV_INTERN
int
innobase_start_or_create_for_mysql(void);
/*====================================*/
- /* out: DB_SUCCESS or error code */
-/********************************************************************
-Shuts down the Innobase database. */
+/****************************************************************//**
+Shuts down the Innobase database.
+@return DB_SUCCESS or error code */
UNIV_INTERN
int
innobase_shutdown_for_mysql(void);
/*=============================*/
- /* out: DB_SUCCESS or error code */
+/** Log sequence number at shutdown */
extern ib_uint64_t srv_shutdown_lsn;
+/** Log sequence number immediately after startup */
extern ib_uint64_t srv_start_lsn;
#ifdef __NETWARE__
@@ -93,26 +96,39 @@ void set_panic_flag_for_netware(void);
#endif
#ifdef HAVE_DARWIN_THREADS
+/** TRUE if the F_FULLFSYNC option is available */
extern ibool srv_have_fullfsync;
#endif
+/** TRUE if the server is being started */
extern ibool srv_is_being_started;
+/** TRUE if the server was successfully started */
extern ibool srv_was_started;
+/** TRUE if the server is being started, before rolling back any
+incomplete transactions */
extern ibool srv_startup_is_before_trx_rollback_phase;
-extern ibool srv_is_being_shut_down;
+/** TRUE if a raw partition is in use */
extern ibool srv_start_raw_disk_in_use;
-/* At a shutdown the value first climbs from 0 to SRV_SHUTDOWN_CLEANUP
-and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
-extern ulint srv_shutdown_state;
+/** Shutdown state */
+enum srv_shutdown_state {
+ SRV_SHUTDOWN_NONE = 0, /*!< Database running normally */
+ SRV_SHUTDOWN_CLEANUP, /*!< Cleaning up in
+ logs_empty_and_mark_files_at_shutdown() */
+ SRV_SHUTDOWN_LAST_PHASE,/*!< Last phase after ensuring that
+ the buffer pool can be freed: flush
+ all file spaces and close all files */
+ SRV_SHUTDOWN_EXIT_THREADS/*!< Exit all threads */
+};
-#define SRV_SHUTDOWN_CLEANUP 1
-#define SRV_SHUTDOWN_LAST_PHASE 2
-#define SRV_SHUTDOWN_EXIT_THREADS 3
+/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
+SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
+extern enum srv_shutdown_state srv_shutdown_state;
+#endif /* !UNIV_HOTBACKUP */
-/* Log 'spaces' have id's >= this */
+/** Log 'spaces' have id's >= this */
#define SRV_LOG_SPACE_FIRST_ID 0xFFFFFFF0UL
#endif
diff --git a/storage/xtradb/include/sync0arr.h b/storage/xtradb/include/sync0arr.h
index cc01c9ac5c8..5f1280f5e28 100644
--- a/storage/xtradb/include/sync0arr.h
+++ b/storage/xtradb/include/sync0arr.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0arr.h
The wait array used in synchronization primitives
Created 9/5/1995 Heikki Tuuri
@@ -30,47 +31,51 @@ Created 9/5/1995 Heikki Tuuri
#include "ut0mem.h"
#include "os0thread.h"
+/** Synchronization wait array cell */
typedef struct sync_cell_struct sync_cell_t;
+/** Synchronization wait array */
typedef struct sync_array_struct sync_array_t;
-#define SYNC_ARRAY_OS_MUTEX 1
-#define SYNC_ARRAY_MUTEX 2
+/** Parameters for sync_array_create() @{ */
+#define SYNC_ARRAY_OS_MUTEX 1 /*!< protected by os_mutex_t */
+#define SYNC_ARRAY_MUTEX 2 /*!< protected by mutex_t */
+/* @} */
-/***********************************************************************
+/*******************************************************************//**
Creates a synchronization wait array. It is protected by a mutex
which is automatically reserved when the functions operating on it
-are called. */
+are called.
+@return own: created wait array */
UNIV_INTERN
sync_array_t*
sync_array_create(
/*==============*/
- /* out, own: created wait array */
- ulint n_cells, /* in: number of cells in the array
+ ulint n_cells, /*!< in: number of cells in the array
to create */
- ulint protection); /* in: either SYNC_ARRAY_OS_MUTEX or
+ ulint protection); /*!< in: either SYNC_ARRAY_OS_MUTEX or
SYNC_ARRAY_MUTEX: determines the type
of mutex protecting the data structure */
-/**********************************************************************
+/******************************************************************//**
Frees the resources in a wait array. */
UNIV_INTERN
void
sync_array_free(
/*============*/
- sync_array_t* arr); /* in, own: sync wait array */
-/**********************************************************************
+ sync_array_t* arr); /*!< in, own: sync wait array */
+/******************************************************************//**
Reserves a wait array cell for waiting for an object.
The event of the cell is reset to nonsignalled state. */
UNIV_INTERN
void
sync_array_reserve_cell(
/*====================*/
- sync_array_t* arr, /* in: wait array */
- void* object, /* in: pointer to the object to wait for */
- ulint type, /* in: lock request type */
- const char* file, /* in: file where requested */
- ulint line, /* in: line where requested */
- ulint* index); /* out: index of the reserved cell */
-/**********************************************************************
+ sync_array_t* arr, /*!< in: wait array */
+ void* object, /*!< in: pointer to the object to wait for */
+ ulint type, /*!< in: lock request type */
+ const char* file, /*!< in: file where requested */
+ ulint line, /*!< in: line where requested */
+ ulint* index); /*!< out: index of the reserved cell */
+/******************************************************************//**
This function should be called when a thread starts to wait on
a wait array cell. In the debug version this function checks
if the wait for a semaphore will result in a deadlock, in which
@@ -79,25 +84,25 @@ UNIV_INTERN
void
sync_array_wait_event(
/*==================*/
- sync_array_t* arr, /* in: wait array */
- ulint index); /* in: index of the reserved cell */
-/**********************************************************************
+ sync_array_t* arr, /*!< in: wait array */
+ ulint index); /*!< in: index of the reserved cell */
+/******************************************************************//**
Frees the cell. NOTE! sync_array_wait_event frees the cell
automatically! */
UNIV_INTERN
void
sync_array_free_cell(
/*=================*/
- sync_array_t* arr, /* in: wait array */
- ulint index); /* in: index of the cell in array */
-/**************************************************************************
+ sync_array_t* arr, /*!< in: wait array */
+ ulint index); /*!< in: index of the cell in array */
+/**********************************************************************//**
Note that one of the wait objects was signalled. */
UNIV_INTERN
void
sync_array_object_signalled(
/*========================*/
- sync_array_t* arr); /* in: wait array */
-/**************************************************************************
+ sync_array_t* arr); /*!< in: wait array */
+/**********************************************************************//**
If the wakeup algorithm does not work perfectly at semaphore relases,
this function will do the waking (see the comment in mutex_exit). This
function should be called about every 1 second in the server. */
@@ -105,30 +110,29 @@ UNIV_INTERN
void
sync_arr_wake_threads_if_sema_free(void);
/*====================================*/
-/**************************************************************************
-Prints warnings of long semaphore waits to stderr. */
+/**********************************************************************//**
+Prints warnings of long semaphore waits to stderr.
+@return TRUE if fatal semaphore wait threshold was exceeded */
UNIV_INTERN
ibool
sync_array_print_long_waits(void);
/*=============================*/
- /* out: TRUE if fatal semaphore wait threshold
- was exceeded */
-/************************************************************************
+/********************************************************************//**
Validates the integrity of the wait array. Checks
that the number of reserved cells equals the count variable. */
UNIV_INTERN
void
sync_array_validate(
/*================*/
- sync_array_t* arr); /* in: sync wait array */
-/**************************************************************************
+ sync_array_t* arr); /*!< in: sync wait array */
+/**********************************************************************//**
Prints info of the wait array. */
UNIV_INTERN
void
sync_array_print_info(
/*==================*/
- FILE* file, /* in: file where to print */
- sync_array_t* arr); /* in: wait array */
+ FILE* file, /*!< in: file where to print */
+ sync_array_t* arr); /*!< in: wait array */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/sync0arr.ic b/storage/xtradb/include/sync0arr.ic
index 09a562a4723..bf57f5b2dc2 100644
--- a/storage/xtradb/include/sync0arr.ic
+++ b/storage/xtradb/include/sync0arr.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0arr.ic
The wait array for synchronization primitives
Inline code
diff --git a/storage/xtradb/include/sync0rw.h b/storage/xtradb/include/sync0rw.h
index e3fe0dc9ccc..85fa014d77a 100644
--- a/storage/xtradb/include/sync0rw.h
+++ b/storage/xtradb/include/sync0rw.h
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0rw.h
The read-write lock (for threads, not for database transactions)
Created 9/11/1995 Heikki Tuuri
@@ -33,6 +34,7 @@ Created 9/11/1995 Heikki Tuuri
#define sync0rw_h
#include "univ.i"
+#ifndef UNIV_HOTBACKUP
#include "ut0lst.h"
#include "sync0sync.h"
#include "os0sync.h"
@@ -40,6 +42,7 @@ Created 9/11/1995 Heikki Tuuri
/* The following undef is to prevent a name conflict with a macro
in MySQL: */
#undef rw_lock_t
+#endif /* !UNIV_HOTBACKUP */
/* Latch types; these are used also in btr0btr.h: keep the numerical values
smaller than 30 and the order of the numerical values like below! */
@@ -47,6 +50,7 @@ smaller than 30 and the order of the numerical values like below! */
#define RW_X_LATCH 2
#define RW_NO_LATCH 3
+#ifndef UNIV_HOTBACKUP
/* We decrement lock_word by this amount for each x_lock. It is also the
start value for the lock_word, meaning that it limits the maximum number
of concurrent read locks before the rw_lock breaks. The current value of
@@ -69,23 +73,39 @@ To modify the debug info list of an rw-lock, this mutex has to be
acquired in addition to the mutex protecting the lock. */
extern mutex_t rw_lock_debug_mutex;
-extern os_event_t rw_lock_debug_event; /* If deadlock detection does
+extern os_event_t rw_lock_debug_event; /*!< If deadlock detection does
not get immediately the mutex it
may wait for this event */
-extern ibool rw_lock_debug_waiters; /* This is set to TRUE, if
+extern ibool rw_lock_debug_waiters; /*!< This is set to TRUE, if
there may be waiters for the event */
#endif /* UNIV_SYNC_DEBUG */
+/** number of spin waits on rw-latches,
+resulted during exclusive (write) locks */
extern ib_int64_t rw_s_spin_wait_count;
+/** number of spin loop rounds on rw-latches,
+resulted during exclusive (write) locks */
extern ib_int64_t rw_s_spin_round_count;
+/** number of unlocks (that unlock shared locks),
+set only when UNIV_SYNC_PERF_STAT is defined */
extern ib_int64_t rw_s_exit_count;
+/** number of OS waits on rw-latches,
+resulted during shared (read) locks */
extern ib_int64_t rw_s_os_wait_count;
+/** number of spin waits on rw-latches,
+resulted during shared (read) locks */
extern ib_int64_t rw_x_spin_wait_count;
+/** number of spin loop rounds on rw-latches,
+resulted during shared (read) locks */
extern ib_int64_t rw_x_spin_round_count;
+/** number of OS waits on rw-latches,
+resulted during exclusive (write) locks */
extern ib_int64_t rw_x_os_wait_count;
+/** number of unlocks (that unlock exclusive locks),
+set only when UNIV_SYNC_PERF_STAT is defined */
extern ib_int64_t rw_x_exit_count;
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes an rw-lock object in a specified memory
location (which must be appropriately aligned). The rw-lock is initialized
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
@@ -100,10 +120,10 @@ is necessary only if the memory block containing it is freed. */
# endif /* UNIV_SYNC_DEBUG */
#else /* UNIV_DEBUG */
# define rw_lock_create(L, level) \
- rw_lock_create_func((L), __FILE__, __LINE__)
+ rw_lock_create_func((L), #L, NULL, 0)
#endif /* UNIV_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes an rw-lock object in a specified memory
location (which must be appropriately aligned). The rw-lock is initialized
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
@@ -112,16 +132,16 @@ UNIV_INTERN
void
rw_lock_create_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to memory */
+ rw_lock_t* lock, /*!< in: pointer to memory */
#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
- ulint level, /* in: level */
+ ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
- const char* cmutex_name, /* in: mutex name */
#endif /* UNIV_DEBUG */
- const char* cfile_name, /* in: file name where created */
- ulint cline); /* in: file line where created */
-/**********************************************************************
+ const char* cmutex_name, /*!< in: mutex name */
+ const char* cfile_name, /*!< in: file name where created */
+ ulint cline); /*!< in: file line where created */
+/******************************************************************//**
Calling this function is obligatory only if the memory buffer containing
the rw-lock is freed. Removes an rw-lock object from the global list. The
rw-lock is checked to be in the non-locked state. */
@@ -129,50 +149,51 @@ UNIV_INTERN
void
rw_lock_free(
/*=========*/
- rw_lock_t* lock); /* in: rw-lock */
+ rw_lock_t* lock); /*!< in: rw-lock */
#ifdef UNIV_DEBUG
-/**********************************************************************
+/******************************************************************//**
Checks that the rw-lock has been initialized and that there are no
-simultaneous shared and exclusive locks. */
+simultaneous shared and exclusive locks.
+@return TRUE */
UNIV_INTERN
ibool
rw_lock_validate(
/*=============*/
- rw_lock_t* lock);
+ rw_lock_t* lock); /*!< in: rw-lock */
#endif /* UNIV_DEBUG */
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used in rw s-locking, not the
corresponding function. */
#define rw_lock_s_lock(M) rw_lock_s_lock_func(\
(M), 0, __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used in rw s-locking, not the
corresponding function. */
#define rw_lock_s_lock_gen(M, P) rw_lock_s_lock_func(\
(M), (P), __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used in rw s-locking, not the
corresponding function. */
#define rw_lock_s_lock_nowait(M, F, L) rw_lock_s_lock_low(\
(M), 0, (F), (L))
-/**********************************************************************
+/******************************************************************//**
Low-level function which tries to lock an rw-lock in s-mode. Performs no
-spinning. */
+spinning.
+@return TRUE if success */
UNIV_INLINE
ibool
rw_lock_s_lock_low(
/*===============*/
- /* out: TRUE if success */
- rw_lock_t* lock, /* in: pointer to rw-lock */
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
ulint pass __attribute__((unused)),
- /* in: pass value; != 0, if the lock will be
+ /*!< in: pass value; != 0, if the lock will be
passed to another thread to unlock */
- const char* file_name, /* in: file name where lock requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ const char* file_name, /*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function, except if
you supply the file name and line number. Lock an rw-lock in shared mode
for the current thread. If the rw-lock is locked in exclusive mode, or
@@ -183,70 +204,63 @@ UNIV_INLINE
void
rw_lock_s_lock_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread if the lock can be
-obtained immediately. */
+obtained immediately.
+@return TRUE if success */
UNIV_INLINE
ibool
rw_lock_x_lock_func_nowait(
/*=======================*/
- /* out: TRUE if success */
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name,/* in: file name where lock requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
Releases a shared mode lock. */
UNIV_INLINE
void
rw_lock_s_unlock_func(
/*==================*/
- rw_lock_t* lock /* in: rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ,ulint pass /* in: pass value; != 0, if the lock may have
+ ulint pass, /*!< in: pass value; != 0, if the lock may have
been passed to another thread to unlock */
#endif
- );
-/***********************************************************************
-Releases a shared mode lock. */
+ rw_lock_t* lock); /*!< in/out: rw-lock */
#ifdef UNIV_SYNC_DEBUG
-#define rw_lock_s_unlock(L) rw_lock_s_unlock_func(L, 0)
+# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(P, L)
#else
-#define rw_lock_s_unlock(L) rw_lock_s_unlock_func(L)
+# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
#endif
-/***********************************************************************
+/*******************************************************************//**
Releases a shared mode lock. */
+#define rw_lock_s_unlock(L) rw_lock_s_unlock_gen(L, 0)
-#ifdef UNIV_SYNC_DEBUG
-#define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L, P)
-#else
-#define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
-#endif
-/******************************************************************
+/**************************************************************//**
NOTE! The following macro should be used in rw x-locking, not the
corresponding function. */
#define rw_lock_x_lock(M) rw_lock_x_lock_func(\
(M), 0, __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macro should be used in rw x-locking, not the
corresponding function. */
#define rw_lock_x_lock_gen(M, P) rw_lock_x_lock_func(\
(M), (P), __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used in rw x-locking, not the
corresponding function. */
#define rw_lock_x_lock_nowait(M) rw_lock_x_lock_func_nowait(\
(M), __FILE__, __LINE__)
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread. If the rw-lock is locked
in shared or exclusive mode, or there is an exclusive lock request waiting,
@@ -259,40 +273,33 @@ UNIV_INTERN
void
rw_lock_x_lock_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
Releases an exclusive mode lock. */
UNIV_INLINE
void
rw_lock_x_unlock_func(
/*==================*/
- rw_lock_t* lock /* in: rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ,ulint pass /* in: pass value; != 0, if the lock may have
+ ulint pass, /*!< in: pass value; != 0, if the lock may have
been passed to another thread to unlock */
#endif
- );
-/***********************************************************************
-Releases an exclusive mode lock. */
+ rw_lock_t* lock); /*!< in/out: rw-lock */
#ifdef UNIV_SYNC_DEBUG
-#define rw_lock_x_unlock(L) rw_lock_x_unlock_func(L, 0)
+# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L)
#else
-#define rw_lock_x_unlock(L) rw_lock_x_unlock_func(L)
+# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
#endif
-/***********************************************************************
+/*******************************************************************//**
Releases an exclusive mode lock. */
+#define rw_lock_x_unlock(L) rw_lock_x_unlock_gen(L, 0)
-#ifdef UNIV_SYNC_DEBUG
-#define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L, P)
-#else
-#define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
-#endif
-/**********************************************************************
+/******************************************************************//**
Low-level function which locks an rw-lock in s-mode when we know that it
is possible and none else is currently accessing the rw-lock structure.
Then we can do the locking without reserving the mutex. */
@@ -300,11 +307,10 @@ UNIV_INLINE
void
rw_lock_s_lock_direct(
/*==================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name, /* in: file name where requested */
- ulint line /* in: line where lock requested */
-);
-/**********************************************************************
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ const char* file_name, /*!< in: file name where requested */
+ ulint line); /*!< in: line where lock requested */
+/******************************************************************//**
Low-level function which locks an rw-lock in x-mode when we know that it
is not locked and none else is currently accessing the rw-lock structure.
Then we can do the locking without reserving the mutex. */
@@ -312,11 +318,10 @@ UNIV_INLINE
void
rw_lock_x_lock_direct(
/*==================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name, /* in: file name where requested */
- ulint line /* in: line where lock requested */
-);
-/**********************************************************************
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ const char* file_name, /*!< in: file name where requested */
+ ulint line); /*!< in: line where lock requested */
+/******************************************************************//**
This function is used in the insert buffer to move the ownership of an
x-latch on a buffer frame to the current thread. The x-latch was set by
the buffer read operation and it protected the buffer frame while the
@@ -328,70 +333,78 @@ UNIV_INTERN
void
rw_lock_x_lock_move_ownership(
/*==========================*/
- rw_lock_t* lock); /* in: lock which was x-locked in the
+ rw_lock_t* lock); /*!< in: lock which was x-locked in the
buffer read */
-/**********************************************************************
+/******************************************************************//**
Releases a shared mode lock when we know there are no waiters and none
else will access the lock during the time this function is executed. */
UNIV_INLINE
void
rw_lock_s_unlock_direct(
/*====================*/
- rw_lock_t* lock); /* in: rw-lock */
-/**********************************************************************
+ rw_lock_t* lock); /*!< in/out: rw-lock */
+/******************************************************************//**
Releases an exclusive mode lock when we know there are no waiters, and
none else will access the lock durint the time this function is executed. */
UNIV_INLINE
void
rw_lock_x_unlock_direct(
/*====================*/
- rw_lock_t* lock); /* in: rw-lock */
-/**********************************************************************
+ rw_lock_t* lock); /*!< in/out: rw-lock */
+/******************************************************************//**
Returns the value of writer_count for the lock. Does not reserve the lock
-mutex, so the caller must be sure it is not changed during the call. */
+mutex, so the caller must be sure it is not changed during the call.
+@return value of writer_count */
UNIV_INLINE
ulint
rw_lock_get_x_lock_count(
/*=====================*/
- /* out: value of writer_count */
- rw_lock_t* lock); /* in: rw-lock */
-/************************************************************************
-Accessor functions for rw lock. */
+ const rw_lock_t* lock); /*!< in: rw-lock */
+/********************************************************************//**
+Check if there are threads waiting for the rw-lock.
+@return 1 if waiters, 0 otherwise */
UNIV_INLINE
ulint
rw_lock_get_waiters(
/*================*/
- rw_lock_t* lock);
+ const rw_lock_t* lock); /*!< in: rw-lock */
+/******************************************************************//**
+Returns the write-status of the lock - this function made more sense
+with the old rw_lock implementation.
+@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */
UNIV_INLINE
ulint
rw_lock_get_writer(
/*===============*/
- rw_lock_t* lock);
+ const rw_lock_t* lock); /*!< in: rw-lock */
+/******************************************************************//**
+Returns the number of readers.
+@return number of readers */
UNIV_INLINE
ulint
rw_lock_get_reader_count(
/*=====================*/
- rw_lock_t* lock);
-/**********************************************************************
+ const rw_lock_t* lock); /*!< in: rw-lock */
+/******************************************************************//**
Decrements lock_word the specified amount if it is greater than 0.
-This is used by both s_lock and x_lock operations. */
+This is used by both s_lock and x_lock operations.
+@return TRUE if decr occurs */
UNIV_INLINE
ibool
rw_lock_lock_word_decr(
/*===================*/
- /* out: TRUE if decr occurs */
- rw_lock_t* lock, /* in: rw-lock */
- ulint amount); /* in: amount to decrement */
-/**********************************************************************
-Increments lock_word the specified amount and returns new value. */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ ulint amount); /*!< in: amount to decrement */
+/******************************************************************//**
+Increments lock_word the specified amount and returns new value.
+@return lock->lock_word after increment */
UNIV_INLINE
lint
rw_lock_lock_word_incr(
/*===================*/
- /* out: TRUE if decr occurs */
- rw_lock_t* lock,
- ulint amount); /* in: rw-lock */
-/**********************************************************************
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ ulint amount); /*!< in: amount to increment */
+/******************************************************************//**
This function sets the lock->writer_thread and lock->recursive fields.
For platforms where we are using atomic builtins instead of lock->mutex
it sets the lock->writer_thread field using atomics to ensure memory
@@ -404,48 +417,49 @@ UNIV_INLINE
void
rw_lock_set_writer_id_and_recursion_flag(
/*=====================================*/
- rw_lock_t* lock, /* in/out: lock to work on */
- ibool recursive); /* in: TRUE if recursion
+ rw_lock_t* lock, /*!< in/out: lock to work on */
+ ibool recursive); /*!< in: TRUE if recursion
allowed */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Checks if the thread has locked the rw-lock in the specified mode, with
the pass value == 0. */
UNIV_INTERN
ibool
rw_lock_own(
/*========*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type); /* in: lock type: RW_LOCK_SHARED,
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint lock_type); /*!< in: lock type: RW_LOCK_SHARED,
RW_LOCK_EX */
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Checks if somebody has locked the rw-lock in the specified mode. */
UNIV_INTERN
ibool
rw_lock_is_locked(
/*==============*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type); /* in: lock type: RW_LOCK_SHARED,
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint lock_type); /*!< in: lock type: RW_LOCK_SHARED,
RW_LOCK_EX */
#ifdef UNIV_SYNC_DEBUG
-/*******************************************************************
+/***************************************************************//**
Prints debug info of an rw-lock. */
UNIV_INTERN
void
rw_lock_print(
/*==========*/
- rw_lock_t* lock); /* in: rw-lock */
-/*******************************************************************
+ rw_lock_t* lock); /*!< in: rw-lock */
+/***************************************************************//**
Prints debug info of currently locked rw-locks. */
UNIV_INTERN
void
rw_lock_list_print_info(
/*====================*/
- FILE* file); /* in: file where to print */
-/*******************************************************************
+ FILE* file); /*!< in: file where to print */
+/***************************************************************//**
Returns the number of currently locked rw-locks.
-Works only in the debug version. */
+Works only in the debug version.
+@return number of locked rw-locks */
UNIV_INTERN
ulint
rw_lock_n_locked(void);
@@ -453,7 +467,7 @@ rw_lock_n_locked(void);
/*#####################################################################*/
-/**********************************************************************
+/******************************************************************//**
Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
because the debug mutex is also acquired in sync0arr while holding the OS
mutex protecting the sync array, and the ordinary mutex_enter might
@@ -463,34 +477,36 @@ UNIV_INTERN
void
rw_lock_debug_mutex_enter(void);
/*==========================*/
-/**********************************************************************
+/******************************************************************//**
Releases the debug mutex. */
UNIV_INTERN
void
rw_lock_debug_mutex_exit(void);
/*==========================*/
-/*************************************************************************
+/*********************************************************************//**
Prints info of a debug struct. */
UNIV_INTERN
void
rw_lock_debug_print(
/*================*/
- rw_lock_debug_t* info); /* in: debug struct */
+ rw_lock_debug_t* info); /*!< in: debug struct */
#endif /* UNIV_SYNC_DEBUG */
/* NOTE! The structure appears here only for the compiler to know its size.
-Do not use its fields directly! The structure used in the spin lock
-implementation of a read-write lock. Several threads may have a shared lock
-simultaneously in this lock, but only one writer may have an exclusive lock,
-in which case no shared locks are allowed. To prevent starving of a writer
-blocked by readers, a writer may queue for x-lock by decrementing lock_word:
-no new readers will be let in while the thread waits for readers to exit. */
-
+Do not use its fields directly! */
+
+/** The structure used in the spin lock implementation of a read-write
+lock. Several threads may have a shared lock simultaneously in this
+lock, but only one writer may have an exclusive lock, in which case no
+shared locks are allowed. To prevent starving of a writer blocked by
+readers, a writer may queue for x-lock by decrementing lock_word: no
+new readers will be let in while the thread waits for readers to
+exit. */
struct rw_lock_struct {
volatile lint lock_word;
- /* Holds the state of the lock. */
- volatile ulint waiters;/* 1: there are waiters */
- volatile ibool recursive;/* Default value FALSE which means the lock
+ /*!< Holds the state of the lock. */
+ volatile ulint waiters;/*!< 1: there are waiters */
+ volatile ibool recursive;/*!< Default value FALSE which means the lock
is non-recursive. The value is typically set
to TRUE making normal rw_locks recursive. In
case of asynchronous IO, when a non-zero
@@ -503,59 +519,61 @@ struct rw_lock_struct {
This flag must be reset in x_unlock
functions before incrementing the lock_word */
volatile os_thread_id_t writer_thread;
- /* Thread id of writer thread. Is only
+ /*!< Thread id of writer thread. Is only
guaranteed to have sane and non-stale
value iff recursive flag is set. */
- os_event_t event; /* Used by sync0arr.c for thread queueing */
+ os_event_t event; /*!< Used by sync0arr.c for thread queueing */
os_event_t wait_ex_event;
- /* Event for next-writer to wait on. A thread
+ /*!< Event for next-writer to wait on. A thread
must decrement lock_word before waiting. */
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
- mutex_t mutex; /* The mutex protecting rw_lock_struct */
+ mutex_t mutex; /*!< The mutex protecting rw_lock_struct */
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
UT_LIST_NODE_T(rw_lock_t) list;
- /* All allocated rw locks are put into a
+ /*!< All allocated rw locks are put into a
list */
#ifdef UNIV_SYNC_DEBUG
UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list;
- /* In the debug version: pointer to the debug
+ /*!< In the debug version: pointer to the debug
info list of the lock */
- ulint level; /* Level in the global latching order. */
+ ulint level; /*!< Level in the global latching order. */
#endif /* UNIV_SYNC_DEBUG */
- ulint count_os_wait; /* Count of os_waits. May not be accurate */
- const char* cfile_name;/* File name where lock created */
+ ulint count_os_wait; /*!< Count of os_waits. May not be accurate */
+ //const char* cfile_name;/*!< File name where lock created */
+ const char* lock_name;/*!< lock name */
/* 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 */
+ 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
+ /*!< 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 */
- ulint magic_n;
+ //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 */
+ ulint magic_n; /*!< RW_LOCK_MAGIC_N */
};
+/** Value of rw_lock_struct::magic_n */
#define RW_LOCK_MAGIC_N 22643
#ifdef UNIV_SYNC_DEBUG
-/* The structure for storing debug info of an rw-lock */
+/** The structure for storing debug info of an rw-lock */
struct rw_lock_debug_struct {
- os_thread_id_t thread_id; /* The thread id of the thread which
+ os_thread_id_t thread_id; /*!< The thread id of the thread which
locked the rw-lock */
- ulint pass; /* Pass value given in the lock operation */
- ulint lock_type; /* Type of the lock: RW_LOCK_EX,
+ ulint pass; /*!< Pass value given in the lock operation */
+ ulint lock_type; /*!< Type of the lock: RW_LOCK_EX,
RW_LOCK_SHARED, RW_LOCK_WAIT_EX */
- const char* file_name;/* File name where the lock was obtained */
- ulint line; /* Line where the rw-lock was locked */
+ const char* file_name;/*!< File name where the lock was obtained */
+ ulint line; /*!< Line where the rw-lock was locked */
UT_LIST_NODE_T(rw_lock_debug_t) list;
- /* Debug structs are linked in a two-way
+ /*!< Debug structs are linked in a two-way
list */
};
#endif /* UNIV_SYNC_DEBUG */
@@ -563,5 +581,6 @@ struct rw_lock_debug_struct {
#ifndef UNIV_NONINL
#include "sync0rw.ic"
#endif
+#endif /* !UNIV_HOTBACKUP */
#endif
diff --git a/storage/xtradb/include/sync0rw.ic b/storage/xtradb/include/sync0rw.ic
index 9e7e4dc9bd8..7116f1b7c9b 100644
--- a/storage/xtradb/include/sync0rw.ic
+++ b/storage/xtradb/include/sync0rw.ic
@@ -23,13 +23,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0rw.ic
The read-write lock (for threads)
Created 9/11/1995 Heikki Tuuri
*******************************************************/
-/**********************************************************************
+/******************************************************************//**
Lock an rw-lock in shared mode for the current thread. If the rw-lock is
locked in exclusive mode, or there is an exclusive lock request waiting,
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS),
@@ -38,47 +39,47 @@ UNIV_INTERN
void
rw_lock_s_lock_spin(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line); /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Inserts the debug information for an rw-lock. */
UNIV_INTERN
void
rw_lock_add_debug_info(
/*===================*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint pass, /* in: pass value */
- ulint lock_type, /* in: lock type */
- const char* file_name, /* in: file where requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint pass, /*!< in: pass value */
+ ulint lock_type, /*!< in: lock type */
+ const char* file_name, /*!< in: file where requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
Removes a debug information struct for an rw-lock. */
UNIV_INTERN
void
rw_lock_remove_debug_info(
/*======================*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint pass, /* in: pass value */
- ulint lock_type); /* in: lock type */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint pass, /*!< in: pass value */
+ ulint lock_type); /*!< in: lock type */
#endif /* UNIV_SYNC_DEBUG */
-/************************************************************************
-Accessor functions for rw lock. */
+/********************************************************************//**
+Check if there are threads waiting for the rw-lock.
+@return 1 if waiters, 0 otherwise */
UNIV_INLINE
ulint
rw_lock_get_waiters(
/*================*/
- /* out: 1 if waiters, 0 otherwise */
- rw_lock_t* lock) /* in: rw-lock */
+ const rw_lock_t* lock) /*!< in: rw-lock */
{
return(lock->waiters);
}
-/************************************************************************
+/********************************************************************//**
Sets lock->waiters to 1. It is not an error if lock->waiters is already
1. On platforms where ATOMIC builtins are used this function enforces a
memory barrier. */
@@ -86,16 +87,16 @@ UNIV_INLINE
void
rw_lock_set_waiter_flag(
/*====================*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- os_compare_and_swap(&lock->waiters, 0, 1);
+ os_compare_and_swap_ulint(&lock->waiters, 0, 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->waiters = 1;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/************************************************************************
+/********************************************************************//**
Resets lock->waiters to 0. It is not an error if lock->waiters is already
0. On platforms where ATOMIC builtins are used this function enforces a
memory barrier. */
@@ -103,26 +104,27 @@ UNIV_INLINE
void
rw_lock_reset_waiter_flag(
/*======================*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- os_compare_and_swap(&lock->waiters, 1, 0);
+ os_compare_and_swap_ulint(&lock->waiters, 1, 0);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->waiters = 0;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/**********************************************************************
+/******************************************************************//**
Returns the write-status of the lock - this function made more sense
-with the old rw_lock implementation. */
+with the old rw_lock implementation.
+@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */
UNIV_INLINE
ulint
rw_lock_get_writer(
/*===============*/
- rw_lock_t* lock)
+ const rw_lock_t* lock) /*!< in: rw-lock */
{
lint lock_word = lock->lock_word;
- if(lock_word > 0) {
+ if (lock_word > 0) {
/* return NOT_LOCKED in s-lock state, like the writer
member of the old lock implementation. */
return(RW_LOCK_NOT_LOCKED);
@@ -134,16 +136,17 @@ rw_lock_get_writer(
}
}
-/**********************************************************************
-Returns number of readers. */
+/******************************************************************//**
+Returns the number of readers.
+@return number of readers */
UNIV_INLINE
ulint
rw_lock_get_reader_count(
/*=====================*/
- rw_lock_t* lock)
+ const rw_lock_t* lock) /*!< in: rw-lock */
{
lint lock_word = lock->lock_word;
- if(lock_word > 0) {
+ if (lock_word > 0) {
/* s-locked, no x-waiters */
return(X_LOCK_DECR - lock_word);
} else if (lock_word < 0 && lock_word > -X_LOCK_DECR) {
@@ -164,85 +167,74 @@ rw_lock_get_mutex(
}
#endif
-/**********************************************************************
+/******************************************************************//**
Returns the value of writer_count for the lock. Does not reserve the lock
-mutex, so the caller must be sure it is not changed during the call. */
+mutex, so the caller must be sure it is not changed during the call.
+@return value of writer_count */
UNIV_INLINE
ulint
rw_lock_get_x_lock_count(
/*=====================*/
- /* out: value of writer_count */
- rw_lock_t* lock) /* in: rw-lock */
+ const rw_lock_t* lock) /*!< in: rw-lock */
{
lint lock_copy = lock->lock_word;
/* If there is a reader, lock_word is not divisible by X_LOCK_DECR */
- if(lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) {
+ if (lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) {
return(0);
}
return(((-lock_copy) / X_LOCK_DECR) + 1);
}
-/**********************************************************************
+/******************************************************************//**
Two different implementations for decrementing the lock_word of a rw_lock:
one for systems supporting atomic operations, one for others. This does
does not support recusive x-locks: they should be handled by the caller and
need not be atomic since they are performed by the current lock holder.
-Returns true if the decrement was made, false if not. */
+Returns true if the decrement was made, false if not.
+@return TRUE if decr occurs */
UNIV_INLINE
ibool
rw_lock_lock_word_decr(
/*===================*/
- /* out: TRUE if decr occurs */
- rw_lock_t* lock, /* in: rw-lock */
- ulint amount) /* in: amount of decrement */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ ulint amount) /*!< in: amount to decrement */
{
-
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
-
lint local_lock_word = lock->lock_word;
while (local_lock_word > 0) {
- if(os_compare_and_swap(&(lock->lock_word),
- local_lock_word,
- local_lock_word - amount)) {
+ if (os_compare_and_swap_lint(&lock->lock_word,
+ local_lock_word,
+ local_lock_word - amount)) {
return(TRUE);
}
local_lock_word = lock->lock_word;
}
return(FALSE);
-
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
-
ibool success = FALSE;
mutex_enter(&(lock->mutex));
- if(lock->lock_word > 0) {
+ if (lock->lock_word > 0) {
lock->lock_word -= amount;
success = TRUE;
}
mutex_exit(&(lock->mutex));
return(success);
-
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/**********************************************************************
-Two different implementations for incrementing the lock_word of a rw_lock:
-one for systems supporting atomic operations, one for others.
-Returns the value of lock_word after increment. */
+/******************************************************************//**
+Increments lock_word the specified amount and returns new value.
+@return lock->lock_word after increment */
UNIV_INLINE
lint
rw_lock_lock_word_incr(
/*===================*/
- /* out: lock->lock_word after increment */
- rw_lock_t* lock, /* in: rw-lock */
- ulint amount) /* in: amount of increment */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ ulint amount) /*!< in: amount of increment */
{
-
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
-
- return(os_atomic_increment(&(lock->lock_word), amount));
-
+ return(os_atomic_increment_lint(&lock->lock_word, amount));
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
-
lint local_lock_word;
mutex_enter(&(lock->mutex));
@@ -253,11 +245,10 @@ rw_lock_lock_word_incr(
mutex_exit(&(lock->mutex));
return(local_lock_word);
-
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/**********************************************************************
+/******************************************************************//**
This function sets the lock->writer_thread and lock->recursive fields.
For platforms where we are using atomic builtins instead of lock->mutex
it sets the lock->writer_thread field using atomics to ensure memory
@@ -270,8 +261,8 @@ UNIV_INLINE
void
rw_lock_set_writer_id_and_recursion_flag(
/*=====================================*/
- rw_lock_t* lock, /* in/out: lock to work on */
- ibool recursive) /* in: TRUE if recursion
+ rw_lock_t* lock, /*!< in/out: lock to work on */
+ ibool recursive) /*!< in: TRUE if recursion
allowed */
{
os_thread_id_t curr_thread = os_thread_get_curr_id();
@@ -287,8 +278,8 @@ rw_lock_set_writer_id_and_recursion_flag(
UNIV_MEM_VALID(&lock->writer_thread, sizeof lock->writer_thread);
local_thread = lock->writer_thread;
- success = os_compare_and_swap(&lock->writer_thread,
- local_thread, curr_thread);
+ success = os_compare_and_swap_thread_id(
+ &lock->writer_thread, local_thread, curr_thread);
ut_a(success);
lock->recursive = recursive;
@@ -302,20 +293,20 @@ rw_lock_set_writer_id_and_recursion_flag(
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/**********************************************************************
+/******************************************************************//**
Low-level function which tries to lock an rw-lock in s-mode. Performs no
-spinning. */
+spinning.
+@return TRUE if success */
UNIV_INLINE
ibool
rw_lock_s_lock_low(
/*===============*/
- /* out: TRUE if success */
- rw_lock_t* lock, /* in: pointer to rw-lock */
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
ulint pass __attribute__((unused)),
- /* in: pass value; != 0, if the lock will be
+ /*!< in: pass value; != 0, if the lock will be
passed to another thread to unlock */
- const char* file_name, /* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name, /*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
/* TODO: study performance of UNIV_LIKELY branch prediction hints. */
if (!rw_lock_lock_word_decr(lock, 1)) {
@@ -334,7 +325,7 @@ rw_lock_s_lock_low(
return(TRUE); /* locking succeeded */
}
-/**********************************************************************
+/******************************************************************//**
Low-level function which locks an rw-lock in s-mode when we know that it
is possible and none else is currently accessing the rw-lock structure.
Then we can do the locking without reserving the mutex. */
@@ -342,9 +333,9 @@ UNIV_INLINE
void
rw_lock_s_lock_direct(
/*==================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name, /* in: file name where requested */
- ulint line) /* in: line where lock requested */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ const char* file_name, /*!< in: file name where requested */
+ ulint line) /*!< in: line where lock requested */
{
ut_ad(lock->lock_word == X_LOCK_DECR);
@@ -359,7 +350,7 @@ rw_lock_s_lock_direct(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Low-level function which locks an rw-lock in x-mode when we know that it
is not locked and none else is currently accessing the rw-lock structure.
Then we can do the locking without reserving the mutex. */
@@ -367,9 +358,9 @@ UNIV_INLINE
void
rw_lock_x_lock_direct(
/*==================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name, /* in: file name where requested */
- ulint line) /* in: line where lock requested */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ const char* file_name, /*!< in: file name where requested */
+ ulint line) /*!< in: line where lock requested */
{
ut_ad(rw_lock_validate(lock));
ut_ad(lock->lock_word == X_LOCK_DECR);
@@ -386,7 +377,7 @@ rw_lock_x_lock_direct(
#endif
}
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in shared mode for the current thread. If the rw-lock is locked
in exclusive mode, or there is an exclusive lock request waiting, the
@@ -396,11 +387,11 @@ UNIV_INLINE
void
rw_lock_s_lock_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
/* NOTE: As we do not know the thread ids for threads which have
s-locked a latch, and s-lockers will be served only after waiting
@@ -430,25 +421,25 @@ rw_lock_s_lock_func(
}
}
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread if the lock can be
-obtained immediately. */
+obtained immediately.
+@return TRUE if success */
UNIV_INLINE
ibool
rw_lock_x_lock_func_nowait(
/*=======================*/
- /* out: TRUE if success */
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
os_thread_id_t curr_thread = os_thread_get_curr_id();
ibool success;
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- success = os_compare_and_swap(&(lock->lock_word), X_LOCK_DECR, 0);
+ success = os_compare_and_swap_lint(&lock->lock_word, X_LOCK_DECR, 0);
#else
success = FALSE;
@@ -488,18 +479,17 @@ rw_lock_x_lock_func_nowait(
return(TRUE);
}
-/**********************************************************************
+/******************************************************************//**
Releases a shared mode lock. */
UNIV_INLINE
void
rw_lock_s_unlock_func(
/*==================*/
- rw_lock_t* lock /* in: rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ,ulint pass /* in: pass value; != 0, if the lock may have
+ ulint pass, /*!< in: pass value; != 0, if the lock may have
been passed to another thread to unlock */
#endif
- )
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
ut_ad((lock->lock_word % X_LOCK_DECR) != 0);
@@ -525,14 +515,14 @@ rw_lock_s_unlock_func(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Releases a shared mode lock when we know there are no waiters and none
else will access the lock during the time this function is executed. */
UNIV_INLINE
void
rw_lock_s_unlock_direct(
/*====================*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
ut_ad(lock->lock_word < X_LOCK_DECR);
@@ -550,18 +540,17 @@ rw_lock_s_unlock_direct(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Releases an exclusive mode lock. */
UNIV_INLINE
void
rw_lock_x_unlock_func(
/*==================*/
- rw_lock_t* lock /* in: rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ,ulint pass /* in: pass value; != 0, if the lock may have
+ ulint pass, /*!< in: pass value; != 0, if the lock may have
been passed to another thread to unlock */
#endif
- )
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
ut_ad((lock->lock_word % X_LOCK_DECR) == 0);
@@ -600,14 +589,14 @@ rw_lock_x_unlock_func(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Releases an exclusive mode lock when we know there are no waiters, and
none else will access the lock during the time this function is executed. */
UNIV_INLINE
void
rw_lock_x_unlock_direct(
/*====================*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
/* Reset the exclusive lock if this thread no longer has an x-mode
lock */
diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h
index dccfc020681..c653e44b5bd 100644
--- a/storage/xtradb/include/sync0sync.h
+++ b/storage/xtradb/include/sync0sync.h
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0sync.h
Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri
@@ -40,23 +41,30 @@ Created 9/5/1995 Heikki Tuuri
#include "os0sync.h"
#include "sync0arr.h"
-#ifndef UNIV_HOTBACKUP
+#if defined(UNIV_DEBUG) && !defined(UNIV_HOTBACKUP)
extern my_bool timed_mutexes;
-#endif /* UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-/**********************************************************************
+#ifdef HAVE_WINDOWS_ATOMICS
+typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
+ on LONG variable */
+#else
+typedef byte lock_word_t;
+#endif
+
+/******************************************************************//**
Initializes the synchronization data structures. */
UNIV_INTERN
void
sync_init(void);
/*===========*/
-/**********************************************************************
+/******************************************************************//**
Frees the resources in synchronization data structures. */
UNIV_INTERN
void
sync_close(void);
/*===========*/
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes a mutex object to a specified memory
location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
@@ -72,10 +80,10 @@ necessary only if the memory block containing it is freed. */
# endif
#else
# define mutex_create(M, level) \
- mutex_create_func((M), __FILE__, __LINE__)
+ mutex_create_func((M), #M, NULL, 0)
#endif
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes a mutex object in a specified memory
location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
@@ -84,19 +92,19 @@ UNIV_INTERN
void
mutex_create_func(
/*==============*/
- mutex_t* mutex, /* in: pointer to memory */
+ mutex_t* mutex, /*!< in: pointer to memory */
+ const char* cmutex_name, /*!< in: mutex name */
#ifdef UNIV_DEBUG
- const char* cmutex_name, /* in: mutex name */
# ifdef UNIV_SYNC_DEBUG
- ulint level, /* in: level */
+ ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
#endif /* UNIV_DEBUG */
- const char* cfile_name, /* in: file name where created */
- ulint cline); /* in: file line where created */
+ const char* cfile_name, /*!< in: file name where created */
+ ulint cline); /*!< in: file line where created */
#undef mutex_free /* Fix for MacOS X */
-/**********************************************************************
+/******************************************************************//**
Calling this function is obligatory only if the memory buffer containing
the mutex is freed. Removes a mutex object from the mutex list. The mutex
is checked to be in the reset state. */
@@ -104,20 +112,20 @@ UNIV_INTERN
void
mutex_free(
/*=======*/
- mutex_t* mutex); /* in: mutex */
-/******************************************************************
+ mutex_t* mutex); /*!< in: mutex */
+/**************************************************************//**
NOTE! The following macro should be used in mutex locking, not the
corresponding function. */
#define mutex_enter(M) mutex_enter_func((M), __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macro should be used in mutex locking, not the
corresponding function. */
/* NOTE! currently same as mutex_enter! */
#define mutex_enter_fast(M) mutex_enter_func((M), __FILE__, __LINE__)
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro in the header file, not this function
directly. Locks a mutex for the current thread. If the mutex is reserved
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting
@@ -126,78 +134,82 @@ UNIV_INLINE
void
mutex_enter_func(
/*=============*/
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where locked */
- ulint line); /* in: line where locked */
-/******************************************************************
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where locked */
+ ulint line); /*!< in: line where locked */
+/**************************************************************//**
NOTE! The following macro should be used in mutex locking, not the
corresponding function. */
#define mutex_enter_nowait(M) \
mutex_enter_nowait_func((M), __FILE__, __LINE__)
-/************************************************************************
+/********************************************************************//**
NOTE! Use the corresponding macro in the header file, not this function
directly. Tries to lock the mutex for the current thread. If the lock is not
-acquired immediately, returns with return value 1. */
+acquired immediately, returns with return value 1.
+@return 0 if succeed, 1 if not */
UNIV_INTERN
ulint
mutex_enter_nowait_func(
/*====================*/
- /* out: 0 if succeed, 1 if not */
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where mutex
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where mutex
requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
Unlocks a mutex owned by the current thread. */
UNIV_INLINE
void
mutex_exit(
/*=======*/
- mutex_t* mutex); /* in: pointer to mutex */
-/**********************************************************************
+ mutex_t* mutex); /*!< in: pointer to mutex */
+#ifdef UNIV_SYNC_DEBUG
+/******************************************************************//**
Returns TRUE if no mutex or rw-lock is currently locked.
-Works only in the debug version. */
+Works only in the debug version.
+@return TRUE if no mutexes and rw-locks reserved */
UNIV_INTERN
ibool
sync_all_freed(void);
/*================*/
+#endif /* UNIV_SYNC_DEBUG */
/*#####################################################################
FUNCTION PROTOTYPES FOR DEBUGGING */
-/***********************************************************************
+/*******************************************************************//**
Prints wait info of the sync system. */
UNIV_INTERN
void
sync_print_wait_info(
/*=================*/
- FILE* file); /* in: file where to print */
-/***********************************************************************
+ FILE* file); /*!< in: file where to print */
+/*******************************************************************//**
Prints info of the sync system. */
UNIV_INTERN
void
sync_print(
/*=======*/
- FILE* file); /* in: file where to print */
+ FILE* file); /*!< in: file where to print */
#ifdef UNIV_DEBUG
-/**********************************************************************
-Checks that the mutex has been initialized. */
+/******************************************************************//**
+Checks that the mutex has been initialized.
+@return TRUE */
UNIV_INTERN
ibool
mutex_validate(
/*===========*/
- const mutex_t* mutex);
-/**********************************************************************
+ const mutex_t* mutex); /*!< in: mutex */
+/******************************************************************//**
Checks that the current thread owns the mutex. Works only
-in the debug version. */
+in the debug version.
+@return TRUE if owns */
UNIV_INTERN
ibool
mutex_own(
/*======*/
- /* out: TRUE if owns */
- const mutex_t* mutex); /* in: mutex */
+ const mutex_t* mutex); /*!< in: mutex */
#endif /* UNIV_DEBUG */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Adds a latch and its level in the thread level array. Allocates the memory
for the array if called first time for this OS thread. Makes the checks
against other latch levels stored in the array for this thread. */
@@ -205,75 +217,74 @@ UNIV_INTERN
void
sync_thread_add_level(
/*==================*/
- void* latch, /* in: pointer to a mutex or an rw-lock */
- ulint level); /* in: level in the latching order; if
+ void* latch, /*!< in: pointer to a mutex or an rw-lock */
+ ulint level); /*!< in: level in the latching order; if
SYNC_LEVEL_VARYING, nothing is done */
-/**********************************************************************
-Removes a latch from the thread level array if it is found there. */
+/******************************************************************//**
+Removes a latch from the thread level array if it is found there.
+@return TRUE if found in the array; it is no error if the latch is
+not found, as we presently are not able to determine the level for
+every latch reservation the program does */
UNIV_INTERN
ibool
sync_thread_reset_level(
/*====================*/
- /* out: TRUE if found from the array; it is no error
- if the latch is not found, as we presently are not
- able to determine the level for every latch
- reservation the program does */
- void* latch); /* in: pointer to a mutex or an rw-lock */
-/**********************************************************************
-Checks that the level array for the current thread is empty. */
+ void* latch); /*!< in: pointer to a mutex or an rw-lock */
+/******************************************************************//**
+Checks that the level array for the current thread is empty.
+@return TRUE if empty */
UNIV_INTERN
ibool
sync_thread_levels_empty(void);
/*==========================*/
- /* out: TRUE if empty */
-/**********************************************************************
-Checks that the level array for the current thread is empty. */
+/******************************************************************//**
+Checks that the level array for the current thread is empty.
+@return TRUE if empty except the exceptions specified below */
UNIV_INTERN
ibool
sync_thread_levels_empty_gen(
/*=========================*/
- /* out: TRUE if empty except the
- exceptions specified below */
- ibool dict_mutex_allowed); /* in: TRUE if dictionary mutex is
+ ibool dict_mutex_allowed); /*!< in: TRUE if dictionary mutex is
allowed to be owned by the thread,
also purge_is_running mutex is
allowed */
-/**********************************************************************
+/******************************************************************//**
Gets the debug information for a reserved mutex. */
UNIV_INTERN
void
mutex_get_debug_info(
/*=================*/
- mutex_t* mutex, /* in: mutex */
- const char** file_name, /* out: file where requested */
- ulint* line, /* out: line where requested */
- os_thread_id_t* thread_id); /* out: id of the thread which owns
+ mutex_t* mutex, /*!< in: mutex */
+ const char** file_name, /*!< out: file where requested */
+ ulint* line, /*!< out: line where requested */
+ os_thread_id_t* thread_id); /*!< out: id of the thread which owns
the mutex */
-/**********************************************************************
-Counts currently reserved mutexes. Works only in the debug version. */
+/******************************************************************//**
+Counts currently reserved mutexes. Works only in the debug version.
+@return number of reserved mutexes */
UNIV_INTERN
ulint
mutex_n_reserved(void);
/*==================*/
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
NOT to be used outside this module except in debugging! Gets the value
of the lock word. */
UNIV_INLINE
-byte
+lock_word_t
mutex_get_lock_word(
/*================*/
- const mutex_t* mutex); /* in: mutex */
+ const mutex_t* mutex); /*!< in: mutex */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
NOT to be used outside this module except in debugging! Gets the waiters
-field in a mutex. */
+field in a mutex.
+@return value to set */
UNIV_INLINE
ulint
mutex_get_waiters(
/*==============*/
- /* out: value to set */
- const mutex_t* mutex); /* in: mutex */
+ const mutex_t* mutex); /*!< in: mutex */
#endif /* UNIV_SYNC_DEBUG */
/*
@@ -490,81 +501,79 @@ or row lock! */
Do not use its fields directly! The structure used in the spin lock
implementation of a mutual exclusion semaphore. */
+/** InnoDB mutex */
struct mutex_struct {
- os_event_t event; /* Used by sync0arr.c for the wait queue */
- byte lock_word; /* This byte is the target of the atomic
- test-and-set instruction in Win32 and
- x86 32/64 with GCC 4.1.0 or later version */
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
-#else
+ os_event_t event; /*!< Used by sync0arr.c for the wait queue */
+ volatile lock_word_t lock_word; /*!< lock_word is the target
+ of the atomic test-and-set instruction when
+ atomic operations are enabled. */
+
+#if !defined(HAVE_ATOMIC_BUILTINS)
os_fast_mutex_t
- os_fast_mutex; /* In other systems we use this OS mutex
- in place of lock_word */
+ os_fast_mutex; /*!< We use this OS mutex in place of lock_word
+ when atomic operations are not enabled */
#endif
- ulint waiters; /* This ulint is set to 1 if there are (or
+ volatile ulint waiters; /*!< This ulint is set to 1 if there are (or
may be) threads waiting in the global wait
array for this mutex to be released.
Otherwise, this is 0. */
- UT_LIST_NODE_T(mutex_t) list; /* All allocated mutexes are put into
+ UT_LIST_NODE_T(mutex_t) list; /*!< All allocated mutexes are put into
a list. Pointers to the next and prev. */
#ifdef UNIV_SYNC_DEBUG
- const char* file_name; /* File where the mutex was locked */
- ulint line; /* Line where the mutex was locked */
- ulint level; /* Level in the global latching order */
+ const char* file_name; /*!< File where the mutex was locked */
+ ulint line; /*!< Line where the mutex was locked */
+ ulint level; /*!< Level in the global latching order */
#endif /* UNIV_SYNC_DEBUG */
- const char* cfile_name;/* File name where mutex created */
- ulint cline; /* Line where created */
#ifdef UNIV_DEBUG
- os_thread_id_t thread_id; /* The thread id of the thread
+ const char* cfile_name;/*!< File name where mutex created */
+ ulint cline; /*!< Line where created */
+ os_thread_id_t thread_id; /*!< The thread id of the thread
which locked the mutex. */
- ulint magic_n;
+ ulint magic_n; /*!< MUTEX_MAGIC_N */
+/** Value of mutex_struct::magic_n */
# define MUTEX_MAGIC_N (ulint)979585
#endif /* UNIV_DEBUG */
-#ifndef UNIV_HOTBACKUP
- ulong count_os_wait; /* count of os_wait */
-# ifdef UNIV_DEBUG
- ulong count_using; /* count of times mutex used */
- ulong count_spin_loop; /* count of spin loops */
- ulong count_spin_rounds; /* count of spin rounds */
- ulong count_os_yield; /* count of os_wait */
- ulonglong lspent_time; /* mutex os_wait timer msec */
- ulonglong lmax_spent_time; /* mutex os_wait timer msec */
- const char* cmutex_name;/* mutex name */
- ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */
-# endif /* UNIV_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
+ ulong count_os_wait; /*!< count of os_wait */
+#ifdef UNIV_DEBUG
+ ulong count_using; /*!< count of times mutex used */
+ ulong count_spin_loop; /*!< count of spin loops */
+ ulong count_spin_rounds;/*!< count of spin rounds */
+ ulong count_os_yield; /*!< count of os_wait */
+ ulonglong lspent_time; /*!< mutex os_wait timer msec */
+ ulonglong lmax_spent_time;/*!< mutex os_wait timer msec */
+ ulint mutex_type; /*!< 0=usual mutex, 1=rw_lock mutex */
+#endif /* UNIV_DEBUG */
+ const char* cmutex_name; /*!< mutex name */
};
-/* The global array of wait cells for implementation of the databases own
-mutexes and read-write locks. Appears here for debugging purposes only! */
+/** The global array of wait cells for implementation of the databases own
+mutexes and read-write locks. */
+extern sync_array_t* sync_primary_wait_array;/* Appears here for
+ debugging purposes only! */
-extern sync_array_t* sync_primary_wait_array;
-
-/* Constant determining how long spin wait is continued before suspending
+/** Constant determining how long spin wait is continued before suspending
the thread. A value 600 rounds on a 1995 100 MHz Pentium seems to correspond
to 20 microseconds. */
#define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds
-/* The number of system calls made in this module. Intended for performance
-monitoring. */
-
+/** The number of mutex_exit calls. Intended for performance monitoring. */
extern ib_int64_t mutex_exit_count;
#ifdef UNIV_SYNC_DEBUG
-/* Latching order checks start when this is set TRUE */
+/** Latching order checks start when this is set TRUE */
extern ibool sync_order_checks_on;
#endif /* UNIV_SYNC_DEBUG */
-/* This variable is set to TRUE when sync_init is called */
+/** This variable is set to TRUE when sync_init is called */
extern ibool sync_initialized;
-/* Global list of database mutexes (not OS mutexes) created. */
+/** Global list of database mutexes (not OS mutexes) created. */
typedef UT_LIST_BASE_NODE_T(mutex_t) ut_list_base_node_t;
+/** Global list of database mutexes (not OS mutexes) created. */
extern ut_list_base_node_t mutex_list;
-/* Mutex protecting the mutex_list variable */
+/** Mutex protecting the mutex_list variable */
extern mutex_t mutex_list_mutex;
diff --git a/storage/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic
index c43121ebd0b..b05020b5660 100644
--- a/storage/xtradb/include/sync0sync.ic
+++ b/storage/xtradb/include/sync0sync.ic
@@ -23,21 +23,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0sync.ic
Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri
*******************************************************/
-/**********************************************************************
+/******************************************************************//**
Sets the waiters field in a mutex. */
UNIV_INTERN
void
mutex_set_waiters(
/*==============*/
- mutex_t* mutex, /* in: mutex */
- ulint n); /* in: value to set */
-/**********************************************************************
+ mutex_t* mutex, /*!< in: mutex */
+ ulint n); /*!< in: value to set */
+/******************************************************************//**
Reserves a mutex for the current thread. If the mutex is reserved, the
function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting
for the mutex before suspending the thread. */
@@ -45,74 +46,41 @@ UNIV_INTERN
void
mutex_spin_wait(
/*============*/
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where mutex
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where mutex
requested */
- ulint line); /* in: line where requested */
+ ulint line); /*!< in: line where requested */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Sets the debug information for a reserved mutex. */
UNIV_INTERN
void
mutex_set_debug_info(
/*=================*/
- mutex_t* mutex, /* in: mutex */
- const char* file_name, /* in: file where requested */
- ulint line); /* in: line where requested */
+ mutex_t* mutex, /*!< in: mutex */
+ const char* file_name, /*!< in: file where requested */
+ ulint line); /*!< in: line where requested */
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Releases the threads waiting in the primary wait array for this mutex. */
UNIV_INTERN
void
mutex_signal_object(
/*================*/
- mutex_t* mutex); /* in: mutex */
+ mutex_t* mutex); /*!< in: mutex */
-/**********************************************************************
+/******************************************************************//**
Performs an atomic test-and-set instruction to the lock_word field of a
-mutex. */
+mutex.
+@return the previous value of lock_word: 0 or 1 */
UNIV_INLINE
byte
mutex_test_and_set(
/*===============*/
- /* out: the previous value of lock_word: 0 or
- 1 */
- mutex_t* mutex) /* in: mutex */
+ mutex_t* mutex) /*!< in: mutex */
{
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
- byte res;
- byte* lw; /* assembler code is used to ensure that
- lock_word is loaded from memory */
- ut_ad(mutex);
- ut_ad(sizeof(byte) == 1);
-
- lw = &(mutex->lock_word);
-
- __asm MOV ECX, lw
- __asm MOV EDX, 1
- __asm XCHG DL, BYTE PTR [ECX]
- __asm MOV res, DL
-
- /* The fence below would prevent this thread from
- reading the data structure protected by the mutex
- before the test-and-set operation is committed, but
- the fence is apparently not needed:
-
- In a posting to comp.arch newsgroup (August 10, 1997)
- Andy Glew said that in P6 a LOCKed instruction like
- XCHG establishes a fence with respect to memory reads
- and writes and thus an explicit fence is not
- needed. In P5 he seemed to agree with a previous
- newsgroup poster that LOCKed instructions serialize
- all instruction execution, and, consequently, also
- memory operations. This is confirmed in Intel Software
- Dev. Manual, Vol. 3. */
-
- /* mutex_fence(); */
-
- return(res);
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
- return __sync_lock_test_and_set(&(mutex->lock_word), 1);
+#if defined(HAVE_ATOMIC_BUILTINS)
+ return(os_atomic_test_and_set_byte(&mutex->lock_word, 1));
#else
ibool ret;
@@ -130,30 +98,20 @@ mutex_test_and_set(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Performs a reset instruction to the lock_word field of a mutex. This
instruction also serializes memory operations to the program order. */
UNIV_INLINE
void
mutex_reset_lock_word(
/*==================*/
- mutex_t* mutex) /* in: mutex */
+ mutex_t* mutex) /*!< in: mutex */
{
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
- byte* lw; /* assembler code is used to ensure that
- lock_word is loaded from memory */
- ut_ad(mutex);
-
- lw = &(mutex->lock_word);
-
- __asm MOV EDX, 0
- __asm MOV ECX, lw
- __asm XCHG DL, BYTE PTR [ECX]
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
+#if defined(HAVE_ATOMIC_BUILTINS)
/* In theory __sync_lock_release should be used to release the lock.
Unfortunately, it does not work properly alone. The workaround is
that more conservative __sync_lock_test_and_set is used instead. */
- __sync_lock_test_and_set(&(mutex->lock_word), 0);
+ os_atomic_test_and_set_byte(&mutex->lock_word, 0);
#else
mutex->lock_word = 0;
@@ -161,33 +119,29 @@ mutex_reset_lock_word(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Gets the value of the lock word. */
UNIV_INLINE
-byte
+lock_word_t
mutex_get_lock_word(
/*================*/
- const mutex_t* mutex) /* in: mutex */
+ const mutex_t* mutex) /*!< in: mutex */
{
- const volatile byte* ptr; /* declared volatile to ensure that
- lock_word is loaded from memory */
ut_ad(mutex);
- ptr = &(mutex->lock_word);
-
- return(*ptr);
+ return(mutex->lock_word);
}
-/**********************************************************************
-Gets the waiters field in a mutex. */
+/******************************************************************//**
+Gets the waiters field in a mutex.
+@return value to set */
UNIV_INLINE
ulint
mutex_get_waiters(
/*==============*/
- /* out: value to set */
- const mutex_t* mutex) /* in: mutex */
+ const mutex_t* mutex) /*!< in: mutex */
{
- const volatile ulint* ptr; /* declared volatile to ensure that
+ const volatile ulint* ptr; /*!< declared volatile to ensure that
the value is read from memory */
ut_ad(mutex);
@@ -197,13 +151,13 @@ mutex_get_waiters(
word from memory is atomic */
}
-/**********************************************************************
+/******************************************************************//**
Unlocks a mutex owned by the current thread. */
UNIV_INLINE
void
mutex_exit(
/*=======*/
- mutex_t* mutex) /* in: pointer to mutex */
+ mutex_t* mutex) /*!< in: pointer to mutex */
{
ut_ad(mutex_own(mutex));
@@ -236,7 +190,7 @@ mutex_exit(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Locks a mutex for the current thread. If the mutex is reserved, the function
spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting for the mutex
before suspending the thread. */
@@ -244,9 +198,9 @@ UNIV_INLINE
void
mutex_enter_func(
/*=============*/
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where locked */
- ulint line) /* in: line where locked */
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where locked */
+ ulint line) /*!< in: line where locked */
{
ut_ad(mutex_validate(mutex));
ut_ad(!mutex_own(mutex));
@@ -254,9 +208,7 @@ mutex_enter_func(
/* Note that we do not peek at the value of lock_word before trying
the atomic test_and_set; we could peek, and possibly save time. */
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
- mutex->count_using++;
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+ ut_d(mutex->count_using++);
if (!mutex_test_and_set(mutex)) {
ut_d(mutex->thread_id = os_thread_get_curr_id());
diff --git a/storage/xtradb/include/sync0types.h b/storage/xtradb/include/sync0types.h
index 3c1021b1a30..1911bbac7fd 100644
--- a/storage/xtradb/include/sync0types.h
+++ b/storage/xtradb/include/sync0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0types.h
Global types for sync
Created 9/5/1995 Heikki Tuuri
@@ -25,7 +26,9 @@ Created 9/5/1995 Heikki Tuuri
#ifndef sync0types_h
#define sync0types_h
+/** Rename mutex_t to avoid name space collision on some systems */
#define mutex_t ib_mutex_t
+/** InnoDB mutex */
typedef struct mutex_struct mutex_t;
#endif
diff --git a/storage/xtradb/include/thr0loc.h b/storage/xtradb/include/thr0loc.h
index 96ec13cc8e4..293d1ebd57f 100644
--- a/storage/xtradb/include/thr0loc.h
+++ b/storage/xtradb/include/thr0loc.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/thr0loc.h
The thread local storage
Created 10/5/1995 Heikki Tuuri
@@ -32,49 +33,55 @@ OS handle to the current thread, or its priority. */
#include "univ.i"
#include "os0thread.h"
-/********************************************************************
+/****************************************************************//**
Initializes the thread local storage module. */
UNIV_INTERN
void
thr_local_init(void);
/*================*/
-/***********************************************************************
+ /****************************************************************//**
+Close the thread local storage module. */
+UNIV_INTERN
+void
+thr_local_close(void);
+/*=================*/
+/*******************************************************************//**
Creates a local storage struct for the calling new thread. */
UNIV_INTERN
void
thr_local_create(void);
/*==================*/
-/***********************************************************************
+/*******************************************************************//**
Frees the local storage struct for the specified thread. */
UNIV_INTERN
void
thr_local_free(
/*===========*/
- os_thread_id_t id); /* in: thread id */
-/***********************************************************************
-Gets the slot number in the thread table of a thread. */
+ os_thread_id_t id); /*!< in: thread id */
+/*******************************************************************//**
+Gets the slot number in the thread table of a thread.
+@return slot number */
UNIV_INTERN
ulint
thr_local_get_slot_no(
/*==================*/
- /* out: slot number */
- os_thread_id_t id); /* in: thread id of the thread */
-/***********************************************************************
+ os_thread_id_t id); /*!< in: thread id of the thread */
+/*******************************************************************//**
Sets in the local storage the slot number in the thread table of a thread. */
UNIV_INTERN
void
thr_local_set_slot_no(
/*==================*/
- os_thread_id_t id, /* in: thread id of the thread */
- ulint slot_no);/* in: slot number */
-/***********************************************************************
+ os_thread_id_t id, /*!< in: thread id of the thread */
+ ulint slot_no);/*!< in: slot number */
+/*******************************************************************//**
Returns pointer to the 'in_ibuf' field within the current thread local
-storage. */
+storage.
+@return pointer to the in_ibuf field */
UNIV_INTERN
ibool*
thr_local_get_in_ibuf_field(void);
/*=============================*/
- /* out: pointer to the in_ibuf field */
/*************************************************************************
Return local hash table informations. */
diff --git a/storage/xtradb/include/thr0loc.ic b/storage/xtradb/include/thr0loc.ic
index 6de183fd857..ce44e512320 100644
--- a/storage/xtradb/include/thr0loc.ic
+++ b/storage/xtradb/include/thr0loc.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/thr0loc.ic
Thread local storage
Created 10/4/1995 Heikki Tuuri
diff --git a/storage/xtradb/include/trx0i_s.h b/storage/xtradb/include/trx0i_s.h
index cf2865af127..7bd4e1b88c8 100644
--- a/storage/xtradb/include/trx0i_s.h
+++ b/storage/xtradb/include/trx0i_s.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0i_s.h
INFORMATION SCHEMA innodb_trx, innodb_locks and
innodb_lock_waits tables cache structures and public
functions.
@@ -31,182 +32,216 @@ Created July 17, 2007 Vasil Dimov
#include "trx0types.h"
#include "ut0ut.h"
-/* the maximum amount of memory that can be consumed by innodb_trx,
+/** The maximum amount of memory that can be consumed by innodb_trx,
innodb_locks and innodb_lock_waits information schema tables. */
#define TRX_I_S_MEM_LIMIT 16777216 /* 16 MiB */
-/* the maximum length of a string that can be stored in
+/** The maximum length of a string that can be stored in
i_s_locks_row_t::lock_data */
#define TRX_I_S_LOCK_DATA_MAX_LEN 8192
-/* the maximum length of a string that can be stored in
+/** The maximum length of a string that can be stored in
i_s_trx_row_t::trx_query */
#define TRX_I_S_TRX_QUERY_MAX_LEN 1024
+/** A row of INFORMATION_SCHEMA.innodb_locks */
typedef struct i_s_locks_row_struct i_s_locks_row_t;
+/** A row of INFORMATION_SCHEMA.innodb_trx */
+typedef struct i_s_trx_row_struct i_s_trx_row_t;
+/** A row of INFORMATION_SCHEMA.innodb_lock_waits */
+typedef struct i_s_lock_waits_row_struct i_s_lock_waits_row_t;
+
+/** Objects of trx_i_s_cache_t::locks_hash */
typedef struct i_s_hash_chain_struct i_s_hash_chain_t;
-/* Objects of this type are added to the hash table
+/** Objects of this type are added to the hash table
trx_i_s_cache_t::locks_hash */
struct i_s_hash_chain_struct {
- i_s_locks_row_t* value;
- i_s_hash_chain_t* next;
+ i_s_locks_row_t* value; /*!< row of
+ INFORMATION_SCHEMA.innodb_locks*/
+ i_s_hash_chain_t* next; /*!< next item in the hash chain */
};
-/* This structure represents INFORMATION_SCHEMA.innodb_locks row */
+/** This structure represents INFORMATION_SCHEMA.innodb_locks row */
struct i_s_locks_row_struct {
- ullint lock_trx_id;
- const char* lock_mode;
- const char* lock_type;
- const char* lock_table;
- const char* lock_index;
- ulint lock_space;
- ulint lock_page;
- ulint lock_rec;
- const char* lock_data;
-
- /* The following are auxiliary and not included in the table */
+ ullint lock_trx_id; /*!< transaction identifier */
+ const char* lock_mode; /*!< lock mode from
+ lock_get_mode_str() */
+ const char* lock_type; /*!< lock type from
+ lock_get_type_str() */
+ const char* lock_table; /*!< table name from
+ lock_get_table_name() */
+ const char* lock_index; /*!< index name from
+ lock_rec_get_index_name() */
+ /** Information for record locks. All these are
+ ULINT_UNDEFINED for table locks. */
+ /* @{ */
+ ulint lock_space; /*!< tablespace identifier */
+ ulint lock_page; /*!< page number within the_space */
+ ulint lock_rec; /*!< heap number of the record
+ on the page */
+ const char* lock_data; /*!< (some) content of the record */
+ /* @} */
+
+ /** The following are auxiliary and not included in the table */
+ /* @{ */
ullint lock_table_id;
- i_s_hash_chain_t hash_chain; /* this object is added to the hash
- table
- trx_i_s_cache_t::locks_hash */
+ /*!< table identifier from
+ lock_get_table_id */
+ i_s_hash_chain_t hash_chain; /*!< hash table chain node for
+ trx_i_s_cache_t::locks_hash */
+ /* @} */
};
-/* This structure represents INFORMATION_SCHEMA.innodb_trx row */
-typedef struct i_s_trx_row_struct {
- ullint trx_id;
- const char* trx_state;
- ib_time_t trx_started;
+/** This structure represents INFORMATION_SCHEMA.innodb_trx row */
+struct i_s_trx_row_struct {
+ ullint trx_id; /*!< transaction identifier */
+ const char* trx_state; /*!< transaction state from
+ trx_get_que_state_str() */
+ ib_time_t trx_started; /*!< trx_struct::start_time */
const i_s_locks_row_t* requested_lock_row;
+ /*!< pointer to a row
+ in innodb_locks if trx
+ is waiting, or NULL */
ib_time_t trx_wait_started;
- ullint trx_weight;
+ /*!< trx_struct::wait_started */
+ ullint trx_weight; /*!< TRX_WEIGHT() */
ulint trx_mysql_thread_id;
- const char* trx_query;
-} i_s_trx_row_t;
+ /*!< thd_get_thread_id() */
+ const char* trx_query; /*!< MySQL statement being
+ executed in the transaction */
+};
-/* This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */
-typedef struct i_s_lock_waits_row_struct {
- const i_s_locks_row_t* requested_lock_row;
- const i_s_locks_row_t* blocking_lock_row;
-} i_s_lock_waits_row_t;
+/** This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */
+struct i_s_lock_waits_row_struct {
+ const i_s_locks_row_t* requested_lock_row; /*!< requested lock */
+ const i_s_locks_row_t* blocking_lock_row; /*!< blocking lock */
+};
-/* This type is opaque and is defined in trx/trx0i_s.c */
+/** Cache of INFORMATION_SCHEMA table data */
typedef struct trx_i_s_cache_struct trx_i_s_cache_t;
-/* Auxiliary enum used by functions that need to select one of the
+/** Auxiliary enum used by functions that need to select one of the
INFORMATION_SCHEMA tables */
enum i_s_table {
- I_S_INNODB_TRX,
- I_S_INNODB_LOCKS,
- I_S_INNODB_LOCK_WAITS
+ I_S_INNODB_TRX, /*!< INFORMATION_SCHEMA.innodb_trx */
+ I_S_INNODB_LOCKS, /*!< INFORMATION_SCHEMA.innodb_locks */
+ I_S_INNODB_LOCK_WAITS /*!< INFORMATION_SCHEMA.innodb_lock_waits */
};
-/* This is the intermediate buffer where data needed to fill the
+/** This is the intermediate buffer where data needed to fill the
INFORMATION SCHEMA tables is fetched and later retrieved by the C++
code in handler/i_s.cc. */
extern trx_i_s_cache_t* trx_i_s_cache;
-/***********************************************************************
+/*******************************************************************//**
Initialize INFORMATION SCHEMA trx related cache. */
UNIV_INTERN
void
trx_i_s_cache_init(
/*===============*/
- trx_i_s_cache_t* cache); /* out: cache to init */
+ trx_i_s_cache_t* cache); /*!< out: cache to init */
+/*******************************************************************//**
+Free the INFORMATION SCHEMA trx related cache. */
+UNIV_INTERN
+void
+trx_i_s_cache_free(
+/*===============*/
+ trx_i_s_cache_t* cache); /*!< in/out: cache to free */
-/***********************************************************************
+/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_start_read(
/*=====================*/
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/***********************************************************************
+/*******************************************************************//**
Release a shared/read lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_end_read(
/*===================*/
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/***********************************************************************
+/*******************************************************************//**
Issue an exclusive/write lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_start_write(
/*======================*/
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/***********************************************************************
+/*******************************************************************//**
Release an exclusive/write lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_end_write(
/*====================*/
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/***********************************************************************
+/*******************************************************************//**
Retrieves the number of used rows in the cache for a given
-INFORMATION SCHEMA table. */
+INFORMATION SCHEMA table.
+@return number of rows */
UNIV_INTERN
ulint
trx_i_s_cache_get_rows_used(
/*========================*/
- /* out: number of rows */
- trx_i_s_cache_t* cache, /* in: cache */
- enum i_s_table table); /* in: which table */
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ enum i_s_table table); /*!< in: which table */
-/***********************************************************************
+/*******************************************************************//**
Retrieves the nth row in the cache for a given INFORMATION SCHEMA
-table. */
+table.
+@return row */
UNIV_INTERN
void*
trx_i_s_cache_get_nth_row(
/*======================*/
- /* out: row */
- trx_i_s_cache_t* cache, /* in: cache */
- enum i_s_table table, /* in: which table */
- ulint n); /* in: row number */
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ enum i_s_table table, /*!< in: which table */
+ ulint n); /*!< in: row number */
-/***********************************************************************
-Update the transactions cache if it has not been read for some time. */
+/*******************************************************************//**
+Update the transactions cache if it has not been read for some time.
+@return 0 - fetched, 1 - not */
UNIV_INTERN
int
trx_i_s_possibly_fetch_data_into_cache(
/*===================================*/
- /* out: 0 - fetched, 1 - not */
- trx_i_s_cache_t* cache); /* in/out: cache */
+ trx_i_s_cache_t* cache); /*!< in/out: cache */
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if the data in the cache is truncated due to the memory
-limit posed by TRX_I_S_MEM_LIMIT. */
+limit posed by TRX_I_S_MEM_LIMIT.
+@return TRUE if truncated */
UNIV_INTERN
ibool
trx_i_s_cache_is_truncated(
/*=======================*/
- /* out: TRUE if truncated */
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/* The maximum length of a resulting lock_id_size in
-trx_i_s_create_lock_id(), not including the terminating '\0'.
+/** The maximum length of a resulting lock_id_size in
+trx_i_s_create_lock_id(), not including the terminating NUL.
":%lu:%lu:%lu" -> 63 chars */
#define TRX_I_S_LOCK_ID_MAX_LEN (TRX_ID_MAX_LEN + 63)
-/***********************************************************************
+/*******************************************************************//**
Crafts a lock id string from a i_s_locks_row_t object. Returns its
second argument. This function aborts if there is not enough space in
lock_id. Be sure to provide at least TRX_I_S_LOCK_ID_MAX_LEN + 1 if you
-want to be 100% sure that it will not abort. */
+want to be 100% sure that it will not abort.
+@return resulting lock id */
UNIV_INTERN
char*
trx_i_s_create_lock_id(
/*===================*/
- /* out: resulting lock id */
- const i_s_locks_row_t* row, /* in: innodb_locks row */
- char* lock_id,/* out: resulting lock_id */
- ulint lock_id_size);/* in: size of the lock id
+ const i_s_locks_row_t* row, /*!< in: innodb_locks row */
+ char* lock_id,/*!< out: resulting lock_id */
+ ulint lock_id_size);/*!< in: size of the lock id
buffer */
#endif /* trx0i_s_h */
diff --git a/storage/xtradb/include/trx0purge.h b/storage/xtradb/include/trx0purge.h
index 4921b860485..ae5bc6f90be 100644
--- a/storage/xtradb/include/trx0purge.h
+++ b/storage/xtradb/include/trx0purge.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0purge.h
Purge old versions
Created 3/26/1996 Heikki Tuuri
@@ -34,41 +35,47 @@ Created 3/26/1996 Heikki Tuuri
#include "usr0sess.h"
#include "fil0fil.h"
-/* The global data structure coordinating a purge */
+/** The global data structure coordinating a purge */
extern trx_purge_t* purge_sys;
-/* A dummy undo record used as a return value when we have a whole undo log
+/** A dummy undo record used as a return value when we have a whole undo log
which needs no purge */
extern trx_undo_rec_t trx_purge_dummy_rec;
-/************************************************************************
+/********************************************************************//**
Calculates the file address of an undo log header when we have the file
-address of its history list node. */
+address of its history list node.
+@return file address of the log */
UNIV_INLINE
fil_addr_t
trx_purge_get_log_from_hist(
/*========================*/
- /* out: file address of the log */
- fil_addr_t node_addr); /* in: file address of the history
+ fil_addr_t node_addr); /*!< in: file address of the history
list node of the log */
-/*********************************************************************
+/*****************************************************************//**
Checks if trx_id is >= purge_view: then it is guaranteed that its update
-undo log still exists in the system. */
+undo log still exists in the system.
+@return TRUE if is sure that it is preserved, also if the function
+returns FALSE, it is possible that the undo log still exists in the
+system */
UNIV_INTERN
ibool
trx_purge_update_undo_must_exist(
/*=============================*/
- /* out: TRUE if is sure that it is preserved, also
- if the function returns FALSE, it is possible that
- the undo log still exists in the system */
- dulint trx_id);/* in: transaction id */
-/************************************************************************
+ trx_id_t trx_id);/*!< in: transaction id */
+/********************************************************************//**
Creates the global purge system control structure and inits the history
mutex. */
UNIV_INTERN
void
trx_purge_sys_create(void);
/*======================*/
+/********************************************************************//**
+Frees the global purge system control structure. */
+UNIV_INTERN
+void
+trx_purge_sys_close(void);
+/*======================*/
/************************************************************************
Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */
@@ -76,101 +83,122 @@ UNIV_INTERN
void
trx_purge_add_update_undo_to_history(
/*=================================*/
- trx_t* trx, /* in: transaction */
- page_t* undo_page, /* in: update undo log header page,
+ trx_t* trx, /*!< in: transaction */
+ page_t* undo_page, /*!< in: update undo log header page,
x-latched */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
Fetches the next undo log record from the history list to purge. It must be
-released with the corresponding release function. */
+released with the corresponding release function.
+@return copy of an undo log record or pointer to trx_purge_dummy_rec,
+if the whole undo log can skipped in purge; NULL if none left */
UNIV_INTERN
trx_undo_rec_t*
trx_purge_fetch_next_rec(
/*=====================*/
- /* out: copy of an undo log record, or
- pointer to the dummy undo log record
- &trx_purge_dummy_rec if the whole undo log
- can skipped in purge; NULL if none left */
- dulint* roll_ptr,/* out: roll pointer to undo record */
- trx_undo_inf_t** cell, /* out: storage cell for the record in the
+ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */
+ trx_undo_inf_t** cell, /*!< out: storage cell for the record in the
purge array */
- mem_heap_t* heap); /* in: memory heap where copied */
-/***********************************************************************
+ mem_heap_t* heap); /*!< in: memory heap where copied */
+/*******************************************************************//**
Releases a reserved purge undo record. */
UNIV_INTERN
void
trx_purge_rec_release(
/*==================*/
- trx_undo_inf_t* cell); /* in: storage cell */
-/***********************************************************************
-This function runs a purge batch. */
+ trx_undo_inf_t* cell); /*!< in: storage cell */
+/*******************************************************************//**
+This function runs a purge batch.
+@return number of undo log pages handled in the batch */
UNIV_INTERN
ulint
trx_purge(void);
/*===========*/
- /* out: number of undo log pages handled in
- the batch */
/**********************************************************************
+This function runs a purge worker batch */
+UNIV_INTERN
+void
+trx_purge_worker(
+/*=============*/
+ ulint worker_id);
+/**********************************************************************
+This function waits the event for worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wait(void);
+/*========================*/
+/**********************************************************************
+This function wakes the waiting worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wake(void);
+/*========================*/
+/******************************************************************//**
Prints information of the purge system to stderr. */
UNIV_INTERN
void
trx_purge_sys_print(void);
/*======================*/
-/* The control structure used in the purge operation */
+/** The control structure used in the purge operation */
struct trx_purge_struct{
- ulint state; /* Purge system state */
- sess_t* sess; /* System session running the purge
+ ulint state; /*!< Purge system state */
+ sess_t* sess; /*!< System session running the purge
query */
- trx_t* trx; /* System transaction running the purge
+ trx_t* trx; /*!< System transaction running the purge
query: this trx is not in the trx list
of the trx system and it never ends */
- que_t* query; /* The query graph which will do the
+ que_t* query; /*!< The query graph which will do the
parallelized purge operation */
- rw_lock_t latch; /* The latch protecting the purge view.
+ ulint n_worker;
+ os_event_t worker_event;
+ sess_t** sess_arr;
+ trx_t** trx_arr;
+ que_t** query_arr;
+ rw_lock_t latch; /*!< The latch protecting the purge view.
A purge operation must acquire an
x-latch here for the instant at which
it changes the purge view: an undo
log operation can prevent this by
obtaining an s-latch here. */
- read_view_t* view; /* The purge will not remove undo logs
+ read_view_t* view; /*!< The purge will not remove undo logs
which are >= this view (purge view) */
- mutex_t mutex; /* Mutex protecting the fields below */
- ulint n_pages_handled;/* Approximate number of undo log
+ mutex_t mutex; /*!< Mutex protecting the fields below */
+ ulint n_pages_handled;/*!< Approximate number of undo log
pages processed in purge */
- ulint handle_limit; /* Target of how many pages to get
+ ulint handle_limit; /*!< Target of how many pages to get
processed in the current purge */
/*------------------------------*/
/* The following two fields form the 'purge pointer' which advances
during a purge, and which is used in history list truncation */
- dulint purge_trx_no; /* Purge has advanced past all
+ trx_id_t purge_trx_no; /*!< Purge has advanced past all
transactions whose number is less
than this */
- dulint purge_undo_no; /* Purge has advanced past all records
+ undo_no_t purge_undo_no; /*!< Purge has advanced past all records
whose undo number is less than this */
/*-----------------------------*/
- ibool next_stored; /* TRUE if the info of the next record
+ ibool next_stored; /*!< TRUE if the info of the next record
to purge is stored below: if yes, then
the transaction number and the undo
number of the record are stored in
purge_trx_no and purge_undo_no above */
- trx_rseg_t* rseg; /* Rollback segment for the next undo
+ trx_rseg_t* rseg; /*!< Rollback segment for the next undo
record to purge */
- ulint page_no; /* Page number for the next undo
+ ulint page_no; /*!< Page number for the next undo
record to purge, page number of the
log header, if dummy record */
- ulint offset; /* Page offset for the next undo
+ ulint offset; /*!< Page offset for the next undo
record to purge, 0 if the dummy
record */
- ulint hdr_page_no; /* Header page of the undo log where
+ ulint hdr_page_no; /*!< Header page of the undo log where
the next record to purge belongs */
- ulint hdr_offset; /* Header byte offset on the page */
+ ulint hdr_offset; /*!< Header byte offset on the page */
/*-----------------------------*/
- trx_undo_arr_t* arr; /* Array of transaction numbers and
+ trx_undo_arr_t* arr; /*!< Array of transaction numbers and
undo numbers of the undo records
currently under processing in purge */
- mem_heap_t* heap; /* Temporary storage used during a
+ mem_heap_t* heap; /*!< Temporary storage used during a
purge: can be emptied after purge
completes */
};
diff --git a/storage/xtradb/include/trx0purge.ic b/storage/xtradb/include/trx0purge.ic
index 2c1d2ac75af..de09e393654 100644
--- a/storage/xtradb/include/trx0purge.ic
+++ b/storage/xtradb/include/trx0purge.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0purge.ic
Purge old versions
Created 3/26/1996 Heikki Tuuri
@@ -24,15 +25,15 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0undo.h"
-/************************************************************************
+/********************************************************************//**
Calculates the file address of an undo log header when we have the file
-address of its history list node. */
+address of its history list node.
+@return file address of the log */
UNIV_INLINE
fil_addr_t
trx_purge_get_log_from_hist(
/*========================*/
- /* out: file address of the log */
- fil_addr_t node_addr) /* in: file address of the history
+ fil_addr_t node_addr) /*!< in: file address of the history
list node of the log */
{
node_addr.boffset -= TRX_UNDO_HISTORY_NODE;
diff --git a/storage/xtradb/include/trx0rec.h b/storage/xtradb/include/trx0rec.h
index 444d39e39db..a6e56e963c6 100644
--- a/storage/xtradb/include/trx0rec.h
+++ b/storage/xtradb/include/trx0rec.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0rec.h
Transaction undo log record
Created 3/26/1996 Heikki Tuuri
@@ -30,278 +31,280 @@ Created 3/26/1996 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
#include "dict0types.h"
-#include "que0types.h"
#include "data0data.h"
#include "rem0types.h"
-/***************************************************************************
-Copies the undo record to the heap. */
+#ifndef UNIV_HOTBACKUP
+# include "que0types.h"
+
+/***********************************************************************//**
+Copies the undo record to the heap.
+@return own: copy of undo log record */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
- /* out, own: copy of undo log record */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- mem_heap_t* heap); /* in: heap where copied */
-/**************************************************************************
-Reads the undo log record type. */
+ const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ mem_heap_t* heap); /*!< in: heap where copied */
+/**********************************************************************//**
+Reads the undo log record type.
+@return record type */
UNIV_INLINE
ulint
trx_undo_rec_get_type(
/*==================*/
- /* out: record type */
- trx_undo_rec_t* undo_rec); /* in: undo log record */
-/**************************************************************************
-Reads from an undo log record the record compiler info. */
+ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */
+/**********************************************************************//**
+Reads from an undo log record the record compiler info.
+@return compiler info */
UNIV_INLINE
ulint
trx_undo_rec_get_cmpl_info(
/*=======================*/
- /* out: compiler info */
- trx_undo_rec_t* undo_rec); /* in: undo log record */
-/**************************************************************************
-Returns TRUE if an undo log record contains an extern storage field. */
+ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */
+/**********************************************************************//**
+Returns TRUE if an undo log record contains an extern storage field.
+@return TRUE if extern */
UNIV_INLINE
ibool
trx_undo_rec_get_extern_storage(
/*============================*/
- /* out: TRUE if extern */
- trx_undo_rec_t* undo_rec); /* in: undo log record */
-/**************************************************************************
-Reads the undo log record number. */
+ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */
+/**********************************************************************//**
+Reads the undo log record number.
+@return undo no */
UNIV_INLINE
-dulint
+undo_no_t
trx_undo_rec_get_undo_no(
/*=====================*/
- /* out: undo no */
- trx_undo_rec_t* undo_rec); /* in: undo log record */
-/**************************************************************************
- * Returns the start of the undo record data area. */
-
+ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */
+/**********************************************************************//**
+Returns the start of the undo record data area.
+@return offset to the data area */
UNIV_INLINE
-byte*
-trx_undo_rec_get_ptr(
-/*==================*/
- /* out: compiler info */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- dulint undo_no); /* in: undo no read from node */
+ulint
+trx_undo_rec_get_offset(
+/*====================*/
+ undo_no_t undo_no) /*!< in: undo no read from node */
+ __attribute__((const));
+
+/**********************************************************************//**
+Returns the start of the undo record data area. */
+#define trx_undo_rec_get_ptr(undo_rec, undo_no) \
+ ((undo_rec) + trx_undo_rec_get_offset(undo_no))
-/**************************************************************************
-Reads from an undo log record the general parameters. */
+/**********************************************************************//**
+Reads from an undo log record the general parameters.
+@return remaining part of undo log record after reading these values */
UNIV_INTERN
byte*
trx_undo_rec_get_pars(
/*==================*/
- /* out: remaining part of undo log
- record after reading these values */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- ulint* type, /* out: undo record type:
+ trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ ulint* type, /*!< out: undo record type:
TRX_UNDO_INSERT_REC, ... */
- ulint* cmpl_info, /* out: compiler info, relevant only
+ ulint* cmpl_info, /*!< out: compiler info, relevant only
for update type records */
- ibool* updated_extern, /* out: TRUE if we updated an
+ ibool* updated_extern, /*!< out: TRUE if we updated an
externally stored fild */
- dulint* undo_no, /* out: undo log record number */
- dulint* table_id); /* out: table id */
-/***********************************************************************
-Builds a row reference from an undo log record. */
+ undo_no_t* undo_no, /*!< out: undo log record number */
+ dulint* table_id); /*!< out: table id */
+/*******************************************************************//**
+Builds a row reference from an undo log record.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_get_row_ref(
/*=====================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part of a copy of an undo log
+ byte* ptr, /*!< in: remaining part of a copy of an undo log
record, at the start of the row reference;
NOTE that this copy of the undo log record must
be preserved as long as the row reference is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- dtuple_t** ref, /* out, own: row reference */
- mem_heap_t* heap); /* in: memory heap from which the memory
+ dict_index_t* index, /*!< in: clustered index */
+ dtuple_t** ref, /*!< out, own: row reference */
+ mem_heap_t* heap); /*!< in: memory heap from which the memory
needed is allocated */
-/***********************************************************************
-Skips a row reference from an undo log record. */
+/*******************************************************************//**
+Skips a row reference from an undo log record.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_skip_row_ref(
/*======================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record, at the start of the row reference */
- dict_index_t* index); /* in: clustered index */
-/**************************************************************************
+ dict_index_t* index); /*!< in: clustered index */
+/**********************************************************************//**
Reads from an undo log update record the system field values of the old
-version. */
+version.
+@return remaining part of undo log record after reading these values */
UNIV_INTERN
byte*
trx_undo_update_rec_get_sys_cols(
/*=============================*/
- /* out: remaining part of undo log
- record after reading these values */
- byte* ptr, /* in: remaining part of undo log
- record after reading general
- parameters */
- dulint* trx_id, /* out: trx id */
- dulint* roll_ptr, /* out: roll ptr */
- ulint* info_bits); /* out: info bits state */
-/***********************************************************************
-Builds an update vector based on a remaining part of an undo log record. */
+ byte* ptr, /*!< in: remaining part of undo
+ log record after reading
+ general parameters */
+ trx_id_t* trx_id, /*!< out: trx id */
+ roll_ptr_t* roll_ptr, /*!< out: roll ptr */
+ ulint* info_bits); /*!< out: info bits state */
+/*******************************************************************//**
+Builds an update vector based on a remaining part of an undo log record.
+@return remaining part of the record, NULL if an error detected, which
+means that the record is corrupted */
UNIV_INTERN
byte*
trx_undo_update_rec_get_update(
/*===========================*/
- /* out: remaining part of the record,
- NULL if an error detected, which means that
- the record is corrupted */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record, after reading the row reference
NOTE that this copy of the undo log record must
be preserved as long as the update vector is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- ulint type, /* in: TRX_UNDO_UPD_EXIST_REC,
+ dict_index_t* index, /*!< in: clustered index */
+ ulint type, /*!< in: TRX_UNDO_UPD_EXIST_REC,
TRX_UNDO_UPD_DEL_REC, or
TRX_UNDO_DEL_MARK_REC; in the last case,
only trx id and roll ptr fields are added to
the update vector */
- dulint trx_id, /* in: transaction id from this undorecord */
- dulint roll_ptr,/* in: roll pointer from this undo record */
- ulint info_bits,/* in: info bits from this undo record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap, /* in: memory heap from which the memory
+ trx_id_t trx_id, /*!< in: transaction id from this undorecord */
+ roll_ptr_t roll_ptr,/*!< in: roll pointer from this undo record */
+ ulint info_bits,/*!< in: info bits from this undo record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
- upd_t** upd); /* out, own: update vector */
-/***********************************************************************
+ upd_t** upd); /*!< out, own: update vector */
+/*******************************************************************//**
Builds a partial row from an update undo log record. It contains the
-columns which occur as ordering in any index of the table. */
+columns which occur as ordering in any index of the table.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_get_partial_row(
/*=========================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record of a suitable type, at the start of
the stored index columns;
NOTE that this copy of the undo log record must
be preserved as long as the partial row is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- dtuple_t** row, /* out, own: partial row */
- ibool ignore_prefix, /* in: flag to indicate if we
+ dict_index_t* index, /*!< in: clustered index */
+ dtuple_t** row, /*!< out, own: partial row */
+ ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
only in the assertion. */
- mem_heap_t* heap); /* in: memory heap from which the memory
+ mem_heap_t* heap); /*!< in: memory heap from which the memory
needed is allocated */
-/***************************************************************************
+/***********************************************************************//**
Writes information to an undo log about an insert, update, or a delete marking
of a clustered index record. This information is used in a rollback of the
transaction and in consistent reads that must look to the history of this
-transaction. */
+transaction.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
trx_undo_report_row_operation(
/*==========================*/
- /* out: DB_SUCCESS or error code */
- ulint flags, /* in: if BTR_NO_UNDO_LOG_FLAG bit is
+ ulint flags, /*!< in: if BTR_NO_UNDO_LOG_FLAG bit is
set, does nothing */
- ulint op_type, /* in: TRX_UNDO_INSERT_OP or
+ ulint op_type, /*!< in: TRX_UNDO_INSERT_OP or
TRX_UNDO_MODIFY_OP */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* clust_entry, /* in: in the case of an insert,
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* clust_entry, /*!< in: in the case of an insert,
index entry to insert into the
clustered index, otherwise NULL */
- const upd_t* update, /* in: in the case of an update,
+ const upd_t* update, /*!< in: in the case of an update,
the update vector, otherwise NULL */
- ulint cmpl_info, /* in: compiler info on secondary
+ ulint cmpl_info, /*!< in: compiler info on secondary
index updates */
- const rec_t* rec, /* in: case of an update or delete
+ const rec_t* rec, /*!< in: case of an update or delete
marking, the record in the clustered
index, otherwise NULL */
- dulint* roll_ptr); /* out: rollback pointer to the
+ roll_ptr_t* roll_ptr); /*!< out: rollback pointer to the
inserted undo log record,
ut_dulint_zero if BTR_NO_UNDO_LOG
flag was specified */
-/**********************************************************************
+/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
-the undo log record exists. */
+the undo log record exists.
+@return own: copy of the record */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_undo_rec_low(
/*======================*/
- /* out, own: copy of the record */
- dulint roll_ptr, /* in: roll pointer to record */
- mem_heap_t* heap); /* in: memory heap where copied */
-/**********************************************************************
-Copies an undo record to heap. */
+ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
+ mem_heap_t* heap); /*!< in: memory heap where copied */
+/******************************************************************//**
+Copies an undo record to heap.
+
+NOTE: the caller must have latches on the clustered index page and
+purge_view.
+
+@return DB_SUCCESS, or DB_MISSING_HISTORY if the undo log has been
+truncated and we cannot fetch the old version */
UNIV_INTERN
ulint
trx_undo_get_undo_rec(
/*==================*/
- /* out: DB_SUCCESS, or
- DB_MISSING_HISTORY if the undo log
- has been truncated and we cannot
- fetch the old version; NOTE: the
- caller must have latches on the
- clustered index page and purge_view */
- dulint roll_ptr, /* in: roll pointer to record */
- dulint trx_id, /* in: id of the trx that generated
+ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
+ trx_id_t trx_id, /*!< in: id of the trx that generated
the roll pointer: it points to an
undo log of this transaction */
- trx_undo_rec_t** undo_rec, /* out, own: copy of the record */
- mem_heap_t* heap); /* in: memory heap where copied */
-/***********************************************************************
+ trx_undo_rec_t** undo_rec, /*!< out, own: copy of the record */
+ mem_heap_t* heap); /*!< in: memory heap where copied */
+/*******************************************************************//**
Build a previous version of a clustered index record. This function checks
that the caller has a latch on the index page of the clustered index record
and an s-latch on the purge_view. This guarantees that the stack of versions
-is locked. */
+is locked.
+@return DB_SUCCESS, or DB_MISSING_HISTORY if the previous version is
+earlier than purge_view, which means that it may have been removed,
+DB_ERROR if corrupted record */
UNIV_INTERN
ulint
trx_undo_prev_version_build(
/*========================*/
- /* out: DB_SUCCESS, or DB_MISSING_HISTORY if
- the previous version is not >= purge_view,
- which means that it may have been removed,
- DB_ERROR if corrupted record */
- const rec_t* index_rec,/* in: clustered index record in the
+ const rec_t* index_rec,/*!< in: clustered index record in the
index tree */
- mtr_t* index_mtr,/* in: mtr which contains the latch to
+ mtr_t* index_mtr,/*!< in: mtr which contains the latch to
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: rec_get_offsets(rec, index) */
- mem_heap_t* heap, /* in: memory heap from which the memory
+ const rec_t* rec, /*!< in: version of a clustered index record */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint* offsets,/*!< in: 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
+ rec_t** old_vers);/*!< out, own: previous version, or NULL if
rec is the first inserted version, or if
history data has been deleted */
-/***************************************************************
-Parses a redo log record of adding an undo log record. */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
+Parses a redo log record of adding an undo log record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_add_undo_rec(
/*========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page); /* in: page or NULL */
-/***************************************************************
-Parses a redo log record of erasing of an undo page end. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page); /*!< in: page or NULL */
+/***********************************************************//**
+Parses a redo log record of erasing of an undo page end.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_erase_page_end(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+
+#ifndef UNIV_HOTBACKUP
/* Types of an undo log record: these have to be smaller than 16, as the
compilation info multiplied by 16 is ORed to this value in an undo log
@@ -330,4 +333,6 @@ record */
#include "trx0rec.ic"
#endif
-#endif
+#endif /* !UNIV_HOTBACKUP */
+
+#endif /* trx0rec_h */
diff --git a/storage/xtradb/include/trx0rec.ic b/storage/xtradb/include/trx0rec.ic
index bfd74eb9dfb..e7e41d6d9f6 100644
--- a/storage/xtradb/include/trx0rec.ic
+++ b/storage/xtradb/include/trx0rec.ic
@@ -16,44 +16,46 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0rec.ic
Transaction undo log record
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-/**************************************************************************
-Reads from an undo log record the record type. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Reads from an undo log record the record type.
+@return record type */
UNIV_INLINE
ulint
trx_undo_rec_get_type(
/*==================*/
- /* out: record type */
- trx_undo_rec_t* undo_rec) /* in: undo log record */
+ const trx_undo_rec_t* undo_rec) /*!< in: undo log record */
{
return(mach_read_from_1(undo_rec + 2) & (TRX_UNDO_CMPL_INFO_MULT - 1));
}
-/**************************************************************************
-Reads from an undo log record the record compiler info. */
+/**********************************************************************//**
+Reads from an undo log record the record compiler info.
+@return compiler info */
UNIV_INLINE
ulint
trx_undo_rec_get_cmpl_info(
/*=======================*/
- /* out: compiler info */
- trx_undo_rec_t* undo_rec) /* in: undo log record */
+ const trx_undo_rec_t* undo_rec) /*!< in: undo log record */
{
return(mach_read_from_1(undo_rec + 2) / TRX_UNDO_CMPL_INFO_MULT);
}
-/**************************************************************************
-Returns TRUE if an undo log record contains an extern storage field. */
+/**********************************************************************//**
+Returns TRUE if an undo log record contains an extern storage field.
+@return TRUE if extern */
UNIV_INLINE
ibool
trx_undo_rec_get_extern_storage(
/*============================*/
- /* out: TRUE if extern */
- trx_undo_rec_t* undo_rec) /* in: undo log record */
+ const trx_undo_rec_t* undo_rec) /*!< in: undo log record */
{
if (mach_read_from_1(undo_rec + 2) & TRX_UNDO_UPD_EXTERN) {
@@ -63,54 +65,48 @@ trx_undo_rec_get_extern_storage(
return(FALSE);
}
-/**************************************************************************
-Reads the undo log record number. */
+/**********************************************************************//**
+Reads the undo log record number.
+@return undo no */
UNIV_INLINE
-dulint
+undo_no_t
trx_undo_rec_get_undo_no(
/*=====================*/
- /* out: undo no */
- trx_undo_rec_t* undo_rec) /* in: undo log record */
+ const trx_undo_rec_t* undo_rec) /*!< in: undo log record */
{
- byte* ptr;
+ const byte* ptr;
ptr = undo_rec + 3;
return(mach_dulint_read_much_compressed(ptr));
}
-/**************************************************************************
-Returns the start of the undo record data area. */
+/**********************************************************************//**
+Returns the start of the undo record data area.
+@return offset to the data area */
UNIV_INLINE
-byte*
-trx_undo_rec_get_ptr(
-/*=================*/
- /* out: compiler info */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- dulint undo_no) /* in: undo no read from node */
+ulint
+trx_undo_rec_get_offset(
+/*====================*/
+ undo_no_t undo_no) /*!< in: undo no read from node */
{
- return (((byte*) undo_rec) + 3
- + mach_dulint_get_much_compressed_size(undo_no));
+ return (3 + mach_dulint_get_much_compressed_size(undo_no));
}
-/***************************************************************************
-Copies the undo record to the heap. */
+/***********************************************************************//**
+Copies the undo record to the heap.
+@return own: copy of undo log record */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
- /* out, own: copy of undo log record */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- mem_heap_t* heap) /* in: heap where copied */
+ const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ mem_heap_t* heap) /*!< in: heap where copied */
{
ulint len;
- trx_undo_rec_t* rec_copy;
len = mach_read_from_2(undo_rec)
- ut_align_offset(undo_rec, UNIV_PAGE_SIZE);
- rec_copy = mem_heap_alloc(heap, len);
-
- ut_memcpy(rec_copy, undo_rec, len);
-
- return(rec_copy);
+ return(mem_heap_dup(heap, undo_rec, len));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/trx0roll.h b/storage/xtradb/include/trx0roll.h
index 3318a5985d7..1dee5655c8c 100644
--- a/storage/xtradb/include/trx0roll.h
+++ b/storage/xtradb/include/trx0roll.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0roll.h
Transaction rollback
Created 3/26/1996 Heikki Tuuri
@@ -33,306 +34,317 @@ Created 3/26/1996 Heikki Tuuri
#define trx_roll_free_all_savepoints(s) trx_roll_savepoints_free((s), NULL)
-/***********************************************************************
+/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
-in crash recovery. */
+in crash recovery.
+@return TRUE if trx is an incomplete transaction that is being rolled
+back in crash recovery */
UNIV_INTERN
ibool
trx_is_recv(
/*========*/
- /* out: TRUE if trx is an incomplete
- transaction that is being rolled back
- in crash recovery */
- const trx_t* trx); /* in: transaction */
-/***********************************************************************
-Returns a transaction savepoint taken at this point in time. */
+ const trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
+Returns a transaction savepoint taken at this point in time.
+@return savepoint */
UNIV_INTERN
trx_savept_t
trx_savept_take(
/*============*/
- /* out: savepoint */
- trx_t* trx); /* in: transaction */
-/***********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
Creates an undo number array. */
UNIV_INTERN
trx_undo_arr_t*
trx_undo_arr_create(void);
/*=====================*/
-/***********************************************************************
+/*******************************************************************//**
Frees an undo number array. */
UNIV_INTERN
void
trx_undo_arr_free(
/*==============*/
- trx_undo_arr_t* arr); /* in: undo number array */
-/***********************************************************************
-Returns pointer to nth element in an undo number array. */
+ trx_undo_arr_t* arr); /*!< in: undo number array */
+/*******************************************************************//**
+Returns pointer to nth element in an undo number array.
+@return pointer to the nth element */
UNIV_INLINE
trx_undo_inf_t*
trx_undo_arr_get_nth_info(
/*======================*/
- /* out: pointer to the nth element */
- trx_undo_arr_t* arr, /* in: undo number array */
- ulint n); /* in: position */
-/***************************************************************************
+ trx_undo_arr_t* arr, /*!< in: undo number array */
+ ulint n); /*!< in: position */
+/***********************************************************************//**
Tries truncate the undo logs. */
UNIV_INTERN
void
trx_roll_try_truncate(
/*==================*/
- trx_t* trx); /* in: transaction */
-/************************************************************************
+ trx_t* trx); /*!< in/out: transaction */
+/********************************************************************//**
Pops the topmost record when the two undo logs of a transaction are seen
as a single stack of records ordered by their undo numbers. Inserts the
undo number of the popped undo record to the array of currently processed
undo numbers in the transaction. When the query thread finishes processing
-of this undo record, it must be released with trx_undo_rec_release. */
+of this undo record, it must be released with trx_undo_rec_release.
+@return undo log record copied to heap, NULL if none left, or if the
+undo number of the top record would be less than the limit */
UNIV_INTERN
trx_undo_rec_t*
trx_roll_pop_top_rec_of_trx(
/*========================*/
- /* out: undo log record copied to heap, NULL
- if none left, or if the undo number of the
- top record would be less than the limit */
- trx_t* trx, /* in: transaction */
- dulint limit, /* in: least undo number we need */
- dulint* roll_ptr,/* out: roll pointer to undo record */
- mem_heap_t* heap); /* in: memory heap where copied */
-/************************************************************************
+ trx_t* trx, /*!< in: transaction */
+ undo_no_t limit, /*!< in: least undo number we need */
+ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */
+ mem_heap_t* heap); /*!< in: memory heap where copied */
+/********************************************************************//**
Reserves an undo log record for a query thread to undo. This should be
called if the query thread gets the undo log record not using the pop
-function above. */
+function above.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
trx_undo_rec_reserve(
/*=================*/
- /* out: TRUE if succeeded */
- trx_t* trx, /* in: transaction */
- dulint undo_no);/* in: undo number of the record */
-/***********************************************************************
+ trx_t* trx, /*!< in/out: transaction */
+ undo_no_t undo_no);/*!< in: undo number of the record */
+/*******************************************************************//**
Releases a reserved undo record. */
UNIV_INTERN
void
trx_undo_rec_release(
/*=================*/
- trx_t* trx, /* in: transaction */
- dulint undo_no);/* in: undo number */
-/*************************************************************************
+ trx_t* trx, /*!< in/out: transaction */
+ undo_no_t undo_no);/*!< in: undo number */
+/*********************************************************************//**
Starts a rollback operation. */
UNIV_INTERN
void
trx_rollback(
/*=========*/
- trx_t* trx, /* in: transaction */
- trx_sig_t* sig, /* in: signal starting the rollback */
- que_thr_t** next_thr);/* in/out: next query thread to run;
+ trx_t* trx, /*!< in: transaction */
+ trx_sig_t* sig, /*!< in: signal starting the rollback */
+ que_thr_t** next_thr);/*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread */
-/***********************************************************************
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery. If the transaction already was
+committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back. */
+UNIV_INTERN
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+ ibool all); /*!< in: FALSE=roll back dictionary transactions;
+ TRUE=roll back all non-PREPARED transactions */
+/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
transaction was not yet committed, then we roll it back.
-Note: this is done in a background thread. */
+Note: this is done in a background thread.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
trx_rollback_or_clean_all_recovered(
/*================================*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)));
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
-/********************************************************************
+/****************************************************************//**
Finishes a transaction rollback. */
UNIV_INTERN
void
trx_finish_rollback_off_kernel(
/*===========================*/
- que_t* graph, /* in: undo graph which can now be freed */
- trx_t* trx, /* in: transaction */
- que_thr_t** next_thr);/* in/out: next query thread to run;
+ que_t* graph, /*!< in: undo graph which can now be freed */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t** next_thr);/*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread; if this parameter is
NULL, it is ignored */
-/********************************************************************
+/****************************************************************//**
Builds an undo 'query' graph for a transaction. The actual rollback is
performed by executing this query graph like a query subprocedure call.
The reply about the completion of the rollback will be sent by this
-graph. */
+graph.
+@return own: the query graph */
UNIV_INTERN
que_t*
trx_roll_graph_build(
/*=================*/
- /* out, own: the query graph */
- trx_t* trx); /* in: trx handle */
-/*************************************************************************
-Creates a rollback command node struct. */
+ trx_t* trx); /*!< in: trx handle */
+/*********************************************************************//**
+Creates a rollback command node struct.
+@return own: rollback node struct */
UNIV_INTERN
roll_node_t*
roll_node_create(
/*=============*/
- /* out, own: rollback node struct */
- mem_heap_t* heap); /* in: mem heap where created */
-/***************************************************************
-Performs an execution step for a rollback command node in a query graph. */
+ mem_heap_t* heap); /*!< in: mem heap where created */
+/***********************************************************//**
+Performs an execution step for a rollback command node in a query graph.
+@return query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_rollback_step(
/*==============*/
- /* out: query thread to run next, or NULL */
- que_thr_t* thr); /* in: query thread */
-/***********************************************************************
-Rollback a transaction used in MySQL. */
+ que_thr_t* thr); /*!< in: query thread */
+/*******************************************************************//**
+Rollback a transaction used in MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_rollback_for_mysql(
/*===================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx); /* in: transaction handle */
-/***********************************************************************
-Rollback the latest SQL statement for MySQL. */
+ trx_t* trx); /*!< in: transaction handle */
+/*******************************************************************//**
+Rollback the latest SQL statement for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_rollback_last_sql_stat_for_mysql(
/*=================================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx); /* in: transaction handle */
-/***********************************************************************
-Rollback a transaction used in MySQL. */
+ trx_t* trx); /*!< in: transaction handle */
+/*******************************************************************//**
+Rollback a transaction used in MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_general_rollback_for_mysql(
/*===========================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- ibool partial,/* in: TRUE if partial rollback requested */
- trx_savept_t* savept);/* in: pointer to savepoint undo number, if
- partial rollback requested */
-/***********************************************************************
+ trx_t* trx, /*!< in: transaction handle */
+ trx_savept_t* savept);/*!< in: pointer to savepoint undo number, if
+ partial rollback requested, or NULL for
+ complete rollback */
+/*******************************************************************//**
Rolls back a transaction back to a named savepoint. Modifications after the
savepoint are undone but InnoDB does NOT release the corresponding locks
which are stored in memory. If a lock is 'implicit', that is, a new inserted
row holds a lock where the lock information is carried by the trx id stored in
the row, these locks are naturally released in the rollback. Savepoints which
-were set after this savepoint are deleted. */
+were set after this savepoint are deleted.
+@return if no savepoint of the name found then DB_NO_SAVEPOINT,
+otherwise DB_SUCCESS */
UNIV_INTERN
ulint
trx_rollback_to_savepoint_for_mysql(
/*================================*/
- /* out: if no savepoint
- of the name found then
- DB_NO_SAVEPOINT,
- otherwise DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name, /* in: savepoint name */
- ib_int64_t* mysql_binlog_cache_pos);/* out: the MySQL binlog cache
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name, /*!< in: savepoint name */
+ ib_int64_t* mysql_binlog_cache_pos);/*!< out: the MySQL binlog cache
position corresponding to this
savepoint; MySQL needs this
information to remove the
binlog entries of the queries
executed after the savepoint */
-/***********************************************************************
+/*******************************************************************//**
Creates a named savepoint. If the transaction is not yet started, starts it.
If there is already a savepoint of the same name, this call erases that old
savepoint and replaces it with a new. Savepoints are deleted in a transaction
-commit or rollback. */
+commit or rollback.
+@return always DB_SUCCESS */
UNIV_INTERN
ulint
trx_savepoint_for_mysql(
/*====================*/
- /* out: always DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name, /* in: savepoint name */
- ib_int64_t binlog_cache_pos); /* in: MySQL binlog cache
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name, /*!< in: savepoint name */
+ ib_int64_t binlog_cache_pos); /*!< in: MySQL binlog cache
position corresponding to this
connection at the time of the
savepoint */
-/***********************************************************************
+/*******************************************************************//**
Releases a named savepoint. Savepoints which
-were set after this savepoint are deleted. */
+were set after this savepoint are deleted.
+@return if no savepoint of the name found then DB_NO_SAVEPOINT,
+otherwise DB_SUCCESS */
UNIV_INTERN
ulint
trx_release_savepoint_for_mysql(
/*============================*/
- /* out: if no savepoint
- of the name found then
- DB_NO_SAVEPOINT,
- otherwise DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name); /* in: savepoint name */
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name); /*!< in: savepoint name */
-/***********************************************************************
+/*******************************************************************//**
Frees a single savepoint struct. */
UNIV_INTERN
void
trx_roll_savepoint_free(
/*=====================*/
- trx_t* trx, /* in: transaction handle */
- trx_named_savept_t* savep); /* in: savepoint to free */
+ trx_t* trx, /*!< in: transaction handle */
+ trx_named_savept_t* savep); /*!< in: savepoint to free */
-/***********************************************************************
+/*******************************************************************//**
Frees savepoint structs starting from savep, if savep == NULL then
free all savepoints. */
-
+UNIV_INTERN
void
trx_roll_savepoints_free(
/*=====================*/
- trx_t* trx, /* in: transaction handle */
- trx_named_savept_t* savep); /* in: free all savepoints > this one;
+ trx_t* trx, /*!< in: transaction handle */
+ trx_named_savept_t* savep); /*!< in: free all savepoints > this one;
if this is NULL, free all savepoints
of trx */
-/* A cell in the array used during a rollback and a purge */
+/** A cell of trx_undo_arr_struct; used during a rollback and a purge */
struct trx_undo_inf_struct{
- dulint trx_no; /* transaction number: not defined during
+ trx_id_t trx_no; /*!< transaction number: not defined during
a rollback */
- dulint undo_no; /* undo number of an undo record */
- ibool in_use; /* TRUE if the cell is in use */
+ undo_no_t undo_no;/*!< undo number of an undo record */
+ ibool in_use; /*!< TRUE if the cell is in use */
};
-/* During a rollback and a purge, undo numbers of undo records currently being
+/** During a rollback and a purge, undo numbers of undo records currently being
processed are stored in this array */
struct trx_undo_arr_struct{
- ulint n_cells; /* number of cells in the array */
- ulint n_used; /* number of cells currently in use */
- trx_undo_inf_t* infos; /* the array of undo infos */
- mem_heap_t* heap; /* memory heap from which allocated */
+ ulint n_cells; /*!< number of cells in the array */
+ ulint n_used; /*!< number of cells currently in use */
+ trx_undo_inf_t* infos; /*!< the array of undo infos */
+ mem_heap_t* heap; /*!< memory heap from which allocated */
};
-/* Rollback command node in a query graph */
+/** Rollback node states */
+enum roll_node_state {
+ ROLL_NODE_SEND = 1, /*!< about to send a rollback signal to
+ the transaction */
+ ROLL_NODE_WAIT /*!< rollback signal sent to the transaction,
+ waiting for completion */
+};
+
+/** Rollback command node in a query graph */
struct roll_node_struct{
- que_common_t common; /* node type: QUE_NODE_ROLLBACK */
- ulint state; /* node execution state */
- ibool partial;/* TRUE if we want a partial rollback */
- trx_savept_t savept; /* savepoint to which to roll back, in the
- case of a partial rollback */
+ que_common_t common; /*!< node type: QUE_NODE_ROLLBACK */
+ enum roll_node_state state; /*!< node execution state */
+ ibool partial;/*!< TRUE if we want a partial
+ rollback */
+ trx_savept_t savept; /*!< savepoint to which to
+ roll back, in the case of a
+ partial rollback */
};
-/* A savepoint set with SQL's "SAVEPOINT savepoint_id" command */
+/** A savepoint set with SQL's "SAVEPOINT savepoint_id" command */
struct trx_named_savept_struct{
- char* name; /* savepoint name */
- trx_savept_t savept; /* the undo number corresponding to
+ char* name; /*!< savepoint name */
+ trx_savept_t savept; /*!< the undo number corresponding to
the savepoint */
ib_int64_t mysql_binlog_cache_pos;
- /* the MySQL binlog cache position
+ /*!< the MySQL binlog cache position
corresponding to this savepoint, not
defined if the MySQL binlogging is not
enabled */
UT_LIST_NODE_T(trx_named_savept_t)
- trx_savepoints; /* the list of savepoints of a
+ trx_savepoints; /*!< the list of savepoints of a
transaction */
};
-/* Rollback node states */
-#define ROLL_NODE_SEND 1
-#define ROLL_NODE_WAIT 2
-
#ifndef UNIV_NONINL
#include "trx0roll.ic"
#endif
diff --git a/storage/xtradb/include/trx0roll.ic b/storage/xtradb/include/trx0roll.ic
index 513b8b44847..3460832b18c 100644
--- a/storage/xtradb/include/trx0roll.ic
+++ b/storage/xtradb/include/trx0roll.ic
@@ -16,21 +16,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0roll.ic
Transaction rollback
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-/***********************************************************************
-Returns pointer to nth element in an undo number array. */
+/*******************************************************************//**
+Returns pointer to nth element in an undo number array.
+@return pointer to the nth element */
UNIV_INLINE
trx_undo_inf_t*
trx_undo_arr_get_nth_info(
/*======================*/
- /* out: pointer to the nth element */
- trx_undo_arr_t* arr, /* in: undo number array */
- ulint n) /* in: position */
+ trx_undo_arr_t* arr, /*!< in: undo number array */
+ ulint n) /*!< in: position */
{
ut_ad(arr);
ut_ad(n < arr->n_cells);
diff --git a/storage/xtradb/include/trx0rseg.h b/storage/xtradb/include/trx0rseg.h
index f3aa736f788..0d7dc60329f 100644
--- a/storage/xtradb/include/trx0rseg.h
+++ b/storage/xtradb/include/trx0rseg.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0rseg.h
Rollback segment
Created 3/26/1996 Heikki Tuuri
@@ -29,106 +30,108 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0types.h"
#include "trx0sys.h"
-/**********************************************************************
-Gets a rollback segment header. */
+/******************************************************************//**
+Gets a rollback segment header.
+@return rollback segment header, page x-latched */
UNIV_INLINE
trx_rsegf_t*
trx_rsegf_get(
/*==========*/
- /* out: rollback segment header, page
- x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the header */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
-Gets a newly created rollback segment header. */
+ ulint page_no, /*!< in: page number of the header */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
+Gets a newly created rollback segment header.
+@return rollback segment header, page x-latched */
UNIV_INLINE
trx_rsegf_t*
trx_rsegf_get_new(
/*==============*/
- /* out: rollback segment header, page
- x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the header */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
-Gets the file page number of the nth undo log slot. */
+ ulint page_no, /*!< in: page number of the header */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
+Gets the file page number of the nth undo log slot.
+@return page number of the undo log segment */
UNIV_INLINE
ulint
trx_rsegf_get_nth_undo(
/*===================*/
- /* out: page number of the undo log segment */
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- ulint n, /* in: index of slot */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ ulint n, /*!< in: index of slot */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
Sets the file page number of the nth undo log slot. */
UNIV_INLINE
void
trx_rsegf_set_nth_undo(
/*===================*/
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- ulint n, /* in: index of slot */
- ulint page_no,/* in: page number of the undo log segment */
- mtr_t* mtr); /* in: mtr */
-/********************************************************************
-Looks for a free slot for an undo log segment. */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ ulint n, /*!< in: index of slot */
+ ulint page_no,/*!< in: page number of the undo log segment */
+ mtr_t* mtr); /*!< in: mtr */
+/****************************************************************//**
+Looks for a free slot for an undo log segment.
+@return slot index or ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
trx_rsegf_undo_find_free(
/*=====================*/
- /* out: slot index or ULINT_UNDEFINED if not
- found */
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
-Looks for a rollback segment, based on the rollback segment id. */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
+Looks for a rollback segment, based on the rollback segment id.
+@return rollback segment */
UNIV_INTERN
trx_rseg_t*
trx_rseg_get_on_id(
/*===============*/
- /* out: rollback segment */
- ulint id); /* in: rollback segment id */
-/********************************************************************
+ ulint id); /*!< in: rollback segment id */
+/****************************************************************//**
Creates a rollback segment header. This function is called only when
-a new rollback segment is created in the database. */
+a new rollback segment is created in the database.
+@return page number of the created segment, FIL_NULL if fail */
UNIV_INTERN
ulint
trx_rseg_header_create(
/*===================*/
- /* out: page number of the created segment,
- FIL_NULL if fail */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint max_size, /* in: max size in pages */
- ulint* slot_no, /* out: rseg id == slot number in trx sys */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************************
+ ulint max_size, /*!< in: max size in pages */
+ ulint* slot_no, /*!< out: rseg id == slot number in trx sys */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************************//**
Creates the memory copies for rollback segments and initializes the
rseg list and array in trx_sys at a database startup. */
UNIV_INTERN
void
trx_rseg_list_and_array_init(
/*=========================*/
- trx_sysf_t* sys_header, /* in: trx system header */
- mtr_t* mtr); /* in: mtr */
-/********************************************************************
-Creates a new rollback segment to the database. */
+ trx_sysf_t* sys_header, /*!< in: trx system header */
+ mtr_t* mtr); /*!< in: mtr */
+/****************************************************************//**
+Creates a new rollback segment to the database.
+@return the created segment object, NULL if fail */
UNIV_INTERN
trx_rseg_t*
trx_rseg_create(
/*============*/
- /* out: the created segment object, NULL if
- fail */
- ulint space, /* in: space id */
- ulint max_size, /* in: max size in pages */
- ulint* id, /* out: rseg id */
- mtr_t* mtr); /* in: mtr */
+ ulint space, /*!< in: space id */
+ ulint max_size, /*!< in: max size in pages */
+ ulint* id, /*!< out: rseg id */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************************
+Free's an instance of the rollback segment in memory. */
+UNIV_INTERN
+void
+trx_rseg_mem_free(
+/*==============*/
+ trx_rseg_t* rseg); /* in, own: instance to free */
/* Real max value may be 4076 in usual. But reserve 4 slot for safety or etc... */
@@ -143,15 +146,15 @@ trx_rseg_create(
/* The rollback segment memory object */
struct trx_rseg_struct{
/*--------------------------------------------------------*/
- ulint id; /* rollback segment id == the index of
+ ulint id; /*!< rollback segment id == the index of
its slot in the trx system file copy */
- mutex_t mutex; /* mutex protecting the fields in this
+ mutex_t mutex; /*!< mutex protecting the fields in this
struct except id; NOTE that the latching
order must always be kernel mutex ->
rseg mutex */
- ulint space; /* space where the rollback segment is
+ ulint space; /*!< space where the rollback segment is
header is placed */
- ulint zip_size;/* in: compressed page size of space
+ ulint zip_size;/* compressed page size of space
in bytes, or 0 for uncompressed spaces */
ulint page_no;/* page number of the rollback segment
header */
@@ -172,14 +175,14 @@ struct trx_rseg_struct{
/* List of insert undo log segments
cached for fast reuse */
/*--------------------------------------------------------*/
- ulint last_page_no; /* Page number of the last not yet
+ ulint last_page_no; /*!< Page number of the last not yet
purged log header in the history list;
FIL_NULL if all list purged */
- ulint last_offset; /* Byte offset of the last not yet
+ ulint last_offset; /*!< Byte offset of the last not yet
purged log header */
- dulint last_trx_no; /* Transaction number of the last not
+ trx_id_t last_trx_no; /*!< Transaction number of the last not
yet purged log */
- ibool last_del_marks; /* TRUE if the last not yet purged log
+ ibool last_del_marks; /*!< TRUE if the last not yet purged log
needs purging */
/*--------------------------------------------------------*/
UT_LIST_NODE_T(trx_rseg_t) rseg_list;
diff --git a/storage/xtradb/include/trx0rseg.ic b/storage/xtradb/include/trx0rseg.ic
index e665a40fa8b..daffa92fc7d 100644
--- a/storage/xtradb/include/trx0rseg.ic
+++ b/storage/xtradb/include/trx0rseg.ic
@@ -16,27 +16,28 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0rseg.ic
Rollback segment
Created 3/26/1996 Heikki Tuuri
*******************************************************/
#include "srv0srv.h"
+#include "mtr0log.h"
-/**********************************************************************
-Gets a rollback segment header. */
+/******************************************************************//**
+Gets a rollback segment header.
+@return rollback segment header, page x-latched */
UNIV_INLINE
trx_rsegf_t*
trx_rsegf_get(
/*==========*/
- /* out: rollback segment header, page
- x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the header */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number of the header */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
trx_rsegf_t* header;
@@ -49,19 +50,18 @@ trx_rsegf_get(
return(header);
}
-/**********************************************************************
-Gets a newly created rollback segment header. */
+/******************************************************************//**
+Gets a newly created rollback segment header.
+@return rollback segment header, page x-latched */
UNIV_INLINE
trx_rsegf_t*
trx_rsegf_get_new(
/*==============*/
- /* out: rollback segment header, page
- x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the header */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number of the header */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
trx_rsegf_t* header;
@@ -74,16 +74,16 @@ trx_rsegf_get_new(
return(header);
}
-/*******************************************************************
-Gets the file page number of the nth undo log slot. */
+/***************************************************************//**
+Gets the file page number of the nth undo log slot.
+@return page number of the undo log segment */
UNIV_INLINE
ulint
trx_rsegf_get_nth_undo(
/*===================*/
- /* out: page number of the undo log segment */
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- ulint n, /* in: index of slot */
- mtr_t* mtr) /* in: mtr */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ ulint n, /*!< in: index of slot */
+ mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_UNLIKELY(n >= TRX_RSEG_N_SLOTS)) {
fprintf(stderr,
@@ -96,16 +96,16 @@ trx_rsegf_get_nth_undo(
+ n * TRX_RSEG_SLOT_SIZE, MLOG_4BYTES, mtr));
}
-/*******************************************************************
+/***************************************************************//**
Sets the file page number of the nth undo log slot. */
UNIV_INLINE
void
trx_rsegf_set_nth_undo(
/*===================*/
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- ulint n, /* in: index of slot */
- ulint page_no,/* in: page number of the undo log segment */
- mtr_t* mtr) /* in: mtr */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ ulint n, /*!< in: index of slot */
+ ulint page_no,/*!< in: page number of the undo log segment */
+ mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_UNLIKELY(n >= TRX_RSEG_N_SLOTS)) {
fprintf(stderr,
@@ -118,16 +118,15 @@ trx_rsegf_set_nth_undo(
page_no, MLOG_4BYTES, mtr);
}
-/********************************************************************
-Looks for a free slot for an undo log segment. */
+/****************************************************************//**
+Looks for a free slot for an undo log segment.
+@return slot index or ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
trx_rsegf_undo_find_free(
/*=====================*/
- /* out: slot index or ULINT_UNDEFINED if not
- found */
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- mtr_t* mtr) /* in: mtr */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
ulint page_no;
diff --git a/storage/xtradb/include/trx0sys.h b/storage/xtradb/include/trx0sys.h
index f7e7e082278..8789d575bca 100644
--- a/storage/xtradb/include/trx0sys.h
+++ b/storage/xtradb/include/trx0sys.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0sys.h
Transaction system
Created 3/26/1996 Heikki Tuuri
@@ -28,54 +29,65 @@ Created 3/26/1996 Heikki Tuuri
#include "univ.i"
#include "trx0types.h"
+#include "fsp0types.h"
+#include "fil0fil.h"
+#include "buf0buf.h"
+#ifndef UNIV_HOTBACKUP
#include "mtr0mtr.h"
-#include "mtr0log.h"
#include "ut0byte.h"
#include "mem0mem.h"
#include "sync0sync.h"
#include "ut0lst.h"
-#include "buf0buf.h"
-#include "fil0fil.h"
-#include "fut0lst.h"
-#include "fsp0fsp.h"
#include "read0types.h"
#include "page0types.h"
-/* In a MySQL replication slave, in crash recovery we store the master log
-file name and position here. We have successfully got the updates to InnoDB
-up to this position. If .._pos is -1, it means no crash recovery was needed,
-or there was no master log position info inside InnoDB. */
-
+/** In a MySQL replication slave, in crash recovery we store the master log
+file name and position here. */
+/* @{ */
+/** Master binlog file name */
extern char trx_sys_mysql_master_log_name[];
+/** Master binlog file position. We have successfully got the updates
+up to this position. -1 means that no crash recovery was needed, or
+there was no master log position info inside InnoDB.*/
extern ib_int64_t trx_sys_mysql_master_log_pos;
+/* @} */
extern char trx_sys_mysql_relay_log_name[];
extern ib_int64_t trx_sys_mysql_relay_log_pos;
-/* If this MySQL server uses binary logging, after InnoDB has been inited
+/** If this MySQL server uses binary logging, after InnoDB has been inited
and if it has done a crash recovery, we store the binlog file name and position
-here. If .._pos is -1, it means there was no binlog position info inside
-InnoDB. */
-
+here. */
+/* @{ */
+/** Binlog file name */
extern char trx_sys_mysql_bin_log_name[];
+/** Binlog file position, or -1 if unknown */
extern ib_int64_t trx_sys_mysql_bin_log_pos;
+/* @} */
-/* The transaction system */
+/** The transaction system */
extern trx_sys_t* trx_sys;
-/* Doublewrite system */
+/** Doublewrite system */
extern trx_doublewrite_t* trx_doublewrite;
+/** The following is set to TRUE when we are upgrading from pre-4.1
+format data files to the multiple tablespaces format data files */
extern ibool trx_doublewrite_must_reset_space_ids;
+/** Set to TRUE when the doublewrite buffer is being created */
+extern ibool trx_doublewrite_buf_is_being_created;
+/** The following is TRUE when we are using the database in the
+post-4.1 format, i.e., we have successfully upgraded, or have created
+a new database installation */
extern ibool trx_sys_multiple_tablespace_format;
-/********************************************************************
+/****************************************************************//**
Creates the doublewrite buffer to a new InnoDB installation. The header of the
doublewrite buffer is placed on the trx system header page. */
UNIV_INTERN
void
trx_sys_create_doublewrite_buf(void);
/*================================*/
-/********************************************************************
+/****************************************************************//**
At a database startup initializes the doublewrite buffer memory structure if
we already have a doublewrite buffer created in the data files. If we are
upgrading to an InnoDB version which supports multiple tablespaces, then this
@@ -86,40 +98,40 @@ UNIV_INTERN
void
trx_sys_doublewrite_init_or_restore_pages(
/*======================================*/
- ibool restore_corrupt_pages);
-/********************************************************************
+ ibool restore_corrupt_pages); /*!< in: TRUE=restore pages */
+/****************************************************************//**
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
multiple tablespace format. */
UNIV_INTERN
void
trx_sys_mark_upgraded_to_multiple_tablespaces(void);
/*===============================================*/
-/********************************************************************
-Determines if a page number is located inside the doublewrite buffer. */
+/****************************************************************//**
+Determines if a page number is located inside the doublewrite buffer.
+@return TRUE if the location is inside the two blocks of the
+doublewrite buffer */
UNIV_INTERN
ibool
trx_doublewrite_page_inside(
/*========================*/
- /* out: TRUE if the location is inside
- the two blocks of the doublewrite buffer */
- ulint page_no); /* in: page number */
-/*******************************************************************
-Checks if a page address is the trx sys header page. */
+ ulint page_no); /*!< in: page number */
+/***************************************************************//**
+Checks if a page address is the trx sys header page.
+@return TRUE if trx sys header page */
UNIV_INLINE
ibool
trx_sys_hdr_page(
/*=============*/
- /* out: TRUE if trx sys header page */
- ulint space, /* in: space */
- ulint page_no);/* in: page number */
-/*********************************************************************
+ ulint space, /*!< in: space */
+ ulint page_no);/*!< in: page number */
+/*****************************************************************//**
Creates and initializes the central memory structures for the transaction
system. This is called when the database is started. */
UNIV_INTERN
void
trx_sys_init_at_db_start(void);
/*==========================*/
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the transaction system at the database creation. */
UNIV_INTERN
void
@@ -132,104 +144,102 @@ void
trx_sys_create_extra_rseg(
/*======================*/
ulint num); /* in: number of extra user rollback segments */
-/********************************************************************
-Looks for a free slot for a rollback segment in the trx system file copy. */
+/****************************************************************//**
+Looks for a free slot for a rollback segment in the trx system file copy.
+@return slot index or ULINT_UNDEFINED if not found */
UNIV_INTERN
ulint
trx_sysf_rseg_find_free(
/*====================*/
- /* out: slot index or ULINT_UNDEFINED
- if not found */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
-Gets the pointer in the nth slot of the rseg array. */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
+Gets the pointer in the nth slot of the rseg array.
+@return pointer to rseg object, NULL if slot not in use */
UNIV_INLINE
trx_rseg_t*
trx_sys_get_nth_rseg(
/*=================*/
- /* out: pointer to rseg object, NULL if slot
- not in use */
- trx_sys_t* sys, /* in: trx system */
- ulint n); /* in: index of slot */
-/*******************************************************************
+ trx_sys_t* sys, /*!< in: trx system */
+ ulint n); /*!< in: index of slot */
+/***************************************************************//**
Sets the pointer in the nth slot of the rseg array. */
UNIV_INLINE
void
trx_sys_set_nth_rseg(
/*=================*/
- trx_sys_t* sys, /* in: trx system */
- ulint n, /* in: index of slot */
- trx_rseg_t* rseg); /* in: pointer to rseg object, NULL if slot
+ trx_sys_t* sys, /*!< in: trx system */
+ ulint n, /*!< in: index of slot */
+ trx_rseg_t* rseg); /*!< in: pointer to rseg object, NULL if slot
not in use */
-/**************************************************************************
-Gets a pointer to the transaction system file copy and x-locks its page. */
+/**********************************************************************//**
+Gets a pointer to the transaction system file copy and x-locks its page.
+@return pointer to system file copy, page x-locked */
UNIV_INLINE
trx_sysf_t*
trx_sysf_get(
/*=========*/
- /* out: pointer to system file copy, page x-locked */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Gets the space of the nth rollback segment slot in the trx system
-file copy. */
+file copy.
+@return space id */
UNIV_INLINE
ulint
trx_sysf_rseg_get_space(
/*====================*/
- /* out: space id */
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Gets the page number of the nth rollback segment slot in the trx system
-file copy. */
+file copy.
+@return page number, FIL_NULL if slot unused */
UNIV_INLINE
ulint
trx_sysf_rseg_get_page_no(
/*======================*/
- /* out: page number, FIL_NULL
- if slot unused */
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Sets the space id of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_space(
/*====================*/
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- ulint space, /* in: space id */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ ulint space, /*!< in: space id */
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Sets the page number of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_page_no(
/*======================*/
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- ulint page_no, /* in: page number, FIL_NULL if
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ ulint page_no, /*!< in: page number, FIL_NULL if
the slot is reset to unused */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
-Allocates a new transaction id. */
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
+Allocates a new transaction id.
+@return new, allocated trx id */
UNIV_INLINE
-dulint
+trx_id_t
trx_sys_get_new_trx_id(void);
/*========================*/
- /* out: new, allocated trx id */
-/*********************************************************************
-Allocates a new transaction number. */
+/*****************************************************************//**
+Allocates a new transaction number.
+@return new, allocated trx number */
UNIV_INLINE
-dulint
+trx_id_t
trx_sys_get_new_trx_no(void);
/*========================*/
- /* out: new, allocated trx number */
-/*********************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/*****************************************************************//**
Writes a trx id to an index page. In case that the id size changes in
some future version, this function should be used instead of
mach_write_... */
@@ -237,54 +247,54 @@ UNIV_INLINE
void
trx_write_trx_id(
/*=============*/
- byte* ptr, /* in: pointer to memory where written */
- dulint id); /* in: id */
-/*********************************************************************
+ byte* ptr, /*!< in: pointer to memory where written */
+ trx_id_t id); /*!< in: id */
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Reads a trx id from an index page. In case that the id size changes in
some future version, this function should be used instead of
-mach_read_... */
+mach_read_...
+@return id */
UNIV_INLINE
-dulint
+trx_id_t
trx_read_trx_id(
/*============*/
- /* out: id */
- const byte* ptr); /* in: pointer to memory from where to read */
-/********************************************************************
-Looks for the trx handle with the given id in trx_list. */
+ const byte* ptr); /*!< in: pointer to memory from where to read */
+/****************************************************************//**
+Looks for the trx handle with the given id in trx_list.
+@return the trx handle or NULL if not found */
UNIV_INLINE
trx_t*
trx_get_on_id(
/*==========*/
- /* out: the trx handle or NULL if not found */
- dulint trx_id); /* in: trx id to search for */
-/********************************************************************
+ trx_id_t trx_id);/*!< in: trx id to search for */
+/****************************************************************//**
Returns the minumum trx id in trx list. This is the smallest id for which
the trx can possibly be active. (But, you must look at the trx->conc_state to
find out if the minimum trx id transaction itself is active, or already
-committed.) */
+committed.)
+@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
UNIV_INLINE
-dulint
+trx_id_t
trx_list_get_min_trx_id(void);
/*=========================*/
- /* out: the minimum trx id, or trx_sys->max_trx_id
- if the trx list is empty */
-/********************************************************************
-Checks if a transaction with the given id is active. */
+/****************************************************************//**
+Checks if a transaction with the given id is active.
+@return TRUE if active */
UNIV_INLINE
ibool
trx_is_active(
/*==========*/
- /* out: TRUE if active */
- dulint trx_id);/* in: trx id of the transaction */
-/********************************************************************
-Checks that trx is in the trx list. */
+ trx_id_t trx_id);/*!< in: trx id of the transaction */
+/****************************************************************//**
+Checks that trx is in the trx list.
+@return TRUE if is in */
UNIV_INTERN
ibool
trx_in_trx_list(
/*============*/
- /* out: TRUE if is in */
- trx_t* in_trx);/* in: trx */
-/*********************************************************************
+ trx_t* in_trx);/*!< in: trx */
+/*****************************************************************//**
Updates the offset information about the end of the MySQL binlog entry
which corresponds to the transaction just being committed. In a MySQL
replication slave updates the latest master binlog position up to which
@@ -293,50 +303,38 @@ UNIV_INTERN
void
trx_sys_update_mysql_binlog_offset(
/*===============================*/
- const char* file_name_in,/* in: MySQL log file name */
- ib_int64_t offset, /* in: position in that log file */
- ulint field, /* in: offset of the MySQL log info field in
+ const char* file_name_in,/*!< in: MySQL log file name */
+ ib_int64_t offset, /*!< in: position in that log file */
+ ulint field, /*!< in: offset of the MySQL log info field in
the trx sys header */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Prints to stderr the MySQL binlog offset info in the trx system header if
the magic number shows it valid. */
UNIV_INTERN
void
trx_sys_print_mysql_binlog_offset(void);
/*===================================*/
-#ifdef UNIV_HOTBACKUP
-/*********************************************************************
-Prints to stderr the MySQL binlog info in the system header if the
-magic number shows it valid. */
-UNIV_INTERN
-void
-trx_sys_print_mysql_binlog_offset_from_page(
-/*========================================*/
- const byte* page); /* in: buffer containing the trx
- system header page, i.e., page number
- TRX_SYS_PAGE_NO in the tablespace */
-#endif /* UNIV_HOTBACKUP */
-/*********************************************************************
+/*****************************************************************//**
Prints to stderr the MySQL master log offset info in the trx system header if
the magic number shows it valid. */
UNIV_INTERN
void
trx_sys_print_mysql_master_log_pos(void);
/*====================================*/
-/*********************************************************************
+/*****************************************************************//**
Initializes the tablespace tag system. */
UNIV_INTERN
void
trx_sys_file_format_init(void);
/*==========================*/
-/*********************************************************************
+/*****************************************************************//**
Closes the tablespace tag system. */
UNIV_INTERN
void
trx_sys_file_format_close(void);
/*===========================*/
-/************************************************************************
+/********************************************************************//**
Tags the system table space with minimum format id if it has not been
tagged yet.
WARNING: This function is only called during the startup and AFTER the
@@ -345,213 +343,291 @@ UNIV_INTERN
void
trx_sys_file_format_tag_init(void);
/*==============================*/
-/*********************************************************************
-Get the name representation of the file format from its id. */
+/*****************************************************************//**
+Shutdown/Close the transaction system. */
+UNIV_INTERN
+void
+trx_sys_close(void);
+/*===============*/
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
UNIV_INTERN
const char*
trx_sys_file_format_id_to_name(
/*===========================*/
- /* out: pointer to the name */
- const ulint id); /* in: id of the file format */
-/*********************************************************************
+ const ulint id); /*!< in: id of the file format */
+/*****************************************************************//**
Set the file format id unconditionally except if it's already the
-same value. */
+same value.
+@return TRUE if value updated */
UNIV_INTERN
ibool
trx_sys_file_format_max_set(
/*========================*/
- /* out: TRUE if value updated */
- ulint format_id, /* in: file format id */
- const char** name); /* out: max file format name or
+ ulint format_id, /*!< in: file format id */
+ const char** name); /*!< out: max file format name or
NULL if not needed. */
-/*********************************************************************
-Get the name representation of the file format from its id. */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the max format name */
UNIV_INTERN
const char*
trx_sys_file_format_max_get(void);
/*=============================*/
- /* out: pointer to the max format name */
-/*********************************************************************
-Check for the max file format tag stored on disk. */
+/*****************************************************************//**
+Check for the max file format tag stored on disk.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
trx_sys_file_format_max_check(
/*==========================*/
- /* out: DB_SUCCESS or error code */
- ulint max_format_id); /* in: the max format id to check */
-/************************************************************************
+ ulint max_format_id); /*!< in: the max format id to check */
+/********************************************************************//**
Update the file format tag in the system tablespace only if the given
-format id is greater than the known max id. */
+format id is greater than the known max id.
+@return TRUE if format_id was bigger than the known max id */
UNIV_INTERN
ibool
trx_sys_file_format_max_upgrade(
/*============================*/
- /* out: TRUE if format_id was
- bigger than the known max id */
- const char** name, /* out: max file format name */
- ulint format_id); /* in: file format identifier */
+ const char** name, /*!< out: max file format name */
+ ulint format_id); /*!< in: file format identifier */
+#else /* !UNIV_HOTBACKUP */
+/*****************************************************************//**
+Prints to stderr the MySQL binlog info in the system header if the
+magic number shows it valid. */
+UNIV_INTERN
+void
+trx_sys_print_mysql_binlog_offset_from_page(
+/*========================================*/
+ const byte* page); /*!< in: buffer containing the trx
+ system header page, i.e., page number
+ TRX_SYS_PAGE_NO in the tablespace */
+/*****************************************************************//**
+Reads the file format id from the first system table space file.
+Even if the call succeeds and returns TRUE, the returned format id
+may be ULINT_UNDEFINED signalling that the format id was not present
+in the data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_file_format_id(
+/*========================*/
+ const char *pathname, /*!< in: pathname of the first system
+ table space file */
+ ulint *format_id); /*!< out: file format of the system table
+ space */
+/*****************************************************************//**
+Reads the file format id from the given per-table data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_pertable_file_format_id(
+/*=================================*/
+ const char *pathname, /*!< in: pathname of a per-table
+ datafile */
+ ulint *format_id); /*!< out: file format of the per-table
+ data file */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
+UNIV_INTERN
+const char*
+trx_sys_file_format_id_to_name(
+/*===========================*/
+ const ulint id); /*!< in: id of the file format */
+
+#endif /* !UNIV_HOTBACKUP */
/* The automatically created system rollback segment has this id */
#define TRX_SYS_SYSTEM_RSEG_ID 0
/* Space id and page no where the trx system file copy resides */
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
+#include "fsp0fsp.h"
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
/* The offset of the transaction system header on the page */
#define TRX_SYS FSEG_PAGE_DATA
-/* Transaction system header */
-/*-------------------------------------------------------------*/
-#define TRX_SYS_TRX_ID_STORE 0 /* the maximum trx id or trx number
- modulo TRX_SYS_TRX_ID_UPDATE_MARGIN
+/** Transaction system header */
+/*------------------------------------------------------------- @{ */
+#define TRX_SYS_TRX_ID_STORE 0 /*!< the maximum trx id or trx
+ number modulo
+ TRX_SYS_TRX_ID_UPDATE_MARGIN
written to a file page by any
transaction; the assignment of
- transaction ids continues from this
- number rounded up by .._MARGIN plus
- .._MARGIN when the database is
+ transaction ids continues from
+ this number rounded up by
+ TRX_SYS_TRX_ID_UPDATE_MARGIN
+ plus
+ TRX_SYS_TRX_ID_UPDATE_MARGIN
+ when the database is
started */
-#define TRX_SYS_FSEG_HEADER 8 /* segment header for the tablespace
- segment the trx system is created
- into */
+#define TRX_SYS_FSEG_HEADER 8 /*!< segment header for the
+ tablespace segment the trx
+ system is created into */
#define TRX_SYS_RSEGS (8 + FSEG_HEADER_SIZE)
- /* the start of the array of rollback
- segment specification slots */
-/*-------------------------------------------------------------*/
-
-/* Max number of rollback segments: the number of segment specification slots
-in the transaction system array; rollback segment id must fit in one byte,
-therefore 256; each slot is currently 8 bytes in size */
+ /*!< the start of the array of
+ rollback segment specification
+ slots */
+/*------------------------------------------------------------- @} */
+
+/** Maximum number of rollback segments: the number of segment
+specification slots in the transaction system array; rollback segment
+id must fit in one byte, therefore 256; each slot is currently 8 bytes
+in size */
#define TRX_SYS_N_RSEGS 256
+/** Maximum length of MySQL binlog file name, in bytes.
+@see trx_sys_mysql_master_log_name
+@see trx_sys_mysql_bin_log_name */
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
#define TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN 480 /* (500 - 12) is dead line. */
+/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
#if UNIV_PAGE_SIZE < 4096
# error "UNIV_PAGE_SIZE < 4096"
#endif
-/* The offset of the MySQL replication info in the trx system header;
+/** The offset of the MySQL replication info in the trx system header;
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
#define TRX_SYS_MYSQL_RELAY_LOG_INFO (UNIV_PAGE_SIZE - 1500)
-/* The offset of the MySQL binlog offset info in the trx system header */
+/** The offset of the MySQL binlog offset info in the trx system header */
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
-#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /* magic number which shows
+#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /*!< magic number which is
+ TRX_SYS_MYSQL_LOG_MAGIC_N
if we have valid data in the
- MySQL binlog info; the value
- is ..._MAGIC_N if yes */
-#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /* high 4 bytes of the offset
+ MySQL binlog info */
+#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /*!< high 4 bytes of the offset
within that file */
-#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /* low 4 bytes of the offset
+#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /*!< low 4 bytes of the offset
within that file */
-#define TRX_SYS_MYSQL_LOG_NAME 12 /* MySQL log file name */
+#define TRX_SYS_MYSQL_LOG_NAME 12 /*!< MySQL log file name */
-/* The offset of the doublewrite buffer header on the trx system header page */
+#ifndef UNIV_HOTBACKUP
+/** Doublewrite buffer */
+/* @{ */
+/** The offset of the doublewrite buffer header on the trx system header page */
#define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200)
/*-------------------------------------------------------------*/
-#define TRX_SYS_DOUBLEWRITE_FSEG 0 /* fseg header of the fseg
+#define TRX_SYS_DOUBLEWRITE_FSEG 0 /*!< fseg header of the fseg
containing the doublewrite
buffer */
#define TRX_SYS_DOUBLEWRITE_MAGIC FSEG_HEADER_SIZE
- /* 4-byte magic number which
+ /*!< 4-byte magic number which
shows if we already have
created the doublewrite
buffer */
#define TRX_SYS_DOUBLEWRITE_BLOCK1 (4 + FSEG_HEADER_SIZE)
- /* page number of the
+ /*!< page number of the
first page in the first
sequence of 64
(= FSP_EXTENT_SIZE) consecutive
pages in the doublewrite
buffer */
#define TRX_SYS_DOUBLEWRITE_BLOCK2 (8 + FSEG_HEADER_SIZE)
- /* page number of the
+ /*!< page number of the
first page in the second
sequence of 64 consecutive
pages in the doublewrite
buffer */
-#define TRX_SYS_DOUBLEWRITE_REPEAT 12 /* we repeat the above 3
- numbers so that if the trx
- sys header is half-written
- to disk, we still may be able
- to recover the information */
+#define TRX_SYS_DOUBLEWRITE_REPEAT 12 /*!< we repeat
+ TRX_SYS_DOUBLEWRITE_MAGIC,
+ TRX_SYS_DOUBLEWRITE_BLOCK1,
+ TRX_SYS_DOUBLEWRITE_BLOCK2
+ so that if the trx sys
+ header is half-written
+ to disk, we still may
+ be able to recover the
+ information */
+/** If this is not yet set to TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
+we must reset the doublewrite buffer, because starting from 4.1.x the
+space id of a data page is stored into
+FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED (24 + FSEG_HEADER_SIZE)
- /* If this is not yet set to
- .._N, we must reset the
- doublewrite buffer, because
- starting from 4.1.x the space
- id of a data page is stored to
- FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO */
+
/*-------------------------------------------------------------*/
+/** Contents of TRX_SYS_DOUBLEWRITE_MAGIC */
#define TRX_SYS_DOUBLEWRITE_MAGIC_N 536853855
+/** Contents of TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED */
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N 1783657386
-
+/** Size of the doublewrite block in pages */
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
+/* @} */
-/* The offset of the file format tag on the trx system header page */
+/** File format tag */
+/* @{ */
+/** The offset of the file format tag on the trx system header page
+(TRX_SYS_PAGE_NO of TRX_SYS_SPACE) */
#define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
-/* We use these random constants to reduce the probability of reading
-garbage (from previous versions) that maps to an actual format id. We
-use these as bit masks at the time of reading and writing from/to disk. */
+/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format
+identifier is added to this constant. */
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
+/** Contents of TRX_SYS_FILE_FORMAT_TAG+4 when valid */
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
+/* @} */
-/* Doublewrite control struct */
+/** Doublewrite control struct */
struct trx_doublewrite_struct{
- mutex_t mutex; /* mutex protecting the first_free field and
+ mutex_t mutex; /*!< mutex protecting the first_free field and
write_buf */
- ulint block1; /* the page number of the first
+ ulint block1; /*!< the page number of the first
doublewrite block (64 pages) */
- ulint block2; /* page number of the second block */
- ulint first_free; /* first free position in write_buf measured
+ ulint block2; /*!< page number of the second block */
+ ulint first_free; /*!< first free position in write_buf measured
in units of UNIV_PAGE_SIZE */
- byte* write_buf; /* write buffer used in writing to the
+ byte* write_buf; /*!< write buffer used in writing to the
doublewrite buffer, aligned to an
address divisible by UNIV_PAGE_SIZE
(which is required by Windows aio) */
- byte* write_buf_unaligned; /* pointer to write_buf, but unaligned */
+ byte* write_buf_unaligned;
+ /*!< pointer to write_buf, but unaligned */
buf_page_t**
- buf_block_arr; /* array to store pointers to the buffer
+ buf_block_arr; /*!< array to store pointers to the buffer
blocks which have been cached to write_buf */
};
-/* The transaction system central memory data structure; protected by the
+/** The transaction system central memory data structure; protected by the
kernel mutex */
struct trx_sys_struct{
- dulint max_trx_id; /* The smallest number not yet
+ trx_id_t max_trx_id; /*!< The smallest number not yet
assigned as a transaction id or
transaction number */
UT_LIST_BASE_NODE_T(trx_t) trx_list;
- /* List of active and committed in
+ /*!< List of active and committed in
memory transactions, sorted on trx id,
biggest first */
UT_LIST_BASE_NODE_T(trx_t) mysql_trx_list;
- /* List of transactions created
+ /*!< List of transactions created
for MySQL */
UT_LIST_BASE_NODE_T(trx_rseg_t) rseg_list;
- /* List of rollback segment objects */
- trx_rseg_t* latest_rseg; /* Latest rollback segment in the
+ /*!< List of rollback segment
+ objects */
+ trx_rseg_t* latest_rseg; /*!< Latest rollback segment in the
round-robin assignment of rollback
segments to transactions */
trx_rseg_t* rseg_array[TRX_SYS_N_RSEGS];
- /* Pointer array to rollback segments;
- NULL if slot not in use */
- ulint rseg_history_len;/* Length of the TRX_RSEG_HISTORY
+ /*!< Pointer array to rollback
+ segments; NULL if slot not in use */
+ ulint rseg_history_len;/*!< Length of the TRX_RSEG_HISTORY
list (update undo logs for committed
transactions), protected by
rseg->mutex */
UT_LIST_BASE_NODE_T(read_view_t) view_list;
- /* List of read views sorted on trx no,
- biggest first */
+ /*!< List of read views sorted
+ on trx no, biggest first */
};
-/* When a trx id which is zero modulo this number (which must be a power of
+/** When a trx id which is zero modulo this number (which must be a power of
two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
page is updated */
#define TRX_SYS_TRX_ID_WRITE_MARGIN 256
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "trx0sys.ic"
diff --git a/storage/xtradb/include/trx0sys.ic b/storage/xtradb/include/trx0sys.ic
index 4437133188f..820d31d0692 100644
--- a/storage/xtradb/include/trx0sys.ic
+++ b/storage/xtradb/include/trx0sys.ic
@@ -16,47 +16,51 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0sys.ic
Transaction system
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-#include "srv0srv.h"
#include "trx0trx.h"
+#include "data0type.h"
+#ifndef UNIV_HOTBACKUP
+# include "srv0srv.h"
+# include "mtr0log.h"
/* The typedef for rseg slot in the file copy */
typedef byte trx_sysf_rseg_t;
/* Rollback segment specification slot offsets */
/*-------------------------------------------------------------*/
-#define TRX_SYS_RSEG_SPACE 0 /* space where the the segment
+#define TRX_SYS_RSEG_SPACE 0 /* space where the segment
header is placed; starting with
MySQL/InnoDB 5.1.7, this is
UNIV_UNDEFINED if the slot is unused */
-#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the the segment
+#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the segment
header is placed; this is FIL_NULL
if the slot is unused */
/*-------------------------------------------------------------*/
/* Size of a rollback segment specification slot */
#define TRX_SYS_RSEG_SLOT_SIZE 8
-/*********************************************************************
+/*****************************************************************//**
Writes the value of max_trx_id to the file based trx system header. */
UNIV_INTERN
void
trx_sys_flush_max_trx_id(void);
/*==========================*/
-/*******************************************************************
-Checks if a page address is the trx sys header page. */
+/***************************************************************//**
+Checks if a page address is the trx sys header page.
+@return TRUE if trx sys header page */
UNIV_INLINE
ibool
trx_sys_hdr_page(
/*=============*/
- /* out: TRUE if trx sys header page */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
if ((space == TRX_SYS_SPACE) && (page_no == TRX_SYS_PAGE_NO)) {
@@ -66,16 +70,15 @@ trx_sys_hdr_page(
return(FALSE);
}
-/*******************************************************************
-Gets the pointer in the nth slot of the rseg array. */
+/***************************************************************//**
+Gets the pointer in the nth slot of the rseg array.
+@return pointer to rseg object, NULL if slot not in use */
UNIV_INLINE
trx_rseg_t*
trx_sys_get_nth_rseg(
/*=================*/
- /* out: pointer to rseg object, NULL if slot
- not in use */
- trx_sys_t* sys, /* in: trx system */
- ulint n) /* in: index of slot */
+ trx_sys_t* sys, /*!< in: trx system */
+ ulint n) /*!< in: index of slot */
{
ut_ad(mutex_own(&(kernel_mutex)));
ut_ad(n < TRX_SYS_N_RSEGS);
@@ -83,15 +86,15 @@ trx_sys_get_nth_rseg(
return(sys->rseg_array[n]);
}
-/*******************************************************************
+/***************************************************************//**
Sets the pointer in the nth slot of the rseg array. */
UNIV_INLINE
void
trx_sys_set_nth_rseg(
/*=================*/
- trx_sys_t* sys, /* in: trx system */
- ulint n, /* in: index of slot */
- trx_rseg_t* rseg) /* in: pointer to rseg object, NULL if slot
+ trx_sys_t* sys, /*!< in: trx system */
+ ulint n, /*!< in: index of slot */
+ trx_rseg_t* rseg) /*!< in: pointer to rseg object, NULL if slot
not in use */
{
ut_ad(n < TRX_SYS_N_RSEGS);
@@ -99,14 +102,14 @@ trx_sys_set_nth_rseg(
sys->rseg_array[n] = rseg;
}
-/**************************************************************************
-Gets a pointer to the transaction system header and x-latches its page. */
+/**********************************************************************//**
+Gets a pointer to the transaction system header and x-latches its page.
+@return pointer to system header, page x-latched. */
UNIV_INLINE
trx_sysf_t*
trx_sysf_get(
/*=========*/
- /* out: pointer to system header, page x-latched. */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
trx_sysf_t* header;
@@ -122,17 +125,17 @@ trx_sysf_get(
return(header);
}
-/*********************************************************************
+/*****************************************************************//**
Gets the space of the nth rollback segment slot in the trx system
-file copy. */
+file copy.
+@return space id */
UNIV_INLINE
ulint
trx_sysf_rseg_get_space(
/*====================*/
- /* out: space id */
- trx_sysf_t* sys_header, /* in: trx sys header */
- ulint i, /* in: slot index == rseg id */
- mtr_t* mtr) /* in: mtr */
+ trx_sysf_t* sys_header, /*!< in: trx sys header */
+ ulint i, /*!< in: slot index == rseg id */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mutex_own(&(kernel_mutex)));
ut_ad(sys_header);
@@ -143,18 +146,17 @@ trx_sysf_rseg_get_space(
+ TRX_SYS_RSEG_SPACE, MLOG_4BYTES, mtr));
}
-/*********************************************************************
+/*****************************************************************//**
Gets the page number of the nth rollback segment slot in the trx system
-header. */
+header.
+@return page number, FIL_NULL if slot unused */
UNIV_INLINE
ulint
trx_sysf_rseg_get_page_no(
/*======================*/
- /* out: page number, FIL_NULL
- if slot unused */
- trx_sysf_t* sys_header, /* in: trx system header */
- ulint i, /* in: slot index == rseg id */
- mtr_t* mtr) /* in: mtr */
+ trx_sysf_t* sys_header, /*!< in: trx system header */
+ ulint i, /*!< in: slot index == rseg id */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(sys_header);
ut_ad(mutex_own(&(kernel_mutex)));
@@ -165,17 +167,17 @@ trx_sysf_rseg_get_page_no(
+ TRX_SYS_RSEG_PAGE_NO, MLOG_4BYTES, mtr));
}
-/*********************************************************************
+/*****************************************************************//**
Sets the space id of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_space(
/*====================*/
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- ulint space, /* in: space id */
- mtr_t* mtr) /* in: mtr */
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ ulint space, /*!< in: space id */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mutex_own(&(kernel_mutex)));
ut_ad(sys_header);
@@ -188,18 +190,18 @@ trx_sysf_rseg_set_space(
MLOG_4BYTES, mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Sets the page number of the nth rollback segment slot in the trx system
header. */
UNIV_INLINE
void
trx_sysf_rseg_set_page_no(
/*======================*/
- trx_sysf_t* sys_header, /* in: trx sys header */
- ulint i, /* in: slot index == rseg id */
- ulint page_no, /* in: page number, FIL_NULL if the
+ trx_sysf_t* sys_header, /*!< in: trx sys header */
+ ulint i, /*!< in: slot index == rseg id */
+ ulint page_no, /*!< in: page number, FIL_NULL if the
slot is reset to unused */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mutex_own(&(kernel_mutex)));
ut_ad(sys_header);
@@ -211,8 +213,9 @@ trx_sysf_rseg_set_page_no(
page_no,
MLOG_4BYTES, mtr);
}
+#endif /* !UNIV_HOTBACKUP */
-/*********************************************************************
+/*****************************************************************//**
Writes a trx id to an index page. In case that the id size changes in
some future version, this function should be used instead of
mach_write_... */
@@ -220,8 +223,8 @@ UNIV_INLINE
void
trx_write_trx_id(
/*=============*/
- byte* ptr, /* in: pointer to memory where written */
- dulint id) /* in: id */
+ byte* ptr, /*!< in: pointer to memory where written */
+ trx_id_t id) /*!< in: id */
{
#if DATA_TRX_ID_LEN != 6
# error "DATA_TRX_ID_LEN != 6"
@@ -229,16 +232,17 @@ trx_write_trx_id(
mach_write_to_6(ptr, id);
}
-/*********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Reads a trx id from an index page. In case that the id size changes in
some future version, this function should be used instead of
-mach_read_... */
+mach_read_...
+@return id */
UNIV_INLINE
-dulint
+trx_id_t
trx_read_trx_id(
/*============*/
- /* out: id */
- const byte* ptr) /* in: pointer to memory from where to read */
+ const byte* ptr) /*!< in: pointer to memory from where to read */
{
#if DATA_TRX_ID_LEN != 6
# error "DATA_TRX_ID_LEN != 6"
@@ -246,14 +250,14 @@ trx_read_trx_id(
return(mach_read_from_6(ptr));
}
-/********************************************************************
-Looks for the trx handle with the given id in trx_list. */
+/****************************************************************//**
+Looks for the trx handle with the given id in trx_list.
+@return the trx handle or NULL if not found */
UNIV_INLINE
trx_t*
trx_get_on_id(
/*==========*/
- /* out: the trx handle or NULL if not found */
- dulint trx_id) /* in: trx id to search for */
+ trx_id_t trx_id) /*!< in: trx id to search for */
{
trx_t* trx;
@@ -273,17 +277,16 @@ trx_get_on_id(
return(NULL);
}
-/********************************************************************
+/****************************************************************//**
Returns the minumum trx id in trx list. This is the smallest id for which
the trx can possibly be active. (But, you must look at the trx->conc_state to
find out if the minimum trx id transaction itself is active, or already
-committed.) */
+committed.)
+@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
UNIV_INLINE
-dulint
+trx_id_t
trx_list_get_min_trx_id(void)
/*=========================*/
- /* out: the minimum trx id, or trx_sys->max_trx_id
- if the trx list is empty */
{
trx_t* trx;
@@ -299,14 +302,14 @@ trx_list_get_min_trx_id(void)
return(trx->id);
}
-/********************************************************************
-Checks if a transaction with the given id is active. */
+/****************************************************************//**
+Checks if a transaction with the given id is active.
+@return TRUE if active */
UNIV_INLINE
ibool
trx_is_active(
/*==========*/
- /* out: TRUE if active */
- dulint trx_id) /* in: trx id of the transaction */
+ trx_id_t trx_id) /*!< in: trx id of the transaction */
{
trx_t* trx;
@@ -337,15 +340,15 @@ trx_is_active(
return(FALSE);
}
-/*********************************************************************
-Allocates a new transaction id. */
+/*****************************************************************//**
+Allocates a new transaction id.
+@return new, allocated trx id */
UNIV_INLINE
-dulint
+trx_id_t
trx_sys_get_new_trx_id(void)
/*========================*/
- /* out: new, allocated trx id */
{
- dulint id;
+ trx_id_t id;
ut_ad(mutex_own(&kernel_mutex));
@@ -369,15 +372,16 @@ trx_sys_get_new_trx_id(void)
return(id);
}
-/*********************************************************************
-Allocates a new transaction number. */
+/*****************************************************************//**
+Allocates a new transaction number.
+@return new, allocated trx number */
UNIV_INLINE
-dulint
+trx_id_t
trx_sys_get_new_trx_no(void)
/*========================*/
- /* out: new, allocated trx number */
{
ut_ad(mutex_own(&kernel_mutex));
return(trx_sys_get_new_trx_id());
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index 1bec1ff73be..3b845e498d0 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0trx.h
The transaction
Created 3/26/1996 Heikki Tuuri
@@ -27,99 +28,100 @@ Created 3/26/1996 Heikki Tuuri
#include "univ.i"
#include "trx0types.h"
+#include "dict0types.h"
+#ifndef UNIV_HOTBACKUP
#include "lock0types.h"
#include "usr0types.h"
#include "que0types.h"
#include "mem0mem.h"
#include "read0types.h"
-#include "dict0types.h"
#include "trx0xa.h"
#include "ut0vec.h"
-/* Dummy session used currently in MySQL interface */
+/** Dummy session used currently in MySQL interface */
extern sess_t* trx_dummy_sess;
-/* Number of transactions currently allocated for MySQL: protected by
+/** Number of transactions currently allocated for MySQL: protected by
the kernel mutex */
extern ulint trx_n_mysql_transactions;
-/************************************************************************
+/********************************************************************//**
Releases the search latch if trx has reserved it. */
UNIV_INTERN
void
trx_search_latch_release_if_reserved(
/*=================================*/
- trx_t* trx); /* in: transaction */
-/**********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/******************************************************************//**
Set detailed error message for the transaction. */
UNIV_INTERN
void
trx_set_detailed_error(
/*===================*/
- trx_t* trx, /* in: transaction struct */
- const char* msg); /* in: detailed error message */
-/*****************************************************************
+ trx_t* trx, /*!< in: transaction struct */
+ const char* msg); /*!< in: detailed error message */
+/*************************************************************//**
Set detailed error message for the transaction from a file. Note that the
file is rewinded before reading from it. */
UNIV_INTERN
void
trx_set_detailed_error_from_file(
/*=============================*/
- trx_t* trx, /* in: transaction struct */
- FILE* file); /* in: file to read message from */
-/********************************************************************
-Retrieves the error_info field from a trx. */
+ trx_t* trx, /*!< in: transaction struct */
+ FILE* file); /*!< in: file to read message from */
+/****************************************************************//**
+Retrieves the error_info field from a trx.
+@return the error info */
UNIV_INLINE
const dict_index_t*
trx_get_error_info(
/*===============*/
- /* out: the error info */
- const trx_t* trx); /* in: trx object */
-/********************************************************************
-Creates and initializes a transaction object. */
+ const trx_t* trx); /*!< in: trx object */
+/****************************************************************//**
+Creates and initializes a transaction object.
+@return own: the transaction */
UNIV_INTERN
trx_t*
trx_create(
/*=======*/
- /* out, own: the transaction */
- sess_t* sess) /* in: session */
+ sess_t* sess) /*!< in: session */
__attribute__((nonnull));
-/************************************************************************
-Creates a transaction object for MySQL. */
+/********************************************************************//**
+Creates a transaction object for MySQL.
+@return own: transaction object */
UNIV_INTERN
trx_t*
trx_allocate_for_mysql(void);
/*========================*/
- /* out, own: transaction object */
-/************************************************************************
-Creates a transaction object for background operations by the master thread. */
+/********************************************************************//**
+Creates a transaction object for background operations by the master thread.
+@return own: transaction object */
UNIV_INTERN
trx_t*
trx_allocate_for_background(void);
/*=============================*/
- /* out, own: transaction object */
-/************************************************************************
+/********************************************************************//**
Frees a transaction object. */
UNIV_INTERN
void
trx_free(
/*=====*/
- trx_t* trx); /* in, own: trx object */
-/************************************************************************
+ trx_t* trx); /*!< in, own: trx object */
+/********************************************************************//**
Frees a transaction object for MySQL. */
UNIV_INTERN
void
trx_free_for_mysql(
/*===============*/
- trx_t* trx); /* in, own: trx object */
-/************************************************************************
+ trx_t* trx); /*!< in, own: trx object */
+/********************************************************************//**
Frees a transaction object of a background operation of the master thread. */
UNIV_INTERN
void
trx_free_for_background(
/*====================*/
- trx_t* trx); /* in, own: trx object */
-/********************************************************************
+ trx_t* trx); /*!< in, own: trx object */
+/****************************************************************//**
Creates trx objects for transactions and initializes the trx list of
trx_sys at database start. Rollback segment and undo log lists must
already exist when this function is called, because the lists of
@@ -129,122 +131,122 @@ UNIV_INTERN
void
trx_lists_init_at_db_start(void);
/*============================*/
-/********************************************************************
-Starts a new transaction. */
+/****************************************************************//**
+Starts a new transaction.
+@return TRUE if success, FALSE if the rollback segment could not
+support this many transactions */
UNIV_INTERN
ibool
trx_start(
/*======*/
- /* out: TRUE if success, FALSE if the rollback
- segment could not support this many transactions */
- trx_t* trx, /* in: transaction */
- ulint rseg_id);/* in: rollback segment id; if ULINT_UNDEFINED
+ trx_t* trx, /*!< in: transaction */
+ ulint rseg_id);/*!< in: rollback segment id; if ULINT_UNDEFINED
is passed, the system chooses the rollback segment
automatically in a round-robin fashion */
-/********************************************************************
-Starts a new transaction. */
+/****************************************************************//**
+Starts a new transaction.
+@return TRUE */
UNIV_INTERN
ibool
trx_start_low(
/*==========*/
- /* out: TRUE */
- trx_t* trx, /* in: transaction */
- ulint rseg_id);/* in: rollback segment id; if ULINT_UNDEFINED
+ trx_t* trx, /*!< in: transaction */
+ ulint rseg_id);/*!< in: rollback segment id; if ULINT_UNDEFINED
is passed, the system chooses the rollback segment
automatically in a round-robin fashion */
-/*****************************************************************
+/*************************************************************//**
Starts the transaction if it is not yet started. */
UNIV_INLINE
void
trx_start_if_not_started(
/*=====================*/
- trx_t* trx); /* in: transaction */
-/*****************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*************************************************************//**
Starts the transaction if it is not yet started. Assumes we have reserved
the kernel mutex! */
UNIV_INLINE
void
trx_start_if_not_started_low(
/*=========================*/
- trx_t* trx); /* in: transaction */
-/********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/****************************************************************//**
Commits a transaction. */
UNIV_INTERN
void
trx_commit_off_kernel(
/*==================*/
- trx_t* trx); /* in: transaction */
-/********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
UNIV_INTERN
void
trx_cleanup_at_db_startup(
/*======================*/
- trx_t* trx); /* in: transaction */
-/**************************************************************************
-Does the transaction commit for MySQL. */
+ trx_t* trx); /*!< in: transaction */
+/**********************************************************************//**
+Does the transaction commit for MySQL.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
trx_commit_for_mysql(
/*=================*/
- /* out: DB_SUCCESS or error number */
- trx_t* trx); /* in: trx handle */
-/**************************************************************************
-Does the transaction prepare for MySQL. */
+ trx_t* trx); /*!< in: trx handle */
+/**********************************************************************//**
+Does the transaction prepare for MySQL.
+@return 0 or error number */
UNIV_INTERN
ulint
trx_prepare_for_mysql(
/*==================*/
- /* out: 0 or error number */
- trx_t* trx); /* in: trx handle */
-/**************************************************************************
+ trx_t* trx); /*!< in: trx handle */
+/**********************************************************************//**
This function is used to find number of prepared transactions and
-their transaction objects for a recovery. */
+their transaction objects for a recovery.
+@return number of prepared transactions */
UNIV_INTERN
int
trx_recover_for_mysql(
/*==================*/
- /* out: number of prepared transactions */
- XID* xid_list, /* in/out: prepared transactions */
- ulint len); /* in: number of slots in xid_list */
-/***********************************************************************
+ XID* xid_list, /*!< in/out: prepared transactions */
+ ulint len); /*!< in: number of slots in xid_list */
+/*******************************************************************//**
This function is used to find one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return trx or NULL */
UNIV_INTERN
trx_t *
trx_get_trx_by_xid(
/*===============*/
- /* out: trx or NULL */
- XID* xid); /* in: X/Open XA transaction identification */
-/**************************************************************************
+ XID* xid); /*!< in: X/Open XA transaction identification */
+/**********************************************************************//**
If required, flushes the log to disk if we called trx_commit_for_mysql()
-with trx->flush_log_later == TRUE. */
+with trx->flush_log_later == TRUE.
+@return 0 or error number */
UNIV_INTERN
ulint
trx_commit_complete_for_mysql(
/*==========================*/
- /* out: 0 or error number */
- trx_t* trx); /* in: trx handle */
-/**************************************************************************
+ trx_t* trx); /*!< in: trx handle */
+/**********************************************************************//**
Marks the latest SQL statement ended. */
UNIV_INTERN
void
trx_mark_sql_stat_end(
/*==================*/
- trx_t* trx); /* in: trx handle */
-/************************************************************************
+ trx_t* trx); /*!< in: trx handle */
+/********************************************************************//**
Assigns a read view for a consistent read query. All the consistent reads
within the same transaction will get the same read view, which is created
-when this function is first called for a new started transaction. */
+when this function is first called for a new started transaction.
+@return consistent read view */
UNIV_INTERN
read_view_t*
trx_assign_read_view(
/*=================*/
- /* out: consistent read view */
- trx_t* trx); /* in: active transaction */
-/***************************************************************
+ trx_t* trx); /*!< in: active transaction */
+/***********************************************************//**
The transaction must be in the TRX_QUE_LOCK_WAIT state. Puts it to
the TRX_QUE_RUNNING state and releases query threads which were
waiting for a lock in the wait_thrs list. */
@@ -252,62 +254,62 @@ UNIV_INTERN
void
trx_end_lock_wait(
/*==============*/
- trx_t* trx); /* in: transaction */
-/********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/****************************************************************//**
Sends a signal to a trx object. */
UNIV_INTERN
void
trx_sig_send(
/*=========*/
- trx_t* trx, /* in: trx handle */
- ulint type, /* in: signal type */
- ulint sender, /* in: TRX_SIG_SELF or
+ trx_t* trx, /*!< in: trx handle */
+ ulint type, /*!< in: signal type */
+ ulint sender, /*!< in: TRX_SIG_SELF or
TRX_SIG_OTHER_SESS */
- que_thr_t* receiver_thr, /* in: query thread which wants the
+ que_thr_t* receiver_thr, /*!< in: query thread which wants the
reply, or NULL; if type is
TRX_SIG_END_WAIT, this must be NULL */
- trx_savept_t* savept, /* in: possible rollback savepoint, or
+ trx_savept_t* savept, /*!< in: possible rollback savepoint, or
NULL */
- que_thr_t** next_thr); /* in/out: next query thread to run;
+ que_thr_t** next_thr); /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread; if the parameter
is NULL, it is ignored */
-/********************************************************************
+/****************************************************************//**
Send the reply message when a signal in the queue of the trx has
been handled. */
UNIV_INTERN
void
trx_sig_reply(
/*==========*/
- trx_sig_t* sig, /* in: signal */
- que_thr_t** next_thr); /* in/out: next query thread to run;
+ trx_sig_t* sig, /*!< in: signal */
+ que_thr_t** next_thr); /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread */
-/********************************************************************
+/****************************************************************//**
Removes the signal object from a trx signal queue. */
UNIV_INTERN
void
trx_sig_remove(
/*===========*/
- trx_t* trx, /* in: trx handle */
- trx_sig_t* sig); /* in, own: signal */
-/********************************************************************
+ trx_t* trx, /*!< in: trx handle */
+ trx_sig_t* sig); /*!< in, own: signal */
+/****************************************************************//**
Starts handling of a trx signal. */
UNIV_INTERN
void
trx_sig_start_handle(
/*=================*/
- trx_t* trx, /* in: trx handle */
- que_thr_t** next_thr); /* in/out: next query thread to run;
+ trx_t* trx, /*!< in: trx handle */
+ que_thr_t** next_thr); /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread */
-/********************************************************************
+/****************************************************************//**
Ends signal handling. If the session is in the error state, and
trx->graph_before_signal_handling != NULL, returns control to the error
handling routine of the graph (currently only returns the control to the
@@ -316,25 +318,25 @@ UNIV_INTERN
void
trx_end_signal_handling(
/*====================*/
- trx_t* trx); /* in: trx */
-/*************************************************************************
-Creates a commit command node struct. */
+ trx_t* trx); /*!< in: trx */
+/*********************************************************************//**
+Creates a commit command node struct.
+@return own: commit node struct */
UNIV_INTERN
commit_node_t*
commit_node_create(
/*===============*/
- /* out, own: commit node struct */
- mem_heap_t* heap); /* in: mem heap where created */
-/***************************************************************
-Performs an execution step for a commit type node in a query graph. */
+ mem_heap_t* heap); /*!< in: mem heap where created */
+/***********************************************************//**
+Performs an execution step for a commit type node in a query graph.
+@return query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_commit_step(
/*============*/
- /* out: query thread to run next, or NULL */
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
-/**************************************************************************
+/**********************************************************************//**
Prints info about a transaction to the given file. The caller must own the
kernel mutex and must have called
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
@@ -343,9 +345,9 @@ UNIV_INTERN
void
trx_print(
/*======*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ulint max_query_len); /* in: max query length to print, or 0 to
+ FILE* f, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ ulint max_query_len); /*!< in: max query length to print, or 0 to
use the default max length */
/** Type of data dictionary operation */
@@ -358,100 +360,100 @@ enum trx_dict_op {
operation modes in crash recovery. */
TRX_DICT_OP_TABLE = 1,
/** The transaction is creating or dropping an index in an
- existing table. In crash recovery, the the data dictionary
+ existing table. In crash recovery, the data dictionary
must be locked, but the table must not be dropped. */
TRX_DICT_OP_INDEX = 2
};
-/**************************************************************************
-Determine if a transaction is a dictionary operation. */
+/**********************************************************************//**
+Determine if a transaction is a dictionary operation.
+@return dictionary operation mode */
UNIV_INLINE
enum trx_dict_op
trx_get_dict_operation(
/*===================*/
- /* out: dictionary operation mode */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
__attribute__((pure));
-/**************************************************************************
+/**********************************************************************//**
Flag a transaction a dictionary operation. */
UNIV_INLINE
void
trx_set_dict_operation(
/*===================*/
- trx_t* trx, /* in/out: transaction */
- enum trx_dict_op op); /* in: operation, not
+ trx_t* trx, /*!< in/out: transaction */
+ enum trx_dict_op op); /*!< in: operation, not
TRX_DICT_OP_NONE */
#ifndef UNIV_HOTBACKUP
-/**************************************************************************
-Determines if the currently running transaction has been interrupted. */
+/**********************************************************************//**
+Determines if the currently running transaction has been interrupted.
+@return TRUE if interrupted */
UNIV_INTERN
ibool
trx_is_interrupted(
/*===============*/
- /* out: TRUE if interrupted */
- trx_t* trx); /* in: transaction */
+ trx_t* trx); /*!< in: transaction */
#else /* !UNIV_HOTBACKUP */
#define trx_is_interrupted(trx) FALSE
#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
+/*******************************************************************//**
Calculates the "weight" of a transaction. The weight of one transaction
is estimated as the number of altered rows + the number of locked rows.
-*/
-
+@param t transaction
+@return transaction weight */
#define TRX_WEIGHT(t) \
ut_dulint_add((t)->undo_no, UT_LIST_GET_LEN((t)->trx_locks))
-/***********************************************************************
+/*******************************************************************//**
Compares the "weight" (or size) of two transactions. Transactions that
have edited non-transactional tables are considered heavier than ones
-that have not. */
+that have not.
+@return <0, 0 or >0; similar to strcmp(3) */
UNIV_INTERN
int
trx_weight_cmp(
/*===========*/
- /* out: <0, 0 or >0; similar to strcmp(3) */
- const trx_t* a, /* in: the first transaction to be compared */
- const trx_t* b); /* in: the second transaction to be compared */
+ const trx_t* a, /*!< in: the first transaction to be compared */
+ const trx_t* b); /*!< in: the second transaction to be compared */
-/***********************************************************************
-Retrieves transacion's id, represented as unsigned long long. */
+/*******************************************************************//**
+Retrieves transacion's id, represented as unsigned long long.
+@return transaction's id */
UNIV_INLINE
ullint
trx_get_id(
/*=======*/
- /* out: transaction's id */
- const trx_t* trx); /* in: transaction */
+ const trx_t* trx); /*!< in: transaction */
/* Maximum length of a string that can be returned by
trx_get_que_state_str(). */
#define TRX_QUE_STATE_STR_MAX_LEN 12 /* "ROLLING BACK" */
-/***********************************************************************
+/*******************************************************************//**
Retrieves transaction's que state in a human readable string. The string
-should not be free()'d or modified. */
+should not be free()'d or modified.
+@return string in the data segment */
UNIV_INLINE
const char*
trx_get_que_state_str(
/*==================*/
- /* out: string in the data segment */
- const trx_t* trx); /* in: transaction */
+ const trx_t* trx); /*!< in: transaction */
/* Signal to a transaction */
struct trx_sig_struct{
- unsigned type:3; /* signal type */
- unsigned sender:1; /* TRX_SIG_SELF or
+ unsigned type:3; /*!< signal type */
+ unsigned sender:1; /*!< TRX_SIG_SELF or
TRX_SIG_OTHER_SESS */
- que_thr_t* receiver; /* non-NULL if the sender of the signal
+ que_thr_t* receiver; /*!< non-NULL if the sender of the signal
wants reply after the operation induced
by the signal is completed */
- trx_savept_t savept; /* possible rollback savepoint */
+ trx_savept_t savept; /*!< possible rollback savepoint */
UT_LIST_NODE_T(trx_sig_t)
- signals; /* queue of pending signals to the
+ signals; /*!< queue of pending signals to the
transaction */
UT_LIST_NODE_T(trx_sig_t)
- reply_signals; /* list of signals for which the sender
+ reply_signals; /*!< list of signals for which the sender
transaction is waiting a reply */
};
@@ -465,17 +467,17 @@ struct trx_struct{
ulint magic_n;
/* All the next fields are protected by the kernel mutex, except the
undo logs which are protected by undo_mutex */
- const char* op_info; /* English text describing the
+ const char* op_info; /*!< English text describing the
current operation, or an empty
string */
- unsigned is_purge:1; /* 0=user transaction, 1=purge */
- unsigned is_recovered:1; /* 0=normal transaction,
+ unsigned is_purge:1; /*!< 0=user transaction, 1=purge */
+ unsigned is_recovered:1; /*!< 0=normal transaction,
1=recovered, must be rolled back */
- unsigned conc_state:2; /* state of the trx from the point
+ unsigned conc_state:2; /*!< state of the trx from the point
of view of concurrency control:
TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY,
... */
- unsigned que_state:2; /* valid when conc_state == TRX_ACTIVE:
+ unsigned que_state:2; /*!< valid when conc_state == TRX_ACTIVE:
TRX_QUE_RUNNING, TRX_QUE_LOCK_WAIT,
... */
unsigned isolation_level:2;/* TRX_ISO_REPEATABLE_READ, ... */
@@ -490,15 +492,17 @@ struct trx_struct{
for secondary indexes when we decide
if we can use the insert buffer for
them, we set this FALSE */
- unsigned support_xa:1; /* normally we do the XA two-phase
+ unsigned support_xa:1; /*!< normally we do the XA two-phase
commit steps, but by setting this to
FALSE, one can save CPU time and about
150 bytes in the undo log size as then
we skip XA steps */
- unsigned flush_log_later:1;/* when we commit the transaction
- in MySQL's binlog write, we will
- flush the log to disk later in
- a separate call */
+ unsigned flush_log_later:1;/* In 2PC, we hold the
+ prepare_commit mutex across
+ both phases. In that case, we
+ defer flush of the logs to disk
+ until after we release the
+ mutex. */
unsigned must_flush_log_later:1;/* this flag is set to TRUE in
trx_commit_off_kernel() if
flush_log_later was TRUE, and there
@@ -506,8 +510,8 @@ struct trx_struct{
in that case we must flush the log
in trx_commit_complete_for_mysql() */
unsigned dict_operation:2;/**< @see enum trx_dict_op */
- unsigned duplicates:2; /* TRX_DUP_IGNORE | TRX_DUP_REPLACE */
- unsigned active_trans:2; /* 1 - if a transaction in MySQL
+ unsigned duplicates:2; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
+ unsigned active_trans:2; /*!< 1 - if a transaction in MySQL
is active. 2 - if prepare_commit_mutex
was taken */
unsigned has_search_latch:1;
@@ -524,21 +528,21 @@ struct trx_struct{
/* 0, RW_S_LATCH, or RW_X_LATCH:
the latch mode trx currently holds
on dict_operation_lock */
- time_t start_time; /* time the trx object was created
+ time_t start_time; /*!< time the trx object was created
or the state last time became
TRX_ACTIVE */
- dulint id; /* transaction id */
- XID xid; /* X/Open XA transaction
+ trx_id_t id; /*!< transaction id */
+ XID xid; /*!< X/Open XA transaction
identification to identify a
transaction branch */
- dulint no; /* transaction serialization number ==
+ trx_id_t no; /*!< transaction serialization number ==
max trx id when the transaction is
moved to COMMITTED_IN_MEMORY state */
- ib_uint64_t commit_lsn; /* lsn at the time of the commit */
- dulint table_id; /* Table to drop iff dict_operation
+ ib_uint64_t commit_lsn; /*!< lsn at the time of the commit */
+ trx_id_t table_id; /*!< Table to drop iff dict_operation
is TRUE, or ut_dulint_zero. */
/*------------------------------*/
- void* mysql_thd; /* MySQL thread handle corresponding
+ void* mysql_thd; /*!< MySQL thread handle corresponding
to this trx, or NULL */
char** mysql_query_str;/* pointer to the field in mysqld_thd
which contains the pointer to the
@@ -597,48 +601,48 @@ struct trx_struct{
here is > 0, we decrement this by 1 */
/*------------------------------*/
UT_LIST_NODE_T(trx_t)
- trx_list; /* list of transactions */
+ trx_list; /*!< list of transactions */
UT_LIST_NODE_T(trx_t)
- mysql_trx_list; /* list of transactions created for
+ mysql_trx_list; /*!< list of transactions created for
MySQL */
/*------------------------------*/
- ulint error_state; /* 0 if no error, otherwise error
+ ulint error_state; /*!< 0 if no error, otherwise error
number; NOTE That ONLY the thread
doing the transaction is allowed to
set this field: this is NOT protected
by the kernel mutex */
- const dict_index_t*error_info; /* if the error number indicates a
+ const dict_index_t*error_info; /*!< if the error number indicates a
duplicate key error, a pointer to
the problematic index is stored here */
- ulint error_key_num; /* if the index creation fails to a
+ ulint error_key_num; /*!< if the index creation fails to a
duplicate key error, a mysql key
number of that index is stored here */
- sess_t* sess; /* session of the trx, NULL if none */
- que_t* graph; /* query currently run in the session,
+ sess_t* sess; /*!< session of the trx, NULL if none */
+ que_t* graph; /*!< query currently run in the session,
or NULL if none; NOTE that the query
belongs to the session, and it can
survive over a transaction commit, if
it is a stored procedure with a COMMIT
WORK statement, for instance */
- ulint n_active_thrs; /* number of active query threads */
+ ulint n_active_thrs; /*!< number of active query threads */
que_t* graph_before_signal_handling;
/* value of graph when signal handling
for this trx started: this is used to
return control to the original query
graph for error processing */
- trx_sig_t sig; /* one signal object can be allocated
+ trx_sig_t sig; /*!< one signal object can be allocated
in this space, avoiding mem_alloc */
UT_LIST_BASE_NODE_T(trx_sig_t)
- signals; /* queue of processed or pending
+ signals; /*!< queue of processed or pending
signals to the trx */
UT_LIST_BASE_NODE_T(trx_sig_t)
- reply_signals; /* list of signals sent by the query
+ reply_signals; /*!< list of signals sent by the query
threads of this trx for which a thread
is waiting for a reply; if this trx is
killed, the reply requests in the list
must be canceled */
/*------------------------------*/
- lock_t* wait_lock; /* if trx execution state is
+ lock_t* wait_lock; /*!< if trx execution state is
TRX_QUE_LOCK_WAIT, this points to
the lock request, otherwise this is
NULL */
@@ -648,21 +652,21 @@ struct trx_struct{
if another transaction chooses this
transaction as a victim in deadlock
resolution, it sets this to TRUE */
- time_t wait_started; /* lock wait started at this time */
+ time_t wait_started; /*!< lock wait started at this time */
UT_LIST_BASE_NODE_T(que_thr_t)
- wait_thrs; /* query threads belonging to this
+ wait_thrs; /*!< query threads belonging to this
trx that are in the QUE_THR_LOCK_WAIT
state */
- ulint deadlock_mark; /* a mark field used in deadlock
+ ulint deadlock_mark; /*!< a mark field used in deadlock
checking algorithm. This must be
in its own machine word, because
it can be changed by other
threads while holding kernel_mutex. */
/*------------------------------*/
- mem_heap_t* lock_heap; /* memory heap for the locks of the
+ mem_heap_t* lock_heap; /*!< memory heap for the locks of the
transaction */
UT_LIST_BASE_NODE_T(lock_t)
- trx_locks; /* locks reserved by the transaction */
+ trx_locks; /*!< locks reserved by the transaction */
/*------------------------------*/
mem_heap_t* global_read_view_heap;
/* memory heap for the global read
@@ -670,7 +674,7 @@ struct trx_struct{
read_view_t* global_read_view;
/* consistent read view associated
to a transaction or NULL */
- read_view_t* read_view; /* consistent read view used in the
+ read_view_t* read_view; /*!< consistent read view used in the
transaction or NULL, this read view
if defined can be normal read view
associated to a transaction (i.e.
@@ -678,16 +682,16 @@ struct trx_struct{
associated to a cursor */
/*------------------------------*/
UT_LIST_BASE_NODE_T(trx_named_savept_t)
- trx_savepoints; /* savepoints set with SAVEPOINT ...,
+ trx_savepoints; /*!< savepoints set with SAVEPOINT ...,
oldest first */
/*------------------------------*/
- mutex_t undo_mutex; /* mutex protecting the fields in this
+ mutex_t undo_mutex; /*!< mutex protecting the fields in this
section (down to undo_no_arr), EXCEPT
last_sql_stat_start, which can be
accessed only when we know that there
cannot be any activity in the undo
logs! */
- dulint undo_no; /* next undo log record number to
+ undo_no_t undo_no; /*!< next undo log record number to
assign; since the undo log is
private for a transaction, this
is a simple ascending sequence
@@ -699,22 +703,22 @@ struct trx_struct{
was started: in case of an error, trx
is rolled back down to this undo
number; see note at undo_mutex! */
- trx_rseg_t* rseg; /* rollback segment assigned to the
+ trx_rseg_t* rseg; /*!< rollback segment assigned to the
transaction, or NULL if not assigned
yet */
- trx_undo_t* insert_undo; /* pointer to the insert undo log, or
+ trx_undo_t* insert_undo; /*!< pointer to the insert undo log, or
NULL if no inserts performed yet */
- trx_undo_t* update_undo; /* pointer to the update undo log, or
+ trx_undo_t* update_undo; /*!< pointer to the update undo log, or
NULL if no update performed yet */
- dulint roll_limit; /* least undo number to undo during
+ undo_no_t roll_limit; /*!< least undo number to undo during
a rollback */
- ulint pages_undone; /* number of undo log pages undone
+ ulint pages_undone; /*!< number of undo log pages undone
since the last undo log truncation */
- trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
+ trx_undo_arr_t* undo_no_arr; /*!< array of undo numbers of undo log
records which are currently processed
by a rollback operation */
/*------------------------------*/
- ulint n_autoinc_rows; /* no. of AUTO-INC rows required for
+ ulint n_autoinc_rows; /*!< no. of AUTO-INC rows required for
an SQL statement. This is useful for
multi-row INSERTs */
ib_vector_t* autoinc_locks; /* AUTOINC locks held by this
@@ -723,8 +727,19 @@ struct trx_struct{
vector needs to be freed explicitly
when the trx_t instance is desrtoyed */
/*------------------------------*/
- char detailed_error[256]; /* detailed error message for last
+ char detailed_error[256]; /*!< detailed error message for last
error, or empty. */
+ /*------------------------------*/
+ ulint io_reads;
+ ib_uint64_t io_read;
+ ulint io_reads_wait_timer;
+ ib_uint64_t lock_que_wait_ustarted;
+ ulint lock_que_wait_timer;
+ ulint innodb_que_wait_timer;
+ ulint distinct_page_access;
+#define DPAH_SIZE 8192
+ byte* distinct_page_access_hash;
+ ibool take_stats;
};
#define TRX_MAX_N_THREADS 32 /* maximum number of
@@ -800,19 +815,26 @@ Multiple flags can be combined with bitwise OR. */
#define TRX_SIG_OTHER_SESS 1 /* sent by another session (which
must hold rights to this) */
-/* Commit command node in a query graph */
+/** Commit node states */
+enum commit_node_state {
+ COMMIT_NODE_SEND = 1, /*!< about to send a commit signal to
+ the transaction */
+ COMMIT_NODE_WAIT /*!< commit signal sent to the transaction,
+ waiting for completion */
+};
+
+/** Commit command node in a query graph */
struct commit_node_struct{
- que_common_t common; /* node type: QUE_NODE_COMMIT */
- ulint state; /* node execution state */
+ que_common_t common; /*!< node type: QUE_NODE_COMMIT */
+ enum commit_node_state
+ state; /*!< node execution state */
};
-/* Commit node states */
-#define COMMIT_NODE_SEND 1
-#define COMMIT_NODE_WAIT 2
#ifndef UNIV_NONINL
#include "trx0trx.ic"
#endif
+#endif /* !UNIV_HOTBACKUP */
#endif
diff --git a/storage/xtradb/include/trx0trx.ic b/storage/xtradb/include/trx0trx.ic
index 51212539c09..7332eeece85 100644
--- a/storage/xtradb/include/trx0trx.ic
+++ b/storage/xtradb/include/trx0trx.ic
@@ -16,19 +16,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0trx.ic
The transaction
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-/*****************************************************************
+/*************************************************************//**
Starts the transaction if it is not yet started. */
UNIV_INLINE
void
trx_start_if_not_started(
/*=====================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
ut_ad(trx->conc_state != TRX_COMMITTED_IN_MEMORY);
@@ -38,14 +39,14 @@ trx_start_if_not_started(
}
}
-/*****************************************************************
+/*************************************************************//**
Starts the transaction if it is not yet started. Assumes we have reserved
the kernel mutex! */
UNIV_INLINE
void
trx_start_if_not_started_low(
/*=========================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
ut_ad(trx->conc_state != TRX_COMMITTED_IN_MEMORY);
@@ -55,39 +56,39 @@ trx_start_if_not_started_low(
}
}
-/********************************************************************
-Retrieves the error_info field from a trx. */
+/****************************************************************//**
+Retrieves the error_info field from a trx.
+@return the error info */
UNIV_INLINE
const dict_index_t*
trx_get_error_info(
/*===============*/
- /* out: the error info */
- const trx_t* trx) /* in: trx object */
+ const trx_t* trx) /*!< in: trx object */
{
return(trx->error_info);
}
-/***********************************************************************
-Retrieves transacion's id, represented as unsigned long long. */
+/*******************************************************************//**
+Retrieves transacion's id, represented as unsigned long long.
+@return transaction's id */
UNIV_INLINE
ullint
trx_get_id(
/*=======*/
- /* out: transaction's id */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
{
return((ullint)ut_conv_dulint_to_longlong(trx->id));
}
-/***********************************************************************
+/*******************************************************************//**
Retrieves transaction's que state in a human readable string. The string
-should not be free()'d or modified. */
+should not be free()'d or modified.
+@return string in the data segment */
UNIV_INLINE
const char*
trx_get_que_state_str(
/*==================*/
- /* out: string in the data segment */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
{
/* be sure to adjust TRX_QUE_STATE_STR_MAX_LEN if you change this */
switch (trx->que_state) {
@@ -104,14 +105,14 @@ trx_get_que_state_str(
}
}
-/**************************************************************************
-Determine if a transaction is a dictionary operation. */
+/**********************************************************************//**
+Determine if a transaction is a dictionary operation.
+@return dictionary operation mode */
UNIV_INLINE
enum trx_dict_op
trx_get_dict_operation(
/*===================*/
- /* out: dictionary operation mode */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
{
enum trx_dict_op op = (enum trx_dict_op) trx->dict_operation;
@@ -126,14 +127,14 @@ trx_get_dict_operation(
#endif /* UNIV_DEBUG */
return((enum trx_dict_op) UNIV_EXPECT(op, TRX_DICT_OP_NONE));
}
-/**************************************************************************
+/**********************************************************************//**
Flag a transaction a dictionary operation. */
UNIV_INLINE
void
trx_set_dict_operation(
/*===================*/
- trx_t* trx, /* in/out: transaction */
- enum trx_dict_op op) /* in: operation, not
+ trx_t* trx, /*!< in/out: transaction */
+ enum trx_dict_op op) /*!< in: operation, not
TRX_DICT_OP_NONE */
{
#ifdef UNIV_DEBUG
diff --git a/storage/xtradb/include/trx0types.h b/storage/xtradb/include/trx0types.h
index 896f4e8c0a2..24cf57d53d5 100644
--- a/storage/xtradb/include/trx0types.h
+++ b/storage/xtradb/include/trx0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0types.h
Transaction system global type definitions
Created 3/26/1996 Heikki Tuuri
@@ -27,52 +28,81 @@ Created 3/26/1996 Heikki Tuuri
#include "ut0byte.h"
-/* prepare trx_t::id for being printed via printf(3) */
+/** prepare trx_t::id for being printed via printf(3) */
#define TRX_ID_PREP_PRINTF(id) (ullint) ut_conv_dulint_to_longlong(id)
-/* printf(3) format used for printing TRX_ID_PRINTF_PREP() */
+/** printf(3) format used for printing TRX_ID_PRINTF_PREP() */
#define TRX_ID_FMT "%llX"
-/* maximum length that a formatted trx_t::id could take, not including
-the terminating '\0'. */
+/** maximum length that a formatted trx_t::id could take, not including
+the terminating NUL character. */
#define TRX_ID_MAX_LEN 17
-/* Memory objects */
+/** Memory objects */
+/* @{ */
+/** Transaction */
typedef struct trx_struct trx_t;
+/** Transaction system */
typedef struct trx_sys_struct trx_sys_t;
+/** Doublewrite information */
typedef struct trx_doublewrite_struct trx_doublewrite_t;
+/** Signal */
typedef struct trx_sig_struct trx_sig_t;
+/** Rollback segment */
typedef struct trx_rseg_struct trx_rseg_t;
+/** Transaction undo log */
typedef struct trx_undo_struct trx_undo_t;
+/** Array of undo numbers of undo records being rolled back or purged */
typedef struct trx_undo_arr_struct trx_undo_arr_t;
+/** A cell of trx_undo_arr_t */
typedef struct trx_undo_inf_struct trx_undo_inf_t;
+/** The control structure used in the purge operation */
typedef struct trx_purge_struct trx_purge_t;
+/** Rollback command node in a query graph */
typedef struct roll_node_struct roll_node_t;
+/** Commit command node in a query graph */
typedef struct commit_node_struct commit_node_t;
+/** SAVEPOINT command node in a query graph */
typedef struct trx_named_savept_struct trx_named_savept_t;
+/* @} */
-/* Rollback contexts */
+/** Rollback contexts */
enum trx_rb_ctx {
- RB_NONE = 0, /* no rollback */
- RB_NORMAL, /* normal rollback */
- RB_RECOVERY, /* rolling back an incomplete transaction,
+ RB_NONE = 0, /*!< no rollback */
+ RB_NORMAL, /*!< normal rollback */
+ RB_RECOVERY /*!< rolling back an incomplete transaction,
in crash recovery */
};
-/* Transaction savepoint */
+/** Transaction identifier (DB_TRX_ID, DATA_TRX_ID) */
+typedef dulint trx_id_t;
+/** Rollback pointer (DB_ROLL_PTR, DATA_ROLL_PTR) */
+typedef dulint roll_ptr_t;
+/** Undo number */
+typedef dulint undo_no_t;
+
+/** Transaction savepoint */
typedef struct trx_savept_struct trx_savept_t;
+/** Transaction savepoint */
struct trx_savept_struct{
- dulint least_undo_no; /* least undo number to undo */
+ undo_no_t least_undo_no; /*!< least undo number to undo */
};
-/* File objects */
+/** File objects */
+/* @{ */
+/** Transaction system header */
typedef byte trx_sysf_t;
+/** Rollback segment header */
typedef byte trx_rsegf_t;
+/** Undo segment header */
typedef byte trx_usegf_t;
+/** Undo log header */
typedef byte trx_ulogf_t;
+/** Undo log page header */
typedef byte trx_upagef_t;
-/* Undo log record */
+/** Undo log record */
typedef byte trx_undo_rec_t;
+/* @} */
#endif
diff --git a/storage/xtradb/include/trx0undo.h b/storage/xtradb/include/trx0undo.h
index 7f7408931da..a084f2394b5 100644
--- a/storage/xtradb/include/trx0undo.h
+++ b/storage/xtradb/include/trx0undo.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0undo.h
Transaction undo log
Created 3/26/1996 Heikki Tuuri
@@ -32,37 +33,40 @@ Created 3/26/1996 Heikki Tuuri
#include "page0types.h"
#include "trx0xa.h"
-/***************************************************************************
-Builds a roll pointer dulint. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Builds a roll pointer.
+@return roll pointer */
UNIV_INLINE
-dulint
+roll_ptr_t
trx_undo_build_roll_ptr(
/*====================*/
- /* out: roll pointer */
- ibool is_insert, /* in: TRUE if insert undo log */
- ulint rseg_id, /* in: rollback segment id */
- ulint page_no, /* in: page number */
- ulint offset); /* in: offset of the undo entry within page */
-/***************************************************************************
-Decodes a roll pointer dulint. */
+ ibool is_insert, /*!< in: TRUE if insert undo log */
+ ulint rseg_id, /*!< in: rollback segment id */
+ ulint page_no, /*!< in: page number */
+ ulint offset); /*!< in: offset of the undo entry within page */
+/***********************************************************************//**
+Decodes a roll pointer. */
UNIV_INLINE
void
trx_undo_decode_roll_ptr(
/*=====================*/
- dulint roll_ptr, /* in: roll pointer */
- ibool* is_insert, /* out: TRUE if insert undo log */
- ulint* rseg_id, /* out: rollback segment id */
- ulint* page_no, /* out: page number */
- ulint* offset); /* out: offset of the undo entry within page */
-/***************************************************************************
-Returns TRUE if the roll pointer is of the insert type. */
+ roll_ptr_t roll_ptr, /*!< in: roll pointer */
+ ibool* is_insert, /*!< out: TRUE if insert undo log */
+ ulint* rseg_id, /*!< out: rollback segment id */
+ ulint* page_no, /*!< out: page number */
+ ulint* offset); /*!< out: offset of the undo
+ entry within page */
+/***********************************************************************//**
+Returns TRUE if the roll pointer is of the insert type.
+@return TRUE if insert undo log */
UNIV_INLINE
ibool
trx_undo_roll_ptr_is_insert(
/*========================*/
- /* out: TRUE if insert undo log */
- dulint roll_ptr); /* in: roll pointer */
-/*********************************************************************
+ roll_ptr_t roll_ptr); /*!< in: roll pointer */
+#endif /* !UNIV_HOTBACKUP */
+/*****************************************************************//**
Writes a roll ptr to an index page. In case that the size changes in
some future version, this function should be used instead of
mach_write_... */
@@ -70,214 +74,210 @@ UNIV_INLINE
void
trx_write_roll_ptr(
/*===============*/
- byte* ptr, /* in: pointer to memory where written */
- dulint roll_ptr); /* in: roll ptr */
-/*********************************************************************
+ byte* ptr, /*!< in: pointer to memory where
+ written */
+ roll_ptr_t roll_ptr); /*!< in: roll ptr */
+/*****************************************************************//**
Reads a roll ptr from an index page. In case that the roll ptr size
changes in some future version, this function should be used instead of
-mach_read_... */
+mach_read_...
+@return roll ptr */
UNIV_INLINE
-dulint
+roll_ptr_t
trx_read_roll_ptr(
/*==============*/
- /* out: roll ptr */
- const byte* ptr); /* in: pointer to memory from where to read */
-/**********************************************************************
-Gets an undo log page and x-latches it. */
+ const byte* ptr); /*!< in: pointer to memory from where to read */
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
+Gets an undo log page and x-latches it.
+@return pointer to page x-latched */
UNIV_INLINE
page_t*
trx_undo_page_get(
/*==============*/
- /* out: pointer to page x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
-Gets an undo log page and s-latches it. */
+ ulint page_no, /*!< in: page number */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
+Gets an undo log page and s-latches it.
+@return pointer to page s-latched */
UNIV_INLINE
page_t*
trx_undo_page_get_s_latched(
/*========================*/
- /* out: pointer to page s-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
+ ulint page_no, /*!< in: page number */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
Returns the previous undo record on the page in the specified log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_prev_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- trx_undo_rec_t* rec, /* in: undo log record */
- ulint page_no,/* in: undo log header page number */
- ulint offset);/* in: undo log header offset on page */
-/**********************************************************************
+ trx_undo_rec_t* rec, /*!< in: undo log record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset);/*!< in: undo log header offset on page */
+/******************************************************************//**
Returns the next undo log record on the page in the specified log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_next_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- trx_undo_rec_t* rec, /* in: undo log record */
- ulint page_no,/* in: undo log header page number */
- ulint offset);/* in: undo log header offset on page */
-/**********************************************************************
+ trx_undo_rec_t* rec, /*!< in: undo log record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset);/*!< in: undo log header offset on page */
+/******************************************************************//**
Returns the last undo record on the page in the specified undo log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_last_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset); /* in: undo log header offset on page */
-/**********************************************************************
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset); /*!< in: undo log header offset on page */
+/******************************************************************//**
Returns the first undo record on the page in the specified undo log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_first_rec(
/*========================*/
- /* out: pointer to record, NULL if none */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset);/* in: undo log header offset on page */
-/***************************************************************************
-Gets the previous record in an undo log. */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset);/*!< in: undo log header offset on page */
+/***********************************************************************//**
+Gets the previous record in an undo log.
+@return undo log record, the page s-latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_prev_rec(
/*==================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************************
-Gets the next record in an undo log. */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************************//**
+Gets the next record in an undo log.
+@return undo log record, the page s-latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_next_rec(
/*==================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************************
-Gets the first record in an undo log. */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************************//**
+Gets the first record in an undo log.
+@return undo log record, the page latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_first_rec(
/*===================*/
- /* out: undo log record, the page latched, NULL if
- none */
- ulint space, /* in: undo log header space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: undo log header space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- ulint mode, /* in: latching mode: RW_S_LATCH or RW_X_LATCH */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
-Tries to add a page to the undo log segment where the undo log is placed. */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ ulint mode, /*!< in: latching mode: RW_S_LATCH or RW_X_LATCH */
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
+Tries to add a page to the undo log segment where the undo log is placed.
+@return page number if success, else FIL_NULL */
UNIV_INTERN
ulint
trx_undo_add_page(
/*==============*/
- /* out: page number if success, else
- FIL_NULL */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory object */
- mtr_t* mtr); /* in: mtr which does not have a latch to any
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory object */
+ mtr_t* mtr); /*!< in: mtr which does not have a latch to any
undo log page; the caller must have reserved
the rollback segment mutex */
-/***************************************************************************
+/***********************************************************************//**
Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
trx_undo_truncate_end(
/*==================*/
- trx_t* trx, /* in: transaction whose undo log it is */
- trx_undo_t* undo, /* in: undo log */
- dulint limit); /* in: all undo records with undo number
+ trx_t* trx, /*!< in: transaction whose undo log it is */
+ trx_undo_t* undo, /*!< in: undo log */
+ undo_no_t limit); /*!< in: all undo records with undo number
>= this value should be truncated */
-/***************************************************************************
+/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
operation. */
UNIV_INTERN
void
trx_undo_truncate_start(
/*====================*/
- trx_rseg_t* rseg, /* in: rollback segment */
- ulint space, /* in: space id of the log */
- ulint hdr_page_no, /* in: header page number */
- ulint hdr_offset, /* in: header offset on the page */
- dulint limit); /* in: all undo pages with undo numbers <
- this value should be truncated; NOTE that
- the function only frees whole pages; the
- header page is not freed, but emptied, if
- all the records there are < limit */
-/************************************************************************
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ ulint space, /*!< in: space id of the log */
+ ulint hdr_page_no, /*!< in: header page number */
+ ulint hdr_offset, /*!< in: header offset on the page */
+ undo_no_t limit); /*!< in: all undo pages with
+ undo numbers < this value
+ should be truncated; NOTE that
+ the function only frees whole
+ pages; the header page is not
+ freed, but emptied, if all the
+ records there are < limit */
+/********************************************************************//**
Initializes the undo log lists for a rollback segment memory copy.
This function is only called when the database is started or a new
-rollback segment created. */
+rollback segment created.
+@return the combined size of undo log segments in pages */
UNIV_INTERN
ulint
trx_undo_lists_init(
/*================*/
- /* out: the combined size of undo log segments
- in pages */
- trx_rseg_t* rseg); /* in: rollback segment memory object */
-/**************************************************************************
+ trx_rseg_t* rseg); /*!< in: rollback segment memory object */
+/**********************************************************************//**
Assigns an undo log for a transaction. A new undo log is created or a cached
-undo log reused. */
+undo log reused.
+@return DB_SUCCESS if undo log assign successful, possible error codes
+are: DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE
+DB_OUT_OF_MEMORY */
UNIV_INTERN
ulint
trx_undo_assign_undo(
/*=================*/
- /* out: DB_SUCCESS if undo log assign
- successful, possible error codes are:
- DB_TOO_MANY_CONCURRENT_TRXS
- DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/
- trx_t* trx, /* in: transaction */
- ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
-/**********************************************************************
-Sets the state of the undo log segment at a transaction finish. */
+ trx_t* trx, /*!< in: transaction */
+ ulint type); /*!< in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
+/******************************************************************//**
+Sets the state of the undo log segment at a transaction finish.
+@return undo log segment header page, x-latched */
UNIV_INTERN
page_t*
trx_undo_set_state_at_finish(
/*=========================*/
- /* out: undo log segment header page,
- x-latched */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
-Sets the state of the undo log segment at a transaction prepare. */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
+Sets the state of the undo log segment at a transaction prepare.
+@return undo log segment header page, x-latched */
UNIV_INTERN
page_t*
trx_undo_set_state_at_prepare(
/*==========================*/
- /* out: undo log segment header page,
- x-latched */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- mtr_t* mtr); /* in: mtr */
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ mtr_t* mtr); /*!< in: mtr */
-/**************************************************************************
+/**********************************************************************//**
Adds the update undo log header as the first in the history list, and
frees the memory object, or puts it to the list of cached update undo log
segments. */
@@ -285,11 +285,11 @@ UNIV_INTERN
void
trx_undo_update_cleanup(
/*====================*/
- trx_t* trx, /* in: trx owning the update undo log */
- page_t* undo_page, /* in: update undo log header page,
+ trx_t* trx, /*!< in: trx owning the update undo log */
+ page_t* undo_page, /*!< in: update undo log header page,
x-latched */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
Frees or caches an insert undo log after a transaction commit or rollback.
Knowledge of inserts is not needed after a commit or rollback, therefore
the data can be discarded. */
@@ -297,41 +297,49 @@ UNIV_INTERN
void
trx_undo_insert_cleanup(
/*====================*/
- trx_t* trx); /* in: transaction handle */
-/***************************************************************
-Parses the redo log entry of an undo log page initialization. */
+ trx_t* trx); /*!< in: transaction handle */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
+Parses the redo log entry of an undo log page initialization.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_page_init(
/*=====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses the redo log entry of an undo log page header create or reuse. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses the redo log entry of an undo log page header create or reuse.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_page_header(
/*=======================*/
- /* out: end of log record or NULL */
- ulint type, /* in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses the redo log entry of an undo log page header discard. */
+ ulint type, /*!< in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses the redo log entry of an undo log page header discard.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_discard_latest(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/************************************************************************
+Frees an undo log memory copy. */
+UNIV_INTERN
+void
+trx_undo_mem_free(
+/*==============*/
+ trx_undo_t* undo); /* in: the undo object to be freed */
/* Types of an undo log segment */
#define TRX_UNDO_INSERT 1 /* contains undo entries for inserts */
@@ -350,18 +358,19 @@ trx_undo_parse_discard_latest(
#define TRX_UNDO_PREPARED 5 /* contains an undo log of an
prepared transaction */
-/* Transaction undo log memory object; this is protected by the undo_mutex
+#ifndef UNIV_HOTBACKUP
+/** Transaction undo log memory object; this is protected by the undo_mutex
in the corresponding transaction object */
struct trx_undo_struct{
/*-----------------------------*/
- ulint id; /* undo log slot number within the
+ ulint id; /*!< undo log slot number within the
rollback segment */
- ulint type; /* TRX_UNDO_INSERT or
+ ulint type; /*!< TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- ulint state; /* state of the corresponding undo log
+ ulint state; /*!< state of the corresponding undo log
segment */
- ibool del_marks; /* relevant only in an update undo log:
+ ibool del_marks; /*!< relevant only in an update undo log:
this is TRUE if the transaction may
have delete marked records, because of
a delete of a row or an update of an
@@ -369,67 +378,72 @@ struct trx_undo_struct{
necessary; also TRUE if the transaction
has updated an externally stored
field */
- dulint trx_id; /* id of the trx assigned to the undo
+ trx_id_t trx_id; /*!< id of the trx assigned to the undo
log */
- XID xid; /* X/Open XA transaction
+ XID xid; /*!< X/Open XA transaction
identification */
- ibool dict_operation; /* TRUE if a dict operation trx */
- dulint table_id; /* if a dict operation, then the table
+ ibool dict_operation; /*!< TRUE if a dict operation trx */
+ dulint table_id; /*!< if a dict operation, then the table
id */
- trx_rseg_t* rseg; /* rseg where the undo log belongs */
+ trx_rseg_t* rseg; /*!< rseg where the undo log belongs */
/*-----------------------------*/
- ulint space; /* space id where the undo log
+ ulint space; /*!< space id where the undo log
placed */
- ulint zip_size; /* in: compressed page size of space
+ ulint zip_size; /*!< compressed page size of space
in bytes, or 0 for uncompressed */
- ulint hdr_page_no; /* page number of the header page in
+ ulint hdr_page_no; /*!< page number of the header page in
the undo log */
- ulint hdr_offset; /* header offset of the undo log on the
+ ulint hdr_offset; /*!< header offset of the undo log on the
page */
- ulint last_page_no; /* page number of the last page in the
+ ulint last_page_no; /*!< page number of the last page in the
undo log; this may differ from
top_page_no during a rollback */
- ulint size; /* current size in pages */
+ ulint size; /*!< current size in pages */
/*-----------------------------*/
- ulint empty; /* TRUE if the stack of undo log
+ ulint empty; /*!< TRUE if the stack of undo log
records is currently empty */
- ulint top_page_no; /* page number where the latest undo
+ ulint top_page_no; /*!< page number where the latest undo
log record was catenated; during
rollback the page from which the latest
undo record was chosen */
- ulint top_offset; /* offset of the latest undo record,
+ ulint top_offset; /*!< offset of the latest undo record,
i.e., the topmost element in the undo
log if we think of it as a stack */
- dulint top_undo_no; /* undo number of the latest record */
- buf_block_t* guess_block; /* guess for the buffer block where
+ undo_no_t top_undo_no; /*!< undo number of the latest record */
+ buf_block_t* guess_block; /*!< guess for the buffer block where
the top page might reside */
/*-----------------------------*/
UT_LIST_NODE_T(trx_undo_t) undo_list;
- /* undo log objects in the rollback
+ /*!< undo log objects in the rollback
segment are chained into lists */
};
+#endif /* !UNIV_HOTBACKUP */
-/* The offset of the undo log page header on pages of the undo log */
+/** The offset of the undo log page header on pages of the undo log */
#define TRX_UNDO_PAGE_HDR FSEG_PAGE_DATA
/*-------------------------------------------------------------*/
-/* Transaction undo log page header offsets */
-#define TRX_UNDO_PAGE_TYPE 0 /* TRX_UNDO_INSERT or
+/** Transaction undo log page header offsets */
+/* @{ */
+#define TRX_UNDO_PAGE_TYPE 0 /*!< TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
-#define TRX_UNDO_PAGE_START 2 /* Byte offset where the undo log
+#define TRX_UNDO_PAGE_START 2 /*!< Byte offset where the undo log
records for the LATEST transaction
start on this page (remember that
in an update undo log, the first page
can contain several undo logs) */
-#define TRX_UNDO_PAGE_FREE 4 /* On each page of the undo log this
+#define TRX_UNDO_PAGE_FREE 4 /*!< On each page of the undo log this
field contains the byte offset of the
first free byte on the page */
-#define TRX_UNDO_PAGE_NODE 6 /* The file list node in the chain
+#define TRX_UNDO_PAGE_NODE 6 /*!< The file list node in the chain
of undo log pages */
/*-------------------------------------------------------------*/
#define TRX_UNDO_PAGE_HDR_SIZE (6 + FLST_NODE_SIZE)
+ /*!< Size of the transaction undo
+ log page header, in bytes */
+/* @} */
-/* An update undo segment with just one page can be reused if it has
-< this number bytes used; we must leave space at least for one new undo
+/** An update undo segment with just one page can be reused if it has
+at most this many bytes used; we must leave space at least for one new undo
log header on the page */
#define TRX_UNDO_PAGE_REUSE_LIMIT (3 * UNIV_PAGE_SIZE / 4)
@@ -443,62 +457,67 @@ allowed to have zero undo records, but if the segment extends to several
pages, then all the rest of the pages must contain at least one undo log
record. */
-/* The offset of the undo log segment header on the first page of the undo
+/** The offset of the undo log segment header on the first page of the undo
log segment */
#define TRX_UNDO_SEG_HDR (TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE)
+/** Undo log segment header */
+/* @{ */
/*-------------------------------------------------------------*/
-#define TRX_UNDO_STATE 0 /* TRX_UNDO_ACTIVE, ... */
-#define TRX_UNDO_LAST_LOG 2 /* Offset of the last undo log header
+#define TRX_UNDO_STATE 0 /*!< TRX_UNDO_ACTIVE, ... */
+#define TRX_UNDO_LAST_LOG 2 /*!< Offset of the last undo log header
on the segment header page, 0 if
none */
-#define TRX_UNDO_FSEG_HEADER 4 /* Header for the file segment which
+#define TRX_UNDO_FSEG_HEADER 4 /*!< Header for the file segment which
the undo log segment occupies */
#define TRX_UNDO_PAGE_LIST (4 + FSEG_HEADER_SIZE)
- /* Base node for the list of pages in
+ /*!< Base node for the list of pages in
the undo log segment; defined only on
the undo log segment's first page */
/*-------------------------------------------------------------*/
-/* Size of the undo log segment header */
+/** Size of the undo log segment header */
#define TRX_UNDO_SEG_HDR_SIZE (4 + FSEG_HEADER_SIZE + FLST_BASE_NODE_SIZE)
+/* @} */
-/* The undo log header. There can be several undo log headers on the first
+/** The undo log header. There can be several undo log headers on the first
page of an update undo log segment. */
+/* @{ */
/*-------------------------------------------------------------*/
-#define TRX_UNDO_TRX_ID 0 /* Transaction id */
-#define TRX_UNDO_TRX_NO 8 /* Transaction number of the
+#define TRX_UNDO_TRX_ID 0 /*!< Transaction id */
+#define TRX_UNDO_TRX_NO 8 /*!< Transaction number of the
transaction; defined only if the log
is in a history list */
-#define TRX_UNDO_DEL_MARKS 16 /* Defined only in an update undo
+#define TRX_UNDO_DEL_MARKS 16 /*!< Defined only in an update undo
log: TRUE if the transaction may have
done delete markings of records, and
thus purge is necessary */
-#define TRX_UNDO_LOG_START 18 /* Offset of the first undo log record
+#define TRX_UNDO_LOG_START 18 /*!< Offset of the first undo log record
of this log on the header page; purge
may remove undo log record from the
log start, and therefore this is not
necessarily the same as this log
header end offset */
-#define TRX_UNDO_XID_EXISTS 20 /* TRUE if undo log header includes
+#define TRX_UNDO_XID_EXISTS 20 /*!< TRUE if undo log header includes
X/Open XA transaction identification
XID */
-#define TRX_UNDO_DICT_TRANS 21 /* TRUE if the transaction is a table
+#define TRX_UNDO_DICT_TRANS 21 /*!< TRUE if the transaction is a table
create, index create, or drop
transaction: in recovery
the transaction cannot be rolled back
in the usual way: a 'rollback' rather
means dropping the created or dropped
table, if it still exists */
-#define TRX_UNDO_TABLE_ID 22 /* Id of the table if the preceding
+#define TRX_UNDO_TABLE_ID 22 /*!< Id of the table if the preceding
field is TRUE */
-#define TRX_UNDO_NEXT_LOG 30 /* Offset of the next undo log header
+#define TRX_UNDO_NEXT_LOG 30 /*!< Offset of the next undo log header
on this page, 0 if none */
-#define TRX_UNDO_PREV_LOG 32 /* Offset of the previous undo log
+#define TRX_UNDO_PREV_LOG 32 /*!< Offset of the previous undo log
header on this page, 0 if none */
-#define TRX_UNDO_HISTORY_NODE 34 /* If the log is put to the history
+#define TRX_UNDO_HISTORY_NODE 34 /*!< If the log is put to the history
list, the file list node is here */
/*-------------------------------------------------------------*/
+/** Size of the undo log header without XID information */
#define TRX_UNDO_LOG_OLD_HDR_SIZE (34 + FLST_NODE_SIZE)
/* Note: the writing of the undo log old header is coded by a log record
@@ -509,15 +528,21 @@ is not needed by the user. The XID wastes about 150 bytes of space in every
undo log. In the history list we may have millions of undo logs, which means
quite a large overhead. */
-/* X/Open XA Transaction Identification (XID) */
-
+/** X/Open XA Transaction Identification (XID) */
+/* @{ */
+/** xid_t::formatID */
#define TRX_UNDO_XA_FORMAT (TRX_UNDO_LOG_OLD_HDR_SIZE)
+/** xid_t::gtrid_length */
#define TRX_UNDO_XA_TRID_LEN (TRX_UNDO_XA_FORMAT + 4)
+/** xid_t::bqual_length */
#define TRX_UNDO_XA_BQUAL_LEN (TRX_UNDO_XA_TRID_LEN + 4)
+/** Distributed transaction identifier data */
#define TRX_UNDO_XA_XID (TRX_UNDO_XA_BQUAL_LEN + 4)
/*--------------------------------------------------------------*/
#define TRX_UNDO_LOG_XA_HDR_SIZE (TRX_UNDO_XA_XID + XIDDATASIZE)
- /* Total size of the header with the XA XID */
+ /*!< Total size of the undo log header
+ with the XA XID */
+/* @} */
#ifndef UNIV_NONINL
#include "trx0undo.ic"
diff --git a/storage/xtradb/include/trx0undo.ic b/storage/xtradb/include/trx0undo.ic
index 0bd8b79414b..2d289b34ef1 100644
--- a/storage/xtradb/include/trx0undo.ic
+++ b/storage/xtradb/include/trx0undo.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0undo.ic
Transaction undo log
Created 3/26/1996 Heikki Tuuri
@@ -25,17 +26,18 @@ Created 3/26/1996 Heikki Tuuri
#include "data0type.h"
#include "page0page.h"
-/***************************************************************************
-Builds a roll pointer dulint. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Builds a roll pointer.
+@return roll pointer */
UNIV_INLINE
-dulint
+roll_ptr_t
trx_undo_build_roll_ptr(
/*====================*/
- /* out: roll pointer */
- ibool is_insert, /* in: TRUE if insert undo log */
- ulint rseg_id, /* in: rollback segment id */
- ulint page_no, /* in: page number */
- ulint offset) /* in: offset of the undo entry within page */
+ ibool is_insert, /*!< in: TRUE if insert undo log */
+ ulint rseg_id, /*!< in: rollback segment id */
+ ulint page_no, /*!< in: page number */
+ ulint offset) /*!< in: offset of the undo entry within page */
{
#if DATA_ROLL_PTR_LEN != 7
# error "DATA_ROLL_PTR_LEN != 7"
@@ -49,17 +51,18 @@ trx_undo_build_roll_ptr(
+ offset));
}
-/***************************************************************************
-Decodes a roll pointer dulint. */
+/***********************************************************************//**
+Decodes a roll pointer. */
UNIV_INLINE
void
trx_undo_decode_roll_ptr(
/*=====================*/
- dulint roll_ptr, /* in: roll pointer */
- ibool* is_insert, /* out: TRUE if insert undo log */
- ulint* rseg_id, /* out: rollback segment id */
- ulint* page_no, /* out: page number */
- ulint* offset) /* out: offset of the undo entry within page */
+ roll_ptr_t roll_ptr, /*!< in: roll pointer */
+ ibool* is_insert, /*!< out: TRUE if insert undo log */
+ ulint* rseg_id, /*!< out: rollback segment id */
+ ulint* page_no, /*!< out: page number */
+ ulint* offset) /*!< out: offset of the undo
+ entry within page */
{
ulint low;
ulint high;
@@ -81,14 +84,14 @@ trx_undo_decode_roll_ptr(
+ (low / 256) / 256;
}
-/***************************************************************************
-Returns TRUE if the roll pointer is of the insert type. */
+/***********************************************************************//**
+Returns TRUE if the roll pointer is of the insert type.
+@return TRUE if insert undo log */
UNIV_INLINE
ibool
trx_undo_roll_ptr_is_insert(
/*========================*/
- /* out: TRUE if insert undo log */
- dulint roll_ptr) /* in: roll pointer */
+ roll_ptr_t roll_ptr) /*!< in: roll pointer */
{
ulint high;
#if DATA_ROLL_PTR_LEN != 7
@@ -101,8 +104,9 @@ trx_undo_roll_ptr_is_insert(
return(high / (256 * 256 * 128));
}
+#endif /* !UNIV_HOTBACKUP */
-/*********************************************************************
+/*****************************************************************//**
Writes a roll ptr to an index page. In case that the size changes in
some future version, this function should be used instead of
mach_write_... */
@@ -110,8 +114,9 @@ UNIV_INLINE
void
trx_write_roll_ptr(
/*===============*/
- byte* ptr, /* in: pointer to memory where written */
- dulint roll_ptr) /* in: roll ptr */
+ byte* ptr, /*!< in: pointer to memory where
+ written */
+ roll_ptr_t roll_ptr) /*!< in: roll ptr */
{
#if DATA_ROLL_PTR_LEN != 7
# error "DATA_ROLL_PTR_LEN != 7"
@@ -119,16 +124,16 @@ trx_write_roll_ptr(
mach_write_to_7(ptr, roll_ptr);
}
-/*********************************************************************
+/*****************************************************************//**
Reads a roll ptr from an index page. In case that the roll ptr size
changes in some future version, this function should be used instead of
-mach_read_... */
+mach_read_...
+@return roll ptr */
UNIV_INLINE
-dulint
+roll_ptr_t
trx_read_roll_ptr(
/*==============*/
- /* out: roll ptr */
- const byte* ptr) /* in: pointer to memory from where to read */
+ const byte* ptr) /*!< in: pointer to memory from where to read */
{
#if DATA_ROLL_PTR_LEN != 7
# error "DATA_ROLL_PTR_LEN != 7"
@@ -136,18 +141,19 @@ trx_read_roll_ptr(
return(mach_read_from_7(ptr));
}
-/**********************************************************************
-Gets an undo log page and x-latches it. */
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
+Gets an undo log page and x-latches it.
+@return pointer to page x-latched */
UNIV_INLINE
page_t*
trx_undo_page_get(
/*==============*/
- /* out: pointer to page x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block = buf_page_get(space, zip_size, page_no,
RW_X_LATCH, mtr);
@@ -156,18 +162,18 @@ trx_undo_page_get(
return(buf_block_get_frame(block));
}
-/**********************************************************************
-Gets an undo log page and s-latches it. */
+/******************************************************************//**
+Gets an undo log page and s-latches it.
+@return pointer to page s-latched */
UNIV_INLINE
page_t*
trx_undo_page_get_s_latched(
/*========================*/
- /* out: pointer to page s-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block = buf_page_get(space, zip_size, page_no,
RW_S_LATCH, mtr);
@@ -176,17 +182,17 @@ trx_undo_page_get_s_latched(
return(buf_block_get_frame(block));
}
-/**********************************************************************
+/******************************************************************//**
Returns the start offset of the undo log records of the specified undo
-log on the page. */
+log on the page.
+@return start offset */
UNIV_INLINE
ulint
trx_undo_page_get_start(
/*====================*/
- /* out: start offset */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
ulint start;
@@ -201,17 +207,17 @@ trx_undo_page_get_start(
return(start);
}
-/**********************************************************************
+/******************************************************************//**
Returns the end offset of the undo log records of the specified undo
-log on the page. */
+log on the page.
+@return end offset */
UNIV_INLINE
ulint
trx_undo_page_get_end(
/*==================*/
- /* out: end offset */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
trx_ulogf_t* log_hdr;
ulint end;
@@ -234,17 +240,17 @@ trx_undo_page_get_end(
return(end);
}
-/**********************************************************************
+/******************************************************************//**
Returns the previous undo record on the page in the specified log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_prev_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- trx_undo_rec_t* rec, /* in: undo log record */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ trx_undo_rec_t* rec, /*!< in: undo log record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
page_t* undo_page;
ulint start;
@@ -261,17 +267,17 @@ trx_undo_page_get_prev_rec(
return(undo_page + mach_read_from_2(rec - 2));
}
-/**********************************************************************
+/******************************************************************//**
Returns the next undo log record on the page in the specified log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_next_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- trx_undo_rec_t* rec, /* in: undo log record */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ trx_undo_rec_t* rec, /*!< in: undo log record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
page_t* undo_page;
ulint end;
@@ -291,17 +297,17 @@ trx_undo_page_get_next_rec(
return(undo_page + next);
}
-/**********************************************************************
+/******************************************************************//**
Returns the last undo record on the page in the specified undo log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_last_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
ulint start;
ulint end;
@@ -317,17 +323,17 @@ trx_undo_page_get_last_rec(
return(undo_page + mach_read_from_2(undo_page + end - 2));
}
-/**********************************************************************
+/******************************************************************//**
Returns the first undo record on the page in the specified undo log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_first_rec(
/*========================*/
- /* out: pointer to record, NULL if none */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
ulint start;
ulint end;
@@ -342,3 +348,4 @@ trx_undo_page_get_first_rec(
return(undo_page + start);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/trx0xa.h b/storage/xtradb/include/trx0xa.h
index 0e040b8d8e5..e0dd8a1af5b 100644
--- a/storage/xtradb/include/trx0xa.h
+++ b/storage/xtradb/include/trx0xa.h
@@ -29,32 +29,41 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef XIDDATASIZE
-#define XIDDATASIZE 128 /* size in bytes */
-#define MAXGTRIDSIZE 64 /* maximum size in bytes of gtrid */
-#define MAXBQUALSIZE 64 /* maximum size in bytes of bqual */
+/** Sizes of transaction identifier */
+#define XIDDATASIZE 128 /*!< maximum size of a transaction
+ identifier, in bytes */
+#define MAXGTRIDSIZE 64 /*!< maximum size in bytes of gtrid */
+#define MAXBQUALSIZE 64 /*!< maximum size in bytes of bqual */
+/** X/Open XA distributed transaction identifier */
struct xid_t {
- long formatID; /* format identifier; -1
+ long formatID; /*!< format identifier; -1
means that the XID is null */
- long gtrid_length; /* value from 1 through 64 */
- long bqual_length; /* value from 1 through 64 */
- char data[XIDDATASIZE];
+ long gtrid_length; /*!< value from 1 through 64 */
+ long bqual_length; /*!< value from 1 through 64 */
+ char data[XIDDATASIZE]; /*!< distributed transaction
+ identifier */
};
+/** X/Open XA distributed transaction identifier */
typedef struct xid_t XID;
#endif
-#define XA_OK 0 /* normal execution */
-#define XAER_ASYNC -2 /* asynchronous operation already
+/** X/Open XA distributed transaction status codes */
+/* @{ */
+#define XA_OK 0 /*!< normal execution */
+#define XAER_ASYNC -2 /*!< asynchronous operation already
outstanding */
-#define XAER_RMERR -3 /* a resource manager error occurred in
- the transaction branch */
-#define XAER_NOTA -4 /* the XID is not valid */
-#define XAER_INVAL -5 /* invalid arguments were given */
-#define XAER_PROTO -6 /* routine invoked in an improper
+#define XAER_RMERR -3 /*!< a resource manager error
+ occurred in the transaction
+ branch */
+#define XAER_NOTA -4 /*!< the XID is not valid */
+#define XAER_INVAL -5 /*!< invalid arguments were given */
+#define XAER_PROTO -6 /*!< routine invoked in an improper
context */
-#define XAER_RMFAIL -7 /* resource manager unavailable */
-#define XAER_DUPID -8 /* the XID already exists */
-#define XAER_OUTSIDE -9 /* resource manager doing work outside
- transaction */
+#define XAER_RMFAIL -7 /*!< resource manager unavailable */
+#define XAER_DUPID -8 /*!< the XID already exists */
+#define XAER_OUTSIDE -9 /*!< resource manager doing
+ work outside transaction */
+/* @} */
#endif /* ifndef XA_H */
/*
* End of xa.h header
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 3fc12503031..26097941c5f 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2009, Sun Microsystems, Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -9,6 +10,12 @@ briefly in the InnoDB documentation. The contributions by Google are
incorporated with their permission, and subject to the conditions contained in
the file COPYING.Google.
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
+
This program is free 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.
@@ -23,7 +30,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***************************************************************************
+/***********************************************************************//**
+@file include/univ.i
Version control for database, common definitions, and include files
Created 1/20/1994 Heikki Tuuri
@@ -32,14 +40,18 @@ Created 1/20/1994 Heikki Tuuri
#ifndef univ_i
#define univ_i
+#ifdef UNIV_HOTBACKUP
+#include "hb_univ.i"
+#endif /* UNIV_HOTBACKUP */
+
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
-#define INNODB_VERSION_BUGFIX 3
-#define PERCONA_INNODB_VERSION 6a
+#define INNODB_VERSION_BUGFIX 6
+#define PERCONA_INNODB_VERSION 9
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
-calculated in in make_version_string() in sql/sql_show.cc like this:
+calculated in make_version_string() in sql/sql_show.cc like this:
"version >> 8" . "version & 0xff"
because the version is shown with only one dot, we skip the last
component, i.e. we show M.N.P as M.N */
@@ -47,15 +59,18 @@ component, i.e. we show M.N.P as M.N */
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
/* auxiliary macros to help creating the version as string */
-#define __INNODB_VERSION(a, b, c, d) (#a "." #b "." #c "-" #d)
-#define _INNODB_VERSION(a, b, c, d) __INNODB_VERSION(a, b, c, d)
+#define __INNODB_VERSION(a, b, c, d) (#a "." #b "." #c "-" #d)
+#define _INNODB_VERSION(a, b, c, d) __INNODB_VERSION(a, b, c, d)
+
#define INNODB_VERSION_STR \
_INNODB_VERSION(INNODB_VERSION_MAJOR, \
INNODB_VERSION_MINOR, \
- INNODB_VERSION_BUGFIX, \
+ INNODB_VERSION_BUGFIX, \
PERCONA_INNODB_VERSION)
+#define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/"
+
#ifdef MYSQL_DYNAMIC_PLUGIN
/* In the dynamic plugin, redefine some externally visible symbols
in order not to conflict with the symbols of a builtin InnoDB. */
@@ -66,16 +81,25 @@ the virtual method table (vtable) in GCC 3. */
# define ha_innobase ha_innodb
#endif /* MYSQL_DYNAMIC_PLUGIN */
+/* if any of the following macros is defined at this point this means
+that the code from the "right" plug.in was executed and we do not
+need to include ut0auxconf.h which would either define the same macros
+or will be empty */
+#if !defined(HAVE_IB_GCC_ATOMIC_BUILTINS) \
+ && !defined(HAVE_IB_ATOMIC_PTHREAD_T_GCC) \
+ && !defined(HAVE_IB_SOLARIS_ATOMICS) \
+ && !defined(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) \
+ && !defined(SIZEOF_PTHREAD_T) \
+ && !defined(HAVE_IB_PAUSE_INSTRUCTION)
+# include "ut0auxconf.h"
+#endif
+
#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
# undef __WIN__
# define __WIN__
# include <windows.h>
-# if !defined(WIN64) && !defined(_WIN64)
-# define UNIV_CAN_USE_X86_ASSEMBLER
-# endif
-
# ifdef _NT_
# define __NT__
# endif
@@ -87,8 +111,10 @@ the virtual method table (vtable) in GCC 3. */
in compiling more Posix-compatible. These headers also define __WIN__
if we are compiling on Windows. */
+#ifndef UNIV_HOTBACKUP
# include <my_global.h>
# include <my_pthread.h>
+#endif /* UNIV_HOTBACKUP */
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
# include <sys/stat.h>
@@ -96,47 +122,21 @@ if we are compiling on Windows. */
# include <sys/mman.h> /* mmap() for os0proc.c */
# endif
-# undef PACKAGE
-# undef VERSION
-
/* Include the header file generated by GNU autoconf */
# ifndef __WIN__
-# include "config.h"
+# ifndef UNIV_HOTBACKUP
+# include "config.h"
+# endif /* UNIV_HOTBACKUP */
# endif
# ifdef HAVE_SCHED_H
# include <sched.h>
# endif
-/* When compiling for Itanium IA64, undefine the flag below to prevent use
-of the 32-bit x86 assembler in mutex operations. */
+/* We only try to do explicit inlining of functions with gcc and
+Sun Studio */
-# if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64)
-# define UNIV_CAN_USE_X86_ASSEMBLER
-# endif
-
-/* For InnoDB rw_locks to work with atomics we need the thread_id
-to be no more than machine word wide. The following enables using
-atomics for InnoDB rw_locks where these conditions are met. */
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-/* if HAVE_ATOMIC_PTHREAD_T is defined at this point that means that
-the code from plug.in has defined it and we do not need to include
-ut0auxconf.h which would either define HAVE_ATOMIC_PTHREAD_T or will
-be empty */
-# ifndef HAVE_ATOMIC_PTHREAD_T
-# include "ut0auxconf.h"
-# endif /* HAVE_ATOMIC_PTHREAD_T */
-/* now HAVE_ATOMIC_PTHREAD_T is eventually defined either by plug.in or
-from Makefile.in->ut0auxconf.h */
-# ifdef HAVE_ATOMIC_PTHREAD_T
-# define INNODB_RW_LOCKS_USE_ATOMICS
-# endif /* HAVE_ATOMIC_PTHREAD_T */
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
-
-/* Enable explicit inlining of functions only for compilers known to
-support it. */
-
-# if !defined(__GNUC__) && !defined(__SUNPRO_C)
+# if !defined(__GNUC__) && !(defined(__SUNPRO_C) || defined(__SUNPRO_CC))
# undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */
# define UNIV_MUST_NOT_INLINE
# endif
@@ -179,12 +179,18 @@ command. Not tested on Windows. */
debugging without UNIV_DEBUG */
#define UNIV_DEBUG /* Enable ut_ad() assertions
and disable UNIV_INLINE */
+#define UNIV_DEBUG_LOCK_VALIDATE /* Enable
+ ut_ad(lock_rec_validate_page())
+ assertions. */
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
(field file_page_was_freed
in buf_page_t) */
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
+#define UNIV_LOG_LSN_DEBUG /* write LSN to the redo log;
+this will break redo log file compatibility, but it may be useful when
+debugging redo log application problems. */
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
#define UNIV_IBUF_DEBUG /* debug the insert buffer */
#define UNIV_IBUF_COUNT_DEBUG /* debug the insert buffer;
@@ -234,19 +240,21 @@ by one. */
/* Linkage specifier for non-static InnoDB symbols (variables and functions)
that are only referenced from within InnoDB, not from MySQL */
-#ifdef __WIN__
-# define UNIV_INTERN
-#else
+#if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__INTEL_COMPILER)
# define UNIV_INTERN __attribute__((visibility ("hidden")))
+#else
+# define UNIV_INTERN
#endif
#if (!defined(UNIV_DEBUG) && !defined(UNIV_MUST_NOT_INLINE))
/* Definition for inline version */
#ifdef __WIN__
-#define UNIV_INLINE __inline
+# define UNIV_INLINE __inline
+#elif defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+# define UNIV_INLINE static inline
#else
-#define UNIV_INLINE static __inline__
+# define UNIV_INLINE static __inline__
#endif
#else
@@ -323,13 +331,15 @@ typedef long int lint;
#ifdef __WIN__
typedef __int64 ib_int64_t;
typedef unsigned __int64 ib_uint64_t;
-#else
+#elif !defined(UNIV_HOTBACKUP)
/* Note: longlong and ulonglong come from MySQL headers. */
typedef longlong ib_int64_t;
typedef ulonglong ib_uint64_t;
#endif
+#ifndef UNIV_HOTBACKUP
typedef unsigned long long int ullint;
+#endif /* UNIV_HOTBACKUP */
#ifndef __WIN__
#if SIZEOF_LONG != SIZEOF_VOIDP
@@ -387,6 +397,19 @@ it is read. */
/* Minimize cache-miss latency by moving data at addr into a cache before
it is read or written. */
# define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
+/* Sun Studio includes sun_prefetch.h as of version 5.9 */
+#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \
+ || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
+# include <sun_prefetch.h>
+#if __SUNPRO_C >= 0x550
+# undef UNIV_INTERN
+# define UNIV_INTERN __hidden
+#endif /* __SUNPRO_C >= 0x550 */
+/* Use sun_prefetch when compile with Sun Studio */
+# define UNIV_EXPECT(expr,value) (expr)
+# define UNIV_LIKELY_NULL(expr) (expr)
+# define UNIV_PREFETCH_R(addr) sun_prefetch_read_many(addr)
+# define UNIV_PREFETCH_RW(addr) sun_prefetch_write_many(addr)
#else
/* Dummy versions of the macros */
# define UNIV_EXPECT(expr,value) (expr)
diff --git a/storage/xtradb/include/usr0sess.h b/storage/xtradb/include/usr0sess.h
index 08c6c70066f..2c288f7d455 100644
--- a/storage/xtradb/include/usr0sess.h
+++ b/storage/xtradb/include/usr0sess.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/usr0sess.h
Sessions
Created 6/25/1996 Heikki Tuuri
@@ -35,33 +36,31 @@ Created 6/25/1996 Heikki Tuuri
#include "data0data.h"
#include "rem0rec.h"
-/*************************************************************************
-Opens a session. */
+/*********************************************************************//**
+Opens a session.
+@return own: session object */
UNIV_INTERN
sess_t*
sess_open(void);
/*============*/
- /* out, own: session object */
-/*************************************************************************
-Closes a session, freeing the memory occupied by it, if it is in a state
-where it should be closed. */
+/*********************************************************************//**
+Closes a session, freeing the memory occupied by it. */
UNIV_INTERN
-ibool
-sess_try_close(
-/*===========*/
- /* out: TRUE if closed */
- sess_t* sess); /* in, own: session object */
+void
+sess_close(
+/*=======*/
+ sess_t* sess); /* in, own: session object */
/* The session handle. All fields are protected by the kernel mutex */
struct sess_struct{
- ulint state; /* state of the session */
- trx_t* trx; /* transaction object permanently
+ ulint state; /*!< state of the session */
+ trx_t* trx; /*!< transaction object permanently
assigned for the session: the
transaction instance designated by the
trx id changes, but the memory
structure is preserved */
UT_LIST_BASE_NODE_T(que_t)
- graphs; /* query graphs belonging to this
+ graphs; /*!< query graphs belonging to this
session */
};
diff --git a/storage/xtradb/include/usr0sess.ic b/storage/xtradb/include/usr0sess.ic
index 5eefed382da..35a75d75acc 100644
--- a/storage/xtradb/include/usr0sess.ic
+++ b/storage/xtradb/include/usr0sess.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/usr0sess.ic
Sessions
Created 6/25/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/usr0types.h b/storage/xtradb/include/usr0types.h
index 7f7d12f7bf5..6cc6f015613 100644
--- a/storage/xtradb/include/usr0types.h
+++ b/storage/xtradb/include/usr0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/usr0types.h
Users and sessions global types
Created 6/25/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/ut0auxconf.h b/storage/xtradb/include/ut0auxconf.h
index fb5fae9b399..16bcc308392 100644
--- a/storage/xtradb/include/ut0auxconf.h
+++ b/storage/xtradb/include/ut0auxconf.h
@@ -1,19 +1,14 @@
/* Do not remove this file even though it is empty.
This file is included in univ.i and will cause compilation failure
if not present.
-A custom check has been added in the generated
-storage/innobase/Makefile.in that is shipped with with the InnoDB Plugin
-source archive. This check tries to compile a test program and if
-successful then adds "#define HAVE_ATOMIC_PTHREAD_T" to this file.
-This is a hack that has been developed in order to check for pthread_t
-atomicity without the need to regenerate the ./configure script that is
+A custom checks have been added in the generated
+storage/innobase/Makefile.in that is shipped with the InnoDB Plugin
+source archive. These checks eventually define some macros and put
+them in this file.
+This is a hack that has been developed in order to deploy new compile
+time checks without the need to regenerate the ./configure script that is
distributed in the MySQL 5.1 official source archives.
If by any chance Makefile.in and ./configure are regenerated and thus
-the hack from Makefile.in wiped away then the "real" check from plug.in
+the hack from Makefile.in wiped away then the "real" checks from plug.in
will take over.
*/
-/* This is temprary fix for http://bugs.mysql.com/43740 */
-/* force to enable */
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-#define HAVE_ATOMIC_PTHREAD_T
-#endif
diff --git a/storage/xtradb/include/ut0byte.h b/storage/xtradb/include/ut0byte.h
index 24aac1678b3..f55e2888c60 100644
--- a/storage/xtradb/include/ut0byte.h
+++ b/storage/xtradb/include/ut0byte.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0byte.h
Utilities for byte operations
Created 1/20/1994 Heikki Tuuri
@@ -28,163 +29,162 @@ Created 1/20/1994 Heikki Tuuri
#include "univ.i"
-/* Type definition for a 64-bit unsigned integer, which works also
+/** Pair of ulint integers. */
+typedef struct dulint_struct dulint;
+/** Type definition for a 64-bit unsigned integer, which works also
in 32-bit machines. NOTE! Access the fields only with the accessor
functions. This definition appears here only for the compiler to
know the size of a dulint. */
-
-typedef struct dulint_struct dulint;
struct dulint_struct{
- ulint high; /* most significant 32 bits */
- ulint low; /* least significant 32 bits */
+ ulint high; /*!< most significant 32 bits */
+ ulint low; /*!< least significant 32 bits */
};
-/* Zero value for a dulint */
+/** Zero value for a dulint */
extern const dulint ut_dulint_zero;
-/* Maximum value for a dulint */
+/** Maximum value for a dulint */
extern const dulint ut_dulint_max;
-/***********************************************************
-Creates a 64-bit dulint out of two ulints. */
+/*******************************************************//**
+Creates a 64-bit dulint out of two ulints.
+@return created dulint */
UNIV_INLINE
dulint
ut_dulint_create(
/*=============*/
- /* out: created dulint */
- ulint high, /* in: high-order 32 bits */
- ulint low); /* in: low-order 32 bits */
-/***********************************************************
-Gets the high-order 32 bits of a dulint. */
+ ulint high, /*!< in: high-order 32 bits */
+ ulint low); /*!< in: low-order 32 bits */
+/*******************************************************//**
+Gets the high-order 32 bits of a dulint.
+@return 32 bits in ulint */
UNIV_INLINE
ulint
ut_dulint_get_high(
/*===============*/
- /* out: 32 bits in ulint */
- dulint d); /* in: dulint */
-/***********************************************************
-Gets the low-order 32 bits of a dulint. */
+ dulint d); /*!< in: dulint */
+/*******************************************************//**
+Gets the low-order 32 bits of a dulint.
+@return 32 bits in ulint */
UNIV_INLINE
ulint
ut_dulint_get_low(
/*==============*/
- /* out: 32 bits in ulint */
- dulint d); /* in: dulint */
-/***********************************************************
+ dulint d); /*!< in: dulint */
+/*******************************************************//**
Converts a dulint (a struct of 2 ulints) to ib_int64_t, which is a 64-bit
-integer type. */
+integer type.
+@return value in ib_int64_t type */
UNIV_INLINE
ib_int64_t
ut_conv_dulint_to_longlong(
/*=======================*/
- /* out: value in ib_int64_t type */
- dulint d); /* in: dulint */
-/***********************************************************
-Tests if a dulint is zero. */
+ dulint d); /*!< in: dulint */
+/*******************************************************//**
+Tests if a dulint is zero.
+@return TRUE if zero */
UNIV_INLINE
ibool
ut_dulint_is_zero(
/*==============*/
- /* out: TRUE if zero */
- dulint a); /* in: dulint */
-/***********************************************************
-Compares two dulints. */
+ dulint a); /*!< in: dulint */
+/*******************************************************//**
+Compares two dulints.
+@return -1 if a < b, 0 if a == b, 1 if a > b */
UNIV_INLINE
int
ut_dulint_cmp(
/*==========*/
- /* out: -1 if a < b, 0 if a == b,
- 1 if a > b */
- dulint a, /* in: dulint */
- dulint b); /* in: dulint */
-/***********************************************************
-Calculates the max of two dulints. */
+ dulint a, /*!< in: dulint */
+ dulint b); /*!< in: dulint */
+/*******************************************************//**
+Calculates the max of two dulints.
+@return max(a, b) */
UNIV_INLINE
dulint
ut_dulint_get_max(
/*==============*/
- /* out: max(a, b) */
- dulint a, /* in: dulint */
- dulint b); /* in: dulint */
-/***********************************************************
-Calculates the min of two dulints. */
+ dulint a, /*!< in: dulint */
+ dulint b); /*!< in: dulint */
+/*******************************************************//**
+Calculates the min of two dulints.
+@return min(a, b) */
UNIV_INLINE
dulint
ut_dulint_get_min(
/*==============*/
- /* out: min(a, b) */
- dulint a, /* in: dulint */
- dulint b); /* in: dulint */
-/***********************************************************
-Adds a ulint to a dulint. */
+ dulint a, /*!< in: dulint */
+ dulint b); /*!< in: dulint */
+/*******************************************************//**
+Adds a ulint to a dulint.
+@return sum a + b */
UNIV_INLINE
dulint
ut_dulint_add(
/*==========*/
- /* out: sum a + b */
- dulint a, /* in: dulint */
- ulint b); /* in: ulint */
-/***********************************************************
-Subtracts a ulint from a dulint. */
+ dulint a, /*!< in: dulint */
+ ulint b); /*!< in: ulint */
+/*******************************************************//**
+Subtracts a ulint from a dulint.
+@return a - b */
UNIV_INLINE
dulint
ut_dulint_subtract(
/*===============*/
- /* out: a - b */
- dulint a, /* in: dulint */
- ulint b); /* in: ulint, b <= a */
-/***********************************************************
+ dulint a, /*!< in: dulint */
+ ulint b); /*!< in: ulint, b <= a */
+/*******************************************************//**
Subtracts a dulint from another. NOTE that the difference must be positive
-and smaller that 4G. */
+and smaller that 4G.
+@return a - b */
UNIV_INLINE
ulint
ut_dulint_minus(
/*============*/
- /* out: a - b */
- dulint a, /* in: dulint; NOTE a must be >= b and at most
+ dulint a, /*!< in: dulint; NOTE a must be >= b and at most
2 to power 32 - 1 greater */
- dulint b); /* in: dulint */
-/************************************************************
-Rounds a dulint downward to a multiple of a power of 2. */
+ dulint b); /*!< in: dulint */
+/********************************************************//**
+Rounds a dulint downward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
dulint
ut_dulint_align_down(
/*=================*/
- /* out: rounded value */
- dulint n, /* in: number to be rounded */
- ulint align_no); /* in: align by this number which must be a
+ dulint n, /*!< in: number to be rounded */
+ ulint align_no); /*!< in: align by this number which must be a
power of 2 */
-/************************************************************
-Rounds a dulint upward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds a dulint upward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
dulint
ut_dulint_align_up(
/*===============*/
- /* out: rounded value */
- dulint n, /* in: number to be rounded */
- ulint align_no); /* in: align by this number which must be a
+ dulint n, /*!< in: number to be rounded */
+ ulint align_no); /*!< in: align by this number which must be a
power of 2 */
-/************************************************************
-Rounds a dulint downward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds a dulint downward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
ib_uint64_t
ut_uint64_align_down(
/*=================*/
- /* out: rounded value */
- ib_uint64_t n, /* in: number to be rounded */
- ulint align_no); /* in: align by this number
+ ib_uint64_t n, /*!< in: number to be rounded */
+ ulint align_no); /*!< in: align by this number
which must be a power of 2 */
-/************************************************************
-Rounds ib_uint64_t upward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds ib_uint64_t upward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
ib_uint64_t
ut_uint64_align_up(
/*===============*/
- /* out: rounded value */
- ib_uint64_t n, /* in: number to be rounded */
- ulint align_no); /* in: align by this number
+ ib_uint64_t n, /*!< in: number to be rounded */
+ ulint align_no); /*!< in: align by this number
which must be a power of 2 */
-/***********************************************************
+/*******************************************************//**
Increments a dulint variable by 1. */
#define UT_DULINT_INC(D)\
{\
@@ -195,71 +195,73 @@ Increments a dulint variable by 1. */
(D).low = (D).low + 1;\
}\
}
-/***********************************************************
+/*******************************************************//**
Tests if two dulints are equal. */
#define UT_DULINT_EQ(D1, D2) (((D1).low == (D2).low)\
&& ((D1).high == (D2).high))
#ifdef notdefined
-/****************************************************************
+/************************************************************//**
Sort function for dulint arrays. */
UNIV_INTERN
void
-ut_dulint_sort(dulint* arr, dulint* aux_arr, ulint low, ulint high);
-/*===============================================================*/
+ut_dulint_sort(
+/*===========*/
+ dulint* arr, /*!< in/out: array to be sorted */
+ dulint* aux_arr,/*!< in/out: auxiliary array (same size as arr) */
+ ulint low, /*!< in: low bound of sort interval, inclusive */
+ ulint high); /*!< in: high bound of sort interval, noninclusive */
#endif /* notdefined */
-/*************************************************************
-The following function rounds up a pointer to the nearest aligned address. */
+/*********************************************************//**
+The following function rounds up a pointer to the nearest aligned address.
+@return aligned pointer */
UNIV_INLINE
void*
ut_align(
/*=====*/
- /* out: aligned pointer */
- void* ptr, /* in: pointer */
- ulint align_no); /* in: align by this number */
-/*************************************************************
+ const void* ptr, /*!< in: pointer */
+ ulint align_no); /*!< in: align by this number */
+/*********************************************************//**
The following function rounds down a pointer to the nearest
-aligned address. */
+aligned address.
+@return aligned pointer */
UNIV_INLINE
void*
ut_align_down(
/*==========*/
- /* out: aligned pointer */
- const void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
__attribute__((const));
-/*************************************************************
+/*********************************************************//**
The following function computes the offset of a pointer from the nearest
-aligned address. */
+aligned address.
+@return distance from aligned pointer */
UNIV_INLINE
ulint
ut_align_offset(
/*============*/
- /* out: distance from aligned
- pointer */
- const void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
__attribute__((const));
-/*********************************************************************
-Gets the nth bit of a ulint. */
+/*****************************************************************//**
+Gets the nth bit of a ulint.
+@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */
UNIV_INLINE
ibool
ut_bit_get_nth(
/*===========*/
- /* out: TRUE if nth bit is 1; 0th bit is defined to
- be the least significant */
- ulint a, /* in: ulint */
- ulint n); /* in: nth bit requested */
-/*********************************************************************
-Sets the nth bit of a ulint. */
+ ulint a, /*!< in: ulint */
+ ulint n); /*!< in: nth bit requested */
+/*****************************************************************//**
+Sets the nth bit of a ulint.
+@return the ulint with the bit set as requested */
UNIV_INLINE
ulint
ut_bit_set_nth(
/*===========*/
- /* out: the ulint with the bit set as requested */
- ulint a, /* in: ulint */
- ulint n, /* in: nth bit requested */
- ibool val); /* in: value for the bit to set */
+ ulint a, /*!< in: ulint */
+ ulint n, /*!< in: nth bit requested */
+ ibool val); /*!< in: value for the bit to set */
#ifndef UNIV_NONINL
#include "ut0byte.ic"
diff --git a/storage/xtradb/include/ut0byte.ic b/storage/xtradb/include/ut0byte.ic
index 021a3a15009..3dd51890cb4 100644
--- a/storage/xtradb/include/ut0byte.ic
+++ b/storage/xtradb/include/ut0byte.ic
@@ -16,21 +16,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************************
+/**************************************************************//**
+@file include/ut0byte.ic
Utilities for byte operations
Created 5/30/1994 Heikki Tuuri
*******************************************************************/
-/***********************************************************
-Creates a 64-bit dulint out of two ulints. */
+/*******************************************************//**
+Creates a 64-bit dulint out of two ulints.
+@return created dulint */
UNIV_INLINE
dulint
ut_dulint_create(
/*=============*/
- /* out: created dulint */
- ulint high, /* in: high-order 32 bits */
- ulint low) /* in: low-order 32 bits */
+ ulint high, /*!< in: high-order 32 bits */
+ ulint low) /*!< in: low-order 32 bits */
{
dulint res;
@@ -43,52 +44,52 @@ ut_dulint_create(
return(res);
}
-/***********************************************************
-Gets the high-order 32 bits of a dulint. */
+/*******************************************************//**
+Gets the high-order 32 bits of a dulint.
+@return 32 bits in ulint */
UNIV_INLINE
ulint
ut_dulint_get_high(
/*===============*/
- /* out: 32 bits in ulint */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
{
return(d.high);
}
-/***********************************************************
-Gets the low-order 32 bits of a dulint. */
+/*******************************************************//**
+Gets the low-order 32 bits of a dulint.
+@return 32 bits in ulint */
UNIV_INLINE
ulint
ut_dulint_get_low(
/*==============*/
- /* out: 32 bits in ulint */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
{
return(d.low);
}
-/***********************************************************
+/*******************************************************//**
Converts a dulint (a struct of 2 ulints) to ib_int64_t, which is a 64-bit
-integer type. */
+integer type.
+@return value in ib_int64_t type */
UNIV_INLINE
ib_int64_t
ut_conv_dulint_to_longlong(
/*=======================*/
- /* out: value in ib_int64_t type */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
{
return((ib_int64_t)d.low
+ (((ib_int64_t)d.high) << 32));
}
-/***********************************************************
-Tests if a dulint is zero. */
+/*******************************************************//**
+Tests if a dulint is zero.
+@return TRUE if zero */
UNIV_INLINE
ibool
ut_dulint_is_zero(
/*==============*/
- /* out: TRUE if zero */
- dulint a) /* in: dulint */
+ dulint a) /*!< in: dulint */
{
if ((a.low == 0) && (a.high == 0)) {
@@ -98,16 +99,15 @@ ut_dulint_is_zero(
return(FALSE);
}
-/***********************************************************
-Compares two dulints. */
+/*******************************************************//**
+Compares two dulints.
+@return -1 if a < b, 0 if a == b, 1 if a > b */
UNIV_INLINE
int
ut_dulint_cmp(
/*==========*/
- /* out: -1 if a < b, 0 if a == b,
- 1 if a > b */
- dulint a, /* in: dulint */
- dulint b) /* in: dulint */
+ dulint a, /*!< in: dulint */
+ dulint b) /*!< in: dulint */
{
if (a.high > b.high) {
return(1);
@@ -122,15 +122,15 @@ ut_dulint_cmp(
}
}
-/***********************************************************
-Calculates the max of two dulints. */
+/*******************************************************//**
+Calculates the max of two dulints.
+@return max(a, b) */
UNIV_INLINE
dulint
ut_dulint_get_max(
/*==============*/
- /* out: max(a, b) */
- dulint a, /* in: dulint */
- dulint b) /* in: dulint */
+ dulint a, /*!< in: dulint */
+ dulint b) /*!< in: dulint */
{
if (ut_dulint_cmp(a, b) > 0) {
@@ -140,15 +140,15 @@ ut_dulint_get_max(
return(b);
}
-/***********************************************************
-Calculates the min of two dulints. */
+/*******************************************************//**
+Calculates the min of two dulints.
+@return min(a, b) */
UNIV_INLINE
dulint
ut_dulint_get_min(
/*==============*/
- /* out: min(a, b) */
- dulint a, /* in: dulint */
- dulint b) /* in: dulint */
+ dulint a, /*!< in: dulint */
+ dulint b) /*!< in: dulint */
{
if (ut_dulint_cmp(a, b) > 0) {
@@ -158,15 +158,15 @@ ut_dulint_get_min(
return(a);
}
-/***********************************************************
-Adds a ulint to a dulint. */
+/*******************************************************//**
+Adds a ulint to a dulint.
+@return sum a + b */
UNIV_INLINE
dulint
ut_dulint_add(
/*==========*/
- /* out: sum a + b */
- dulint a, /* in: dulint */
- ulint b) /* in: ulint */
+ dulint a, /*!< in: dulint */
+ ulint b) /*!< in: ulint */
{
if (0xFFFFFFFFUL - b >= a.low) {
a.low += b;
@@ -181,15 +181,15 @@ ut_dulint_add(
return(a);
}
-/***********************************************************
-Subtracts a ulint from a dulint. */
+/*******************************************************//**
+Subtracts a ulint from a dulint.
+@return a - b */
UNIV_INLINE
dulint
ut_dulint_subtract(
/*===============*/
- /* out: a - b */
- dulint a, /* in: dulint */
- ulint b) /* in: ulint, b <= a */
+ dulint a, /*!< in: dulint */
+ ulint b) /*!< in: ulint, b <= a */
{
if (a.low >= b) {
a.low -= b;
@@ -208,17 +208,17 @@ ut_dulint_subtract(
return(a);
}
-/***********************************************************
+/*******************************************************//**
Subtracts a dulint from another. NOTE that the difference must be positive
-and smaller that 4G. */
+and smaller that 4G.
+@return a - b */
UNIV_INLINE
ulint
ut_dulint_minus(
/*============*/
- /* out: a - b */
- dulint a, /* in: dulint; NOTE a must be >= b and at most
+ dulint a, /*!< in: dulint; NOTE a must be >= b and at most
2 to power 32 - 1 greater */
- dulint b) /* in: dulint */
+ dulint b) /*!< in: dulint */
{
ulint diff;
@@ -238,15 +238,15 @@ ut_dulint_minus(
return(diff);
}
-/************************************************************
-Rounds a dulint downward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds a dulint downward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
dulint
ut_dulint_align_down(
/*=================*/
- /* out: rounded value */
- dulint n, /* in: number to be rounded */
- ulint align_no) /* in: align by this number which must be a
+ dulint n, /*!< in: number to be rounded */
+ ulint align_no) /*!< in: align by this number which must be a
power of 2 */
{
ulint low, high;
@@ -262,29 +262,29 @@ ut_dulint_align_down(
return(ut_dulint_create(high, low));
}
-/************************************************************
-Rounds a dulint upward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds a dulint upward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
dulint
ut_dulint_align_up(
/*===============*/
- /* out: rounded value */
- dulint n, /* in: number to be rounded */
- ulint align_no) /* in: align by this number which must be a
+ dulint n, /*!< in: number to be rounded */
+ ulint align_no) /*!< in: align by this number which must be a
power of 2 */
{
return(ut_dulint_align_down(ut_dulint_add(n, align_no - 1), align_no));
}
-/************************************************************
-Rounds ib_uint64_t downward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds ib_uint64_t downward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
ib_uint64_t
ut_uint64_align_down(
/*=================*/
- /* out: rounded value */
- ib_uint64_t n, /* in: number to be rounded */
- ulint align_no) /* in: align by this number
+ ib_uint64_t n, /*!< in: number to be rounded */
+ ulint align_no) /*!< in: align by this number
which must be a power of 2 */
{
ut_ad(align_no > 0);
@@ -293,15 +293,15 @@ ut_uint64_align_down(
return(n & ~((ib_uint64_t) align_no - 1));
}
-/************************************************************
-Rounds ib_uint64_t upward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds ib_uint64_t upward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
ib_uint64_t
ut_uint64_align_up(
/*===============*/
- /* out: rounded value */
- ib_uint64_t n, /* in: number to be rounded */
- ulint align_no) /* in: align by this number
+ ib_uint64_t n, /*!< in: number to be rounded */
+ ulint align_no) /*!< in: align by this number
which must be a power of 2 */
{
ib_uint64_t align_1 = (ib_uint64_t) align_no - 1;
@@ -312,15 +312,15 @@ ut_uint64_align_up(
return((n + align_1) & ~align_1);
}
-/*************************************************************
-The following function rounds up a pointer to the nearest aligned address. */
+/*********************************************************//**
+The following function rounds up a pointer to the nearest aligned address.
+@return aligned pointer */
UNIV_INLINE
void*
ut_align(
/*=====*/
- /* out: aligned pointer */
- void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
@@ -331,16 +331,16 @@ ut_align(
return((void*)((((ulint)ptr) + align_no - 1) & ~(align_no - 1)));
}
-/*************************************************************
+/*********************************************************//**
The following function rounds down a pointer to the nearest
-aligned address. */
+aligned address.
+@return aligned pointer */
UNIV_INLINE
void*
ut_align_down(
/*==========*/
- /* out: aligned pointer */
- const void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
@@ -351,17 +351,16 @@ ut_align_down(
return((void*)((((ulint)ptr)) & ~(align_no - 1)));
}
-/*************************************************************
+/*********************************************************//**
The following function computes the offset of a pointer from the nearest
-aligned address. */
+aligned address.
+@return distance from aligned pointer */
UNIV_INLINE
ulint
ut_align_offset(
/*============*/
- /* out: distance from
- aligned pointer */
- const void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
@@ -372,16 +371,15 @@ ut_align_offset(
return(((ulint)ptr) & (align_no - 1));
}
-/*********************************************************************
-Gets the nth bit of a ulint. */
+/*****************************************************************//**
+Gets the nth bit of a ulint.
+@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */
UNIV_INLINE
ibool
ut_bit_get_nth(
/*===========*/
- /* out: TRUE if nth bit is 1; 0th bit is defined to
- be the least significant */
- ulint a, /* in: ulint */
- ulint n) /* in: nth bit requested */
+ ulint a, /*!< in: ulint */
+ ulint n) /*!< in: nth bit requested */
{
ut_ad(n < 8 * sizeof(ulint));
#if TRUE != 1
@@ -390,16 +388,16 @@ ut_bit_get_nth(
return(1 & (a >> n));
}
-/*********************************************************************
-Sets the nth bit of a ulint. */
+/*****************************************************************//**
+Sets the nth bit of a ulint.
+@return the ulint with the bit set as requested */
UNIV_INLINE
ulint
ut_bit_set_nth(
/*===========*/
- /* out: the ulint with the bit set as requested */
- ulint a, /* in: ulint */
- ulint n, /* in: nth bit requested */
- ibool val) /* in: value for the bit to set */
+ ulint a, /*!< in: ulint */
+ ulint n, /*!< in: nth bit requested */
+ ibool val) /*!< in: value for the bit to set */
{
ut_ad(n < 8 * sizeof(ulint));
#if TRUE != 1
diff --git a/storage/xtradb/include/ut0dbg.h b/storage/xtradb/include/ut0dbg.h
index a206789fd4c..78b525c38ab 100644
--- a/storage/xtradb/include/ut0dbg.h
+++ b/storage/xtradb/include/ut0dbg.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*********************************************************************
+/*****************************************************************//**
+@file include/ut0dbg.h
Debug utilities for Innobase
Created 1/30/1994 Heikki Tuuri
@@ -30,26 +31,33 @@ Created 1/30/1994 Heikki Tuuri
#include "os0thread.h"
#if defined(__GNUC__) && (__GNUC__ > 2)
+/** Test if an assertion fails.
+@param EXPR assertion expression
+@return nonzero if EXPR holds, zero if not */
# define UT_DBG_FAIL(EXPR) UNIV_UNLIKELY(!((ulint)(EXPR)))
#else
-extern ulint ut_dbg_zero; /* This is used to eliminate
- compiler warnings */
+/** This is used to eliminate compiler warnings */
+extern ulint ut_dbg_zero;
+/** Test if an assertion fails.
+@param EXPR assertion expression
+@return nonzero if EXPR holds, zero if not */
# define UT_DBG_FAIL(EXPR) !((ulint)(EXPR) + ut_dbg_zero)
#endif
-/*****************************************************************
+/*************************************************************//**
Report a failed assertion. */
UNIV_INTERN
void
ut_dbg_assertion_failed(
/*====================*/
- const char* expr, /* in: the failed assertion */
- const char* file, /* in: source file containing the assertion */
- ulint line); /* in: line number of the assertion */
+ const char* expr, /*!< in: the failed assertion */
+ const char* file, /*!< in: source file containing the assertion */
+ ulint line); /*!< in: line number of the assertion */
#ifdef __NETWARE__
-/* Flag for ignoring further assertion failures.
-On NetWare, have a graceful exit rather than a segfault to avoid abends. */
+/** Flag for ignoring further assertion failures. This is set to TRUE
+when on NetWare there happens an InnoDB assertion failure or other
+fatal error condition that requires an immediate shutdown. */
extern ibool panic_shutdown;
/* Abort the execution. */
void ut_dbg_panic(void);
@@ -64,16 +72,16 @@ void ut_dbg_panic(void);
# endif
# ifndef UT_DBG_USE_ABORT
-/* A null pointer that will be dereferenced to trigger a memory trap */
+/** A null pointer that will be dereferenced to trigger a memory trap */
extern ulint* ut_dbg_null_ptr;
# endif
# if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/* Flag for indicating that all threads should stop. This will be set
-by ut_dbg_assertion_failed(). */
+/** If this is set to TRUE by ut_dbg_assertion_failed(), all threads
+will stop at the next ut_a() or ut_ad(). */
extern ibool ut_dbg_stop_threads;
-/*****************************************************************
+/*************************************************************//**
Stop a thread after assertion failure. */
UNIV_INTERN
void
@@ -84,15 +92,15 @@ ut_dbg_stop_thread(
# endif
# ifdef UT_DBG_USE_ABORT
-/* Abort the execution. */
+/** Abort the execution. */
# define UT_DBG_PANIC abort()
-/* Stop threads (null operation) */
+/** Stop threads (null operation) */
# define UT_DBG_STOP do {} while (0)
# else /* UT_DBG_USE_ABORT */
-/* Abort the execution. */
+/** Abort the execution. */
# define UT_DBG_PANIC \
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL
-/* Stop threads in ut_a(). */
+/** Stop threads in ut_a(). */
# define UT_DBG_STOP do \
if (UNIV_UNLIKELY(ut_dbg_stop_threads)) { \
ut_dbg_stop_thread(__FILE__, (ulint) __LINE__); \
@@ -100,7 +108,8 @@ ut_dbg_stop_thread(
# endif /* UT_DBG_USE_ABORT */
#endif /* __NETWARE__ */
-/* Abort execution if EXPR does not evaluate to nonzero. */
+/** Abort execution if EXPR does not evaluate to nonzero.
+@param EXPR assertion expression that should hold */
#define ut_a(EXPR) do { \
if (UT_DBG_FAIL(EXPR)) { \
ut_dbg_assertion_failed(#EXPR, \
@@ -110,20 +119,26 @@ ut_dbg_stop_thread(
UT_DBG_STOP; \
} while (0)
-/* Abort execution. */
+/** Abort execution. */
#define ut_error do { \
ut_dbg_assertion_failed(0, __FILE__, (ulint) __LINE__); \
UT_DBG_PANIC; \
} while (0)
#ifdef UNIV_DEBUG
+/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR) ut_a(EXPR)
+/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) do {EXPR;} while (0)
#else
+/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR)
+/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR)
#endif
+/** Silence warnings about an unused variable by doing a null assignment.
+@param A the unused variable */
#define UT_NOT_USED(A) A = A
#ifdef UNIV_COMPILE_TEST_FUNCS
@@ -132,28 +147,28 @@ ut_dbg_stop_thread(
#include <sys/time.h>
#include <sys/resource.h>
-/* structure used for recording usage statistics */
+/** structure used for recording usage statistics */
typedef struct speedo_struct {
- struct rusage ru;
- struct timeval tv;
+ struct rusage ru; /*!< getrusage() result */
+ struct timeval tv; /*!< gettimeofday() result */
} speedo_t;
-/***********************************************************************
+/*******************************************************************//**
Resets a speedo (records the current time in it). */
UNIV_INTERN
void
speedo_reset(
/*=========*/
- speedo_t* speedo); /* out: speedo */
+ speedo_t* speedo); /*!< out: speedo */
-/***********************************************************************
+/*******************************************************************//**
Shows the time elapsed and usage statistics since the last reset of a
speedo. */
UNIV_INTERN
void
speedo_show(
/*========*/
- const speedo_t* speedo); /* in: speedo */
+ const speedo_t* speedo); /*!< in: speedo */
#endif /* UNIV_COMPILE_TEST_FUNCS */
diff --git a/storage/xtradb/include/ut0list.h b/storage/xtradb/include/ut0list.h
index 034aa400af9..ec67f4e2a0f 100644
--- a/storage/xtradb/include/ut0list.h
+++ b/storage/xtradb/include/ut0list.h
@@ -16,7 +16,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/ut0list.h
+A double-linked list
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
+/*******************************************************************//**
A double-linked list. This differs from the one in ut0lst.h in that in this
one, each list node contains a pointer to the data, whereas the one in
ut0lst.h uses a strategy where the list pointers are embedded in the data
@@ -45,117 +52,117 @@ typedef struct ib_list_struct ib_list_t;
typedef struct ib_list_node_struct ib_list_node_t;
typedef struct ib_list_helper_struct ib_list_helper_t;
-/********************************************************************
+/****************************************************************//**
Create a new list using mem_alloc. Lists created with this function must be
-freed with ib_list_free. */
+freed with ib_list_free.
+@return list */
UNIV_INTERN
ib_list_t*
ib_list_create(void);
/*=================*/
- /* out: list */
-/********************************************************************
+/****************************************************************//**
Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
-lists created with this function. */
+lists created with this function.
+@return list */
UNIV_INTERN
ib_list_t*
ib_list_create_heap(
/*================*/
- /* out: list */
- mem_heap_t* heap); /* in: memory heap to use */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/********************************************************************
+/****************************************************************//**
Free a list. */
UNIV_INTERN
void
ib_list_free(
/*=========*/
- ib_list_t* list); /* in: list */
+ ib_list_t* list); /*!< in: list */
-/********************************************************************
-Add the data to the start of the list. */
+/****************************************************************//**
+Add the data to the start of the list.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_first(
/*==============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- void* data, /* in: data */
- mem_heap_t* heap); /* in: memory heap to use */
+ ib_list_t* list, /*!< in: list */
+ void* data, /*!< in: data */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/********************************************************************
-Add the data to the end of the list. */
+/****************************************************************//**
+Add the data to the end of the list.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_last(
/*=============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- void* data, /* in: data */
- mem_heap_t* heap); /* in: memory heap to use */
+ ib_list_t* list, /*!< in: list */
+ void* data, /*!< in: data */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/********************************************************************
-Add the data after the indicated node. */
+/****************************************************************//**
+Add the data after the indicated node.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_after(
/*==============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- ib_list_node_t* prev_node, /* in: node preceding new node (can
+ ib_list_t* list, /*!< in: list */
+ ib_list_node_t* prev_node, /*!< in: node preceding new node (can
be NULL) */
- void* data, /* in: data */
- mem_heap_t* heap); /* in: memory heap to use */
+ void* data, /*!< in: data */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/********************************************************************
+/****************************************************************//**
Remove the node from the list. */
UNIV_INTERN
void
ib_list_remove(
/*===========*/
- ib_list_t* list, /* in: list */
- ib_list_node_t* node); /* in: node to remove */
+ ib_list_t* list, /*!< in: list */
+ ib_list_node_t* node); /*!< in: node to remove */
-/********************************************************************
-Get the first node in the list. */
+/****************************************************************//**
+Get the first node in the list.
+@return first node, or NULL */
UNIV_INLINE
ib_list_node_t*
ib_list_get_first(
/*==============*/
- /* out: first node, or NULL */
- ib_list_t* list); /* in: list */
+ ib_list_t* list); /*!< in: list */
-/********************************************************************
-Get the last node in the list. */
+/****************************************************************//**
+Get the last node in the list.
+@return last node, or NULL */
UNIV_INLINE
ib_list_node_t*
ib_list_get_last(
/*=============*/
- /* out: last node, or NULL */
- ib_list_t* list); /* in: list */
+ ib_list_t* list); /*!< in: list */
/* List. */
struct ib_list_struct {
- ib_list_node_t* first; /* first node */
- ib_list_node_t* last; /* last node */
- ibool is_heap_list; /* TRUE if this list was
+ ib_list_node_t* first; /*!< first node */
+ ib_list_node_t* last; /*!< last node */
+ ibool is_heap_list; /*!< TRUE if this list was
allocated through a heap */
};
/* A list node. */
struct ib_list_node_struct {
- ib_list_node_t* prev; /* previous node */
- ib_list_node_t* next; /* next node */
- void* data; /* user data */
+ ib_list_node_t* prev; /*!< previous node */
+ ib_list_node_t* next; /*!< next node */
+ void* data; /*!< user data */
};
/* Quite often, the only additional piece of data you need is the per-item
memory heap, so we have this generic struct available to use in those
cases. */
struct ib_list_helper_struct {
- mem_heap_t* heap; /* memory heap */
- void* data; /* user data */
+ mem_heap_t* heap; /*!< memory heap */
+ void* data; /*!< user data */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/ut0list.ic b/storage/xtradb/include/ut0list.ic
index c79a0cf18dc..eb5c62796e8 100644
--- a/storage/xtradb/include/ut0list.ic
+++ b/storage/xtradb/include/ut0list.ic
@@ -16,26 +16,33 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/********************************************************************
-Get the first node in the list. */
+/*******************************************************************//**
+@file include/ut0list.ic
+A double-linked list
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
+/****************************************************************//**
+Get the first node in the list.
+@return first node, or NULL */
UNIV_INLINE
ib_list_node_t*
ib_list_get_first(
/*==============*/
- /* out: first node, or NULL */
- ib_list_t* list) /* in: list */
+ ib_list_t* list) /*!< in: list */
{
return(list->first);
}
-/********************************************************************
-Get the last node in the list. */
+/****************************************************************//**
+Get the last node in the list.
+@return last node, or NULL */
UNIV_INLINE
ib_list_node_t*
ib_list_get_last(
/*=============*/
- /* out: last node, or NULL */
- ib_list_t* list) /* in: list */
+ ib_list_t* list) /*!< in: list */
{
return(list->last);
}
diff --git a/storage/xtradb/include/ut0lst.h b/storage/xtradb/include/ut0lst.h
index 46ee23a2538..261d33963dc 100644
--- a/storage/xtradb/include/ut0lst.h
+++ b/storage/xtradb/include/ut0lst.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0lst.h
List utilities
Created 9/10/1995 Heikki Tuuri
@@ -32,45 +33,46 @@ if a list is used in the database. Note that a single struct may belong
to two or more lists, provided that the list are given different names.
An example of the usage of the lists can be found in fil0fil.c. */
-/***********************************************************************
+/*******************************************************************//**
This macro expands to the unnamed type definition of a struct which acts
as the two-way list base node. The base node contains pointers
to both ends of the list and a count of nodes in the list (excluding
-the base node from the count). TYPE should be the list node type name. */
-
+the base node from the count).
+@param TYPE the name of the list node data type */
#define UT_LIST_BASE_NODE_T(TYPE)\
struct {\
- ulint count; /* count of nodes in list */\
- TYPE * start; /* pointer to list start, NULL if empty */\
- TYPE * end; /* pointer to list end, NULL if empty */\
+ ulint count; /*!< count of nodes in list */\
+ TYPE * start; /*!< pointer to list start, NULL if empty */\
+ TYPE * end; /*!< pointer to list end, NULL if empty */\
}\
-/***********************************************************************
+/*******************************************************************//**
This macro expands to the unnamed type definition of a struct which
should be embedded in the nodes of the list, the node type must be a struct.
This struct contains the pointers to next and previous nodes in the list.
The name of the field in the node struct should be the name given
-to the list. TYPE should be the list node type name. Example of usage:
-
+to the list.
+@param TYPE the list node type name */
+/* Example:
typedef struct LRU_node_struct LRU_node_t;
struct LRU_node_struct {
UT_LIST_NODE_T(LRU_node_t) LRU_list;
...
}
The example implements an LRU list of name LRU_list. Its nodes are of type
-LRU_node_t.
-*/
+LRU_node_t. */
#define UT_LIST_NODE_T(TYPE)\
struct {\
- TYPE * prev; /* pointer to the previous node,\
+ TYPE * prev; /*!< pointer to the previous node,\
NULL if start of list */\
- TYPE * next; /* pointer to next node, NULL if end of list */\
+ TYPE * next; /*!< pointer to next node, NULL if end of list */\
}\
-/***********************************************************************
-Initializes the base node of a two-way list. */
-
+/*******************************************************************//**
+Initializes the base node of a two-way list.
+@param BASE the list base node
+*/
#define UT_LIST_INIT(BASE)\
{\
(BASE).count = 0;\
@@ -78,11 +80,12 @@ Initializes the base node of a two-way list. */
(BASE).end = NULL;\
}\
-/***********************************************************************
+/*******************************************************************//**
Adds the node as the first element in a two-way linked list.
-BASE has to be the base node (not a pointer to it). N has to be
-the pointer to the node to be added to the list. NAME is the list name. */
-
+@param NAME list name
+@param BASE the base node (not a pointer to it)
+@param N pointer to the node to be added to the list.
+*/
#define UT_LIST_ADD_FIRST(NAME, BASE, N)\
{\
ut_ad(N);\
@@ -99,11 +102,12 @@ the pointer to the node to be added to the list. NAME is the list name. */
}\
}\
-/***********************************************************************
+/*******************************************************************//**
Adds the node as the last element in a two-way linked list.
-BASE has to be the base node (not a pointer to it). N has to be
-the pointer to the node to be added to the list. NAME is the list name. */
-
+@param NAME list name
+@param BASE the base node (not a pointer to it)
+@param N pointer to the node to be added to the list
+*/
#define UT_LIST_ADD_LAST(NAME, BASE, N)\
{\
ut_ad(N);\
@@ -120,11 +124,13 @@ the pointer to the node to be added to the list. NAME is the list name. */
}\
}\
-/***********************************************************************
+/*******************************************************************//**
Inserts a NODE2 after NODE1 in a list.
-BASE has to be the base node (not a pointer to it). NAME is the list
-name, NODE1 and NODE2 are pointers to nodes. */
-
+@param NAME list name
+@param BASE the base node (not a pointer to it)
+@param NODE1 pointer to node after which NODE2 is inserted
+@param NODE2 pointer to node being inserted after NODE1
+*/
#define UT_LIST_INSERT_AFTER(NAME, BASE, NODE1, NODE2)\
{\
ut_ad(NODE1);\
@@ -142,19 +148,25 @@ name, NODE1 and NODE2 are pointers to nodes. */
}\
}\
-/* Invalidate the pointers in a list node. */
#ifdef UNIV_LIST_DEBUG
+/** Invalidate the pointers in a list node.
+@param NAME list name
+@param N pointer to the node that was removed */
# define UT_LIST_REMOVE_CLEAR(NAME, N) \
((N)->NAME.prev = (N)->NAME.next = (void*) -1)
#else
+/** Invalidate the pointers in a list node.
+@param NAME list name
+@param N pointer to the node that was removed */
# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0)
#endif
-/***********************************************************************
-Removes a node from a two-way linked list. BASE has to be the base node
-(not a pointer to it). N has to be the pointer to the node to be removed
-from the list. NAME is the list name. */
-
+/*******************************************************************//**
+Removes a node from a two-way linked list.
+@param NAME list name
+@param BASE the base node (not a pointer to it)
+@param N pointer to the node to be removed from the list
+*/
#define UT_LIST_REMOVE(NAME, BASE, N) \
do { \
ut_ad(N); \
@@ -173,71 +185,77 @@ do { \
UT_LIST_REMOVE_CLEAR(NAME, N); \
} while (0)
-/************************************************************************
-Gets the next node in a two-way list. NAME is the name of the list
-and N is pointer to a node. */
-
+/********************************************************************//**
+Gets the next node in a two-way list.
+@param NAME list name
+@param N pointer to a node
+@return the successor of N in NAME, or NULL */
#define UT_LIST_GET_NEXT(NAME, N)\
(((N)->NAME).next)
-/************************************************************************
-Gets the previous node in a two-way list. NAME is the name of the list
-and N is pointer to a node. */
-
+/********************************************************************//**
+Gets the previous node in a two-way list.
+@param NAME list name
+@param N pointer to a node
+@return the predecessor of N in NAME, or NULL */
#define UT_LIST_GET_PREV(NAME, N)\
(((N)->NAME).prev)
-/************************************************************************
+/********************************************************************//**
Alternative macro to get the number of nodes in a two-way list, i.e.,
-its length. BASE is the base node (not a pointer to it). */
-
+its length.
+@param BASE the base node (not a pointer to it).
+@return the number of nodes in the list */
#define UT_LIST_GET_LEN(BASE)\
(BASE).count
-/************************************************************************
-Gets the first node in a two-way list, or returns NULL,
-if the list is empty. BASE is the base node (not a pointer to it). */
-
+/********************************************************************//**
+Gets the first node in a two-way list.
+@param BASE the base node (not a pointer to it)
+@return first node, or NULL if the list is empty */
#define UT_LIST_GET_FIRST(BASE)\
(BASE).start
-/************************************************************************
-Gets the last node in a two-way list, or returns NULL,
-if the list is empty. BASE is the base node (not a pointer to it). */
-
+/********************************************************************//**
+Gets the last node in a two-way list.
+@param BASE the base node (not a pointer to it)
+@return last node, or NULL if the list is empty */
#define UT_LIST_GET_LAST(BASE)\
(BASE).end
-/************************************************************************
-Checks the consistency of a two-way list. NAME is the name of the list,
-TYPE is the node type, and BASE is the base node (not a pointer to it). */
-
-#define UT_LIST_VALIDATE(NAME, TYPE, BASE)\
-{\
- ulint ut_list_i_313;\
- TYPE * ut_list_node_313;\
-\
- ut_list_node_313 = (BASE).start;\
-\
- for (ut_list_i_313 = 0; ut_list_i_313 < (BASE).count;\
- ut_list_i_313++) {\
- ut_a(ut_list_node_313);\
- ut_list_node_313 = (ut_list_node_313->NAME).next;\
- }\
-\
- ut_a(ut_list_node_313 == NULL);\
-\
- ut_list_node_313 = (BASE).end;\
-\
- for (ut_list_i_313 = 0; ut_list_i_313 < (BASE).count;\
- ut_list_i_313++) {\
- ut_a(ut_list_node_313);\
- ut_list_node_313 = (ut_list_node_313->NAME).prev;\
- }\
-\
- ut_a(ut_list_node_313 == NULL);\
-}\
-
+/********************************************************************//**
+Checks the consistency of a two-way list.
+@param NAME the name of the list
+@param TYPE node type
+@param BASE base node (not a pointer to it)
+@param ASSERTION a condition on ut_list_node_313 */
+#define UT_LIST_VALIDATE(NAME, TYPE, BASE, ASSERTION) \
+do { \
+ ulint ut_list_i_313; \
+ TYPE* ut_list_node_313; \
+ \
+ ut_list_node_313 = (BASE).start; \
+ \
+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
+ ut_a(ut_list_node_313); \
+ ASSERTION; \
+ ut_ad((ut_list_node_313->NAME).next || !ut_list_i_313); \
+ ut_list_node_313 = (ut_list_node_313->NAME).next; \
+ } \
+ \
+ ut_a(ut_list_node_313 == NULL); \
+ \
+ ut_list_node_313 = (BASE).end; \
+ \
+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
+ ut_a(ut_list_node_313); \
+ ASSERTION; \
+ ut_ad((ut_list_node_313->NAME).prev || !ut_list_i_313); \
+ ut_list_node_313 = (ut_list_node_313->NAME).prev; \
+ } \
+ \
+ ut_a(ut_list_node_313 == NULL); \
+} while (0)
#endif
diff --git a/storage/xtradb/include/ut0mem.h b/storage/xtradb/include/ut0mem.h
index f8dec99ed4a..cf41cba4643 100644
--- a/storage/xtradb/include/ut0mem.h
+++ b/storage/xtradb/include/ut0mem.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/ut0mem.h
Memory primitives
Created 5/30/1994 Heikki Tuuri
@@ -26,77 +27,100 @@ Created 5/30/1994 Heikki Tuuri
#define ut0mem_h
#include "univ.i"
-#include "os0sync.h"
#include <string.h>
+#ifndef UNIV_HOTBACKUP
+# include "os0sync.h"
-/* The total amount of memory currently allocated from the operating
+/** The total amount of memory currently allocated from the operating
system with os_mem_alloc_large() or malloc(). Does not count malloc()
if srv_use_sys_malloc is set. Protected by ut_list_mutex. */
extern ulint ut_total_allocated_memory;
-/* Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
+/** Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
extern os_fast_mutex_t ut_list_mutex;
-
+#endif /* !UNIV_HOTBACKUP */
+
+/** Wrapper for memcpy(3). Copy memory area when the source and
+target are not overlapping.
+* @param dest in: copy to
+* @param sour in: copy from
+* @param n in: number of bytes to copy
+* @return dest */
UNIV_INLINE
void*
ut_memcpy(void* dest, const void* sour, ulint n);
+/** Wrapper for memmove(3). Copy memory area when the source and
+target are overlapping.
+* @param dest in: copy to
+* @param sour in: copy from
+* @param n in: number of bytes to copy
+* @return dest */
UNIV_INLINE
void*
ut_memmove(void* dest, const void* sour, ulint n);
+/** Wrapper for memcmp(3). Compare memory areas.
+* @param str1 in: first memory block to compare
+* @param str2 in: second memory block to compare
+* @param n in: number of bytes to compare
+* @return negative, 0, or positive if str1 is smaller, equal,
+ or greater than str2, respectively. */
UNIV_INLINE
int
ut_memcmp(const void* str1, const void* str2, ulint n);
-/**************************************************************************
+/**********************************************************************//**
Initializes the mem block list at database startup. */
UNIV_INTERN
void
ut_mem_init(void);
/*=============*/
-/**************************************************************************
+/**********************************************************************//**
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
-defined and set_to_zero is TRUE. */
+defined and set_to_zero is TRUE.
+@return own: allocated memory */
UNIV_INTERN
void*
ut_malloc_low(
/*==========*/
- /* out, own: allocated memory */
- ulint n, /* in: number of bytes to allocate */
- ibool set_to_zero, /* in: TRUE if allocated memory
+ ulint n, /*!< in: number of bytes to allocate */
+ ibool set_to_zero, /*!< in: TRUE if allocated memory
should be set to zero if
UNIV_SET_MEM_TO_ZERO is defined */
- ibool assert_on_error); /* in: if TRUE, we crash mysqld if
+ ibool assert_on_error); /*!< in: if TRUE, we crash mysqld if
the memory cannot be allocated */
-/**************************************************************************
+/**********************************************************************//**
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
-defined. */
+defined.
+@return own: allocated memory */
UNIV_INTERN
void*
ut_malloc(
/*======*/
- /* out, own: allocated memory */
- ulint n); /* in: number of bytes to allocate */
-/**************************************************************************
+ ulint n); /*!< in: number of bytes to allocate */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs
out. It cannot be used if we want to return an error message. Prints to
-stderr a message if fails. */
+stderr a message if fails.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
ut_test_malloc(
/*===========*/
- /* out: TRUE if succeeded */
- ulint n); /* in: try to allocate this many bytes */
-/**************************************************************************
+ ulint n); /*!< in: try to allocate this many bytes */
+#endif /* !UNIV_HOTBACKUP */
+/**********************************************************************//**
Frees a memory block allocated with ut_malloc. */
UNIV_INTERN
void
ut_free(
/*====*/
- void* ptr); /* in, own: memory block */
-/**************************************************************************
+ void* ptr); /*!< in, own: memory block */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not
use this function because the allocation functions in mem0mem.h are the
recommended ones in InnoDB.
@@ -119,149 +143,160 @@ RETURN VALUE
size was equal to 0, either NULL or a pointer suitable to
be passed to free() is returned. If realloc() fails the
original block is left untouched - it is not freed or
- moved. */
+ moved.
+@return own: pointer to new mem block or NULL */
UNIV_INTERN
void*
ut_realloc(
/*=======*/
- /* out, own: pointer to new mem block or NULL */
- void* ptr, /* in: pointer to old block or NULL */
- ulint size); /* in: desired size */
-/**************************************************************************
+ void* ptr, /*!< in: pointer to old block or NULL */
+ ulint size); /*!< in: desired size */
+/**********************************************************************//**
Frees in shutdown all allocated memory not freed yet. */
UNIV_INTERN
void
ut_free_all_mem(void);
/*=================*/
+#endif /* !UNIV_HOTBACKUP */
+/** Wrapper for strcpy(3). Copy a NUL-terminated string.
+* @param dest in: copy to
+* @param sour in: copy from
+* @return dest */
UNIV_INLINE
char*
ut_strcpy(char* dest, const char* sour);
+/** Wrapper for strlen(3). Determine the length of a NUL-terminated string.
+* @param str in: string
+* @return length of the string in bytes, excluding the terminating NUL */
UNIV_INLINE
ulint
ut_strlen(const char* str);
+/** Wrapper for strcmp(3). Compare NUL-terminated strings.
+* @param str1 in: first string to compare
+* @param str2 in: second string to compare
+* @return negative, 0, or positive if str1 is smaller, equal,
+ or greater than str2, respectively. */
UNIV_INLINE
int
ut_strcmp(const char* str1, const char* str2);
-/**************************************************************************
+/**********************************************************************//**
Copies up to size - 1 characters from the NUL-terminated string src to
dst, NUL-terminating the result. Returns strlen(src), so truncation
-occurred if the return value >= size. */
+occurred if the return value >= size.
+@return strlen(src) */
UNIV_INTERN
ulint
ut_strlcpy(
/*=======*/
- /* out: strlen(src) */
- char* dst, /* in: destination buffer */
- const char* src, /* in: source buffer */
- ulint size); /* in: size of destination buffer */
+ char* dst, /*!< in: destination buffer */
+ const char* src, /*!< in: source buffer */
+ ulint size); /*!< in: size of destination buffer */
-/**************************************************************************
+/**********************************************************************//**
Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
-(size - 1) bytes of src, not the first. */
+(size - 1) bytes of src, not the first.
+@return strlen(src) */
UNIV_INTERN
ulint
ut_strlcpy_rev(
/*===========*/
- /* out: strlen(src) */
- char* dst, /* in: destination buffer */
- const char* src, /* in: source buffer */
- ulint size); /* in: size of destination buffer */
+ char* dst, /*!< in: destination buffer */
+ const char* src, /*!< in: source buffer */
+ ulint size); /*!< in: size of destination buffer */
-/**************************************************************************
-Compute strlen(ut_strcpyq(str, q)). */
+/**********************************************************************//**
+Compute strlen(ut_strcpyq(str, q)).
+@return length of the string when quoted */
UNIV_INLINE
ulint
ut_strlenq(
/*=======*/
- /* out: length of the string when quoted */
- const char* str, /* in: null-terminated string */
- char q); /* in: the quote character */
+ const char* str, /*!< in: null-terminated string */
+ char q); /*!< in: the quote character */
-/**************************************************************************
+/**********************************************************************//**
Make a quoted copy of a NUL-terminated string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
-See also ut_strlenq() and ut_memcpyq(). */
+See also ut_strlenq() and ut_memcpyq().
+@return pointer to end of dest */
UNIV_INTERN
char*
ut_strcpyq(
/*=======*/
- /* out: pointer to end of dest */
- char* dest, /* in: output buffer */
- char q, /* in: the quote character */
- const char* src); /* in: null-terminated string */
+ char* dest, /*!< in: output buffer */
+ char q, /*!< in: the quote character */
+ const char* src); /*!< in: null-terminated string */
-/**************************************************************************
+/**********************************************************************//**
Make a quoted copy of a fixed-length string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
-See also ut_strlenq() and ut_strcpyq(). */
+See also ut_strlenq() and ut_strcpyq().
+@return pointer to end of dest */
UNIV_INTERN
char*
ut_memcpyq(
/*=======*/
- /* out: pointer to end of dest */
- char* dest, /* in: output buffer */
- char q, /* in: the quote character */
- const char* src, /* in: string to be quoted */
- ulint len); /* in: length of src */
+ char* dest, /*!< in: output buffer */
+ char q, /*!< in: the quote character */
+ const char* src, /*!< in: string to be quoted */
+ ulint len); /*!< in: length of src */
-/**************************************************************************
+/**********************************************************************//**
Return the number of times s2 occurs in s1. Overlapping instances of s2
-are only counted once. */
+are only counted once.
+@return the number of times s2 occurs in s1 */
UNIV_INTERN
ulint
ut_strcount(
/*========*/
- /* out: the number of times s2 occurs in s1 */
- const char* s1, /* in: string to search in */
- const char* s2); /* in: string to search for */
+ const char* s1, /*!< in: string to search in */
+ const char* s2); /*!< in: string to search for */
-/**************************************************************************
+/**********************************************************************//**
Replace every occurrence of s1 in str with s2. Overlapping instances of s1
-are only replaced once. */
+are only replaced once.
+@return own: modified string, must be freed with mem_free() */
UNIV_INTERN
char*
ut_strreplace(
/*==========*/
- /* out, own: modified string, must be
- freed with mem_free() */
- const char* str, /* in: string to operate on */
- const char* s1, /* in: string to replace */
- const char* s2); /* in: string to replace s1 with */
-
-/**************************************************************************
-Converts a raw binary data to a '\0'-terminated hex string. The output is
+ const char* str, /*!< in: string to operate on */
+ const char* s1, /*!< in: string to replace */
+ const char* s2); /*!< in: string to replace s1 with */
+
+/**********************************************************************//**
+Converts a raw binary data to a NUL-terminated hex string. The output is
truncated if there is not enough space in "hex", make sure "hex_size" is at
least (2 * raw_size + 1) if you do not want this to happen. Returns the
-actual number of characters written to "hex" (including the '\0'). */
+actual number of characters written to "hex" (including the NUL).
+@return number of chars written */
UNIV_INLINE
ulint
ut_raw_to_hex(
/*==========*/
- /* out: number of chars written */
- const void* raw, /* in: raw data */
- ulint raw_size, /* in: "raw" length in bytes */
- char* hex, /* out: hex string */
- ulint hex_size); /* in: "hex" size in bytes */
+ const void* raw, /*!< in: raw data */
+ ulint raw_size, /*!< in: "raw" length in bytes */
+ char* hex, /*!< out: hex string */
+ ulint hex_size); /*!< in: "hex" size in bytes */
-/***********************************************************************
+/*******************************************************************//**
Adds single quotes to the start and end of string and escapes any quotes
by doubling them. Returns the number of bytes that were written to "buf"
-(including the terminating '\0'). If buf_size is too small then the
-trailing bytes from "str" are discarded. */
+(including the terminating NUL). If buf_size is too small then the
+trailing bytes from "str" are discarded.
+@return number of bytes that were written */
UNIV_INLINE
ulint
ut_str_sql_format(
/*==============*/
- /* out: number of bytes
- that were written */
- const char* str, /* in: string */
- ulint str_len, /* in: string length in bytes */
- char* buf, /* out: output buffer */
- ulint buf_size); /* in: output buffer size
+ const char* str, /*!< in: string */
+ ulint str_len, /*!< in: string length in bytes */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size); /*!< in: output buffer size
in bytes */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/ut0mem.ic b/storage/xtradb/include/ut0mem.ic
index 5078c721706..f36c28f1989 100644
--- a/storage/xtradb/include/ut0mem.ic
+++ b/storage/xtradb/include/ut0mem.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/ut0mem.ic
Memory primitives
Created 5/30/1994 Heikki Tuuri
@@ -25,6 +26,12 @@ Created 5/30/1994 Heikki Tuuri
#include "ut0byte.h"
#include "mach0data.h"
+/** Wrapper for memcpy(3). Copy memory area when the source and
+target are not overlapping.
+* @param dest in: copy to
+* @param sour in: copy from
+* @param n in: number of bytes to copy
+* @return dest */
UNIV_INLINE
void*
ut_memcpy(void* dest, const void* sour, ulint n)
@@ -32,6 +39,12 @@ ut_memcpy(void* dest, const void* sour, ulint n)
return(memcpy(dest, sour, n));
}
+/** Wrapper for memmove(3). Copy memory area when the source and
+target are overlapping.
+* @param dest in: copy to
+* @param sour in: copy from
+* @param n in: number of bytes to copy
+* @return dest */
UNIV_INLINE
void*
ut_memmove(void* dest, const void* sour, ulint n)
@@ -39,6 +52,12 @@ ut_memmove(void* dest, const void* sour, ulint n)
return(memmove(dest, sour, n));
}
+/** Wrapper for memcmp(3). Compare memory areas.
+* @param str1 in: first memory block to compare
+* @param str2 in: second memory block to compare
+* @param n in: number of bytes to compare
+* @return negative, 0, or positive if str1 is smaller, equal,
+ or greater than str2, respectively. */
UNIV_INLINE
int
ut_memcmp(const void* str1, const void* str2, ulint n)
@@ -46,6 +65,10 @@ ut_memcmp(const void* str1, const void* str2, ulint n)
return(memcmp(str1, str2, n));
}
+/** Wrapper for strcpy(3). Copy a NUL-terminated string.
+* @param dest in: copy to
+* @param sour in: copy from
+* @return dest */
UNIV_INLINE
char*
ut_strcpy(char* dest, const char* sour)
@@ -53,6 +76,9 @@ ut_strcpy(char* dest, const char* sour)
return(strcpy(dest, sour));
}
+/** Wrapper for strlen(3). Determine the length of a NUL-terminated string.
+* @param str in: string
+* @return length of the string in bytes, excluding the terminating NUL */
UNIV_INLINE
ulint
ut_strlen(const char* str)
@@ -60,6 +86,11 @@ ut_strlen(const char* str)
return(strlen(str));
}
+/** Wrapper for strcmp(3). Compare NUL-terminated strings.
+* @param str1 in: first string to compare
+* @param str2 in: second string to compare
+* @return negative, 0, or positive if str1 is smaller, equal,
+ or greater than str2, respectively. */
UNIV_INLINE
int
ut_strcmp(const char* str1, const char* str2)
@@ -67,15 +98,15 @@ ut_strcmp(const char* str1, const char* str2)
return(strcmp(str1, str2));
}
-/**************************************************************************
-Compute strlen(ut_strcpyq(str, q)). */
+/**********************************************************************//**
+Compute strlen(ut_strcpyq(str, q)).
+@return length of the string when quoted */
UNIV_INLINE
ulint
ut_strlenq(
/*=======*/
- /* out: length of the string when quoted */
- const char* str, /* in: null-terminated string */
- char q) /* in: the quote character */
+ const char* str, /*!< in: null-terminated string */
+ char q) /*!< in: the quote character */
{
ulint len;
@@ -88,20 +119,20 @@ ut_strlenq(
return(len);
}
-/**************************************************************************
-Converts a raw binary data to a '\0'-terminated hex string. The output is
+/**********************************************************************//**
+Converts a raw binary data to a NUL-terminated hex string. The output is
truncated if there is not enough space in "hex", make sure "hex_size" is at
least (2 * raw_size + 1) if you do not want this to happen. Returns the
-actual number of characters written to "hex" (including the '\0'). */
+actual number of characters written to "hex" (including the NUL).
+@return number of chars written */
UNIV_INLINE
ulint
ut_raw_to_hex(
/*==========*/
- /* out: number of chars written */
- const void* raw, /* in: raw data */
- ulint raw_size, /* in: "raw" length in bytes */
- char* hex, /* out: hex string */
- ulint hex_size) /* in: "hex" size in bytes */
+ const void* raw, /*!< in: raw data */
+ ulint raw_size, /*!< in: "raw" length in bytes */
+ char* hex, /*!< out: hex string */
+ ulint hex_size) /*!< in: "hex" size in bytes */
{
#ifdef WORDS_BIGENDIAN
@@ -208,21 +239,20 @@ ut_raw_to_hex(
return(write_bytes);
}
-/***********************************************************************
+/*******************************************************************//**
Adds single quotes to the start and end of string and escapes any quotes
by doubling them. Returns the number of bytes that were written to "buf"
-(including the terminating '\0'). If buf_size is too small then the
-trailing bytes from "str" are discarded. */
+(including the terminating NUL). If buf_size is too small then the
+trailing bytes from "str" are discarded.
+@return number of bytes that were written */
UNIV_INLINE
ulint
ut_str_sql_format(
/*==============*/
- /* out: number of bytes
- that were written */
- const char* str, /* in: string */
- ulint str_len, /* in: string length in bytes */
- char* buf, /* out: output buffer */
- ulint buf_size) /* in: output buffer size
+ const char* str, /*!< in: string */
+ ulint str_len, /*!< in: string length in bytes */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size) /*!< in: output buffer size
in bytes */
{
ulint str_i;
diff --git a/storage/xtradb/include/ut0rnd.h b/storage/xtradb/include/ut0rnd.h
index b9e23d7cd14..ce5152e942f 100644
--- a/storage/xtradb/include/ut0rnd.h
+++ b/storage/xtradb/include/ut0rnd.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0rnd.h
Random numbers and hashing
Created 1/20/1994 Heikki Tuuri
@@ -29,109 +30,109 @@ Created 1/20/1994 Heikki Tuuri
#include "ut0byte.h"
-/* The 'character code' for end of field or string (used
+/** 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. */
+ 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(
/*==================*/
- /* out: the next 'random' number */
- ulint rnd); /* in: the previous random number value */
-/*************************************************************
+ 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. */
+always after N calls to the generator.
+@return the 'random' number */
UNIV_INLINE
ulint
ut_rnd_gen_ulint(void);
/*==================*/
- /* out: the 'random' number */
-/************************************************************
-Generates a random integer from a given interval. */
+/********************************************************//**
+Generates a random integer from a given interval.
+@return the 'random' number */
UNIV_INLINE
ulint
ut_rnd_interval(
/*============*/
- /* out: the 'random' number */
- ulint low, /* in: low limit; can generate also this value */
- ulint high); /* in: high limit; can generate also this value */
-/*************************************************************
-Generates a random iboolean value. */
+ ulint low, /*!< in: low limit; can generate also this value */
+ ulint high); /*!< in: high limit; can generate also this value */
+/*********************************************************//**
+Generates a random iboolean value.
+@return the random value */
UNIV_INLINE
ibool
ut_rnd_gen_ibool(void);
/*=================*/
- /* out: the random value */
-/***********************************************************
+/*******************************************************//**
The following function generates a hash value for a ulint integer
to a hash table of size table_size, which should be a prime or some
-random number to work reliably. */
+random number to work reliably.
+@return hash value */
UNIV_INLINE
ulint
ut_hash_ulint(
/*==========*/
- /* out: hash value */
- ulint key, /* in: value to be hashed */
- ulint table_size); /* in: hash table size */
-/*****************************************************************
-Folds a pair of ulints. */
+ ulint key, /*!< in: value to be hashed */
+ ulint table_size); /*!< in: hash table size */
+/*************************************************************//**
+Folds a pair of ulints.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_ulint_pair(
/*===============*/
- /* out: folded value */
- ulint n1, /* in: ulint */
- ulint n2) /* in: ulint */
+ ulint n1, /*!< in: ulint */
+ ulint n2) /*!< in: ulint */
__attribute__((const));
-/*****************************************************************
-Folds a dulint. */
+/*************************************************************//**
+Folds a dulint.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_dulint(
/*===========*/
- /* out: folded value */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
__attribute__((const));
-/*****************************************************************
-Folds a character string ending in the null character. */
+/*************************************************************//**
+Folds a character string ending in the null character.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_string(
/*===========*/
- /* out: folded value */
- const char* str) /* in: null-terminated string */
+ const char* str) /*!< in: null-terminated string */
__attribute__((pure));
-/*****************************************************************
-Folds a binary string. */
+/*************************************************************//**
+Folds a binary string.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_binary(
/*===========*/
- /* out: folded value */
- const byte* str, /* in: string of bytes */
- ulint len) /* in: length */
+ const byte* str, /*!< in: string of bytes */
+ ulint len) /*!< in: length */
__attribute__((pure));
-/***************************************************************
+/***********************************************************//**
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. */
+The prime is chosen so that it is not near any power of 2.
+@return prime */
UNIV_INTERN
ulint
ut_find_prime(
/*==========*/
- /* out: prime */
- ulint n) /* in: positive number > 100 */
+ ulint n) /*!< in: positive number > 100 */
__attribute__((const));
diff --git a/storage/xtradb/include/ut0rnd.ic b/storage/xtradb/include/ut0rnd.ic
index d72100d16a1..763469142ec 100644
--- a/storage/xtradb/include/ut0rnd.ic
+++ b/storage/xtradb/include/ut0rnd.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************************
+/**************************************************************//**
+@file include/ut0rnd.ic
Random numbers and hashing
Created 5/30/1994 Heikki Tuuri
@@ -34,27 +35,28 @@ Created 5/30/1994 Heikki Tuuri
#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 */
+ ulint seed) /*!< in: seed */
{
ut_rnd_ulint_counter = seed;
}
-/************************************************************
-The following function generates a series of 'random' ulint integers. */
+/********************************************************//**
+The following function generates a series of 'random' ulint integers.
+@return the next 'random' number */
UNIV_INLINE
ulint
ut_rnd_gen_next_ulint(
/*==================*/
- /* out: the next 'random' number */
- ulint rnd) /* in: the previous random number value */
+ ulint rnd) /*!< in: the previous random number value */
{
ulint n_bits;
@@ -71,16 +73,16 @@ ut_rnd_gen_next_ulint(
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). */
+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)
/*==================*/
- /* out: the 'random' number */
{
ulint rnd;
ulint n_bits;
@@ -94,15 +96,15 @@ ut_rnd_gen_ulint(void)
return(rnd);
}
-/************************************************************
-Generates a random integer from a given interval. */
+/********************************************************//**
+Generates a random integer from a given interval.
+@return the 'random' number */
UNIV_INLINE
ulint
ut_rnd_interval(
/*============*/
- /* out: the 'random' number */
- ulint low, /* in: low limit; can generate also this value */
- ulint high) /* in: high limit; can generate also this value */
+ ulint low, /*!< in: low limit; can generate also this value */
+ ulint high) /*!< in: high limit; can generate also this value */
{
ulint rnd;
@@ -118,13 +120,13 @@ ut_rnd_interval(
return(low + (rnd % (high - low + 1)));
}
-/*************************************************************
-Generates a random iboolean value. */
+/*********************************************************//**
+Generates a random iboolean value.
+@return the random value */
UNIV_INLINE
ibool
ut_rnd_gen_ibool(void)
/*=================*/
- /* out: the random value */
{
ulint x;
@@ -138,58 +140,58 @@ ut_rnd_gen_ibool(void)
return(FALSE);
}
-/***********************************************************
+/*******************************************************//**
The following function generates a hash value for a ulint integer
to a hash table of size table_size, which should be a prime
-or some random number for the hash table to work reliably. */
+or some random number for the hash table to work reliably.
+@return hash value */
UNIV_INLINE
ulint
ut_hash_ulint(
/*==========*/
- /* out: hash value */
- ulint key, /* in: value to be hashed */
- ulint table_size) /* in: hash table size */
+ ulint key, /*!< in: value to be hashed */
+ ulint table_size) /*!< in: hash table size */
{
key = key ^ UT_HASH_RANDOM_MASK2;
return(key % table_size);
}
-/*****************************************************************
-Folds a pair of ulints. */
+/*************************************************************//**
+Folds a pair of ulints.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_ulint_pair(
/*===============*/
- /* out: folded value */
- ulint n1, /* in: ulint */
- ulint n2) /* in: ulint */
+ ulint n1, /*!< in: ulint */
+ ulint n2) /*!< in: ulint */
{
return(((((n1 ^ n2 ^ UT_HASH_RANDOM_MASK2) << 8) + n1)
^ UT_HASH_RANDOM_MASK) + n2);
}
-/*****************************************************************
-Folds a dulint. */
+/*************************************************************//**
+Folds a dulint.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_dulint(
/*===========*/
- /* out: folded value */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
{
return(ut_fold_ulint_pair(ut_dulint_get_low(d),
ut_dulint_get_high(d)));
}
-/*****************************************************************
-Folds a character string ending in the null character. */
+/*************************************************************//**
+Folds a character string ending in the null character.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_string(
/*===========*/
- /* out: folded value */
- const char* str) /* in: null-terminated string */
+ const char* str) /*!< in: null-terminated string */
{
ulint fold = 0;
@@ -203,15 +205,15 @@ ut_fold_string(
return(fold);
}
-/*****************************************************************
-Folds a binary string. */
+/*************************************************************//**
+Folds a binary string.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_binary(
/*===========*/
- /* out: folded value */
- const byte* str, /* in: string of bytes */
- ulint len) /* in: length */
+ const byte* str, /*!< in: string of bytes */
+ ulint len) /*!< in: length */
{
const byte* str_end = str + len;
ulint fold = 0;
diff --git a/storage/xtradb/include/ut0sort.h b/storage/xtradb/include/ut0sort.h
index 5fd5db54832..5c6647dda9e 100644
--- a/storage/xtradb/include/ut0sort.h
+++ b/storage/xtradb/include/ut0sort.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0sort.h
Sort utility
Created 11/9/1995 Heikki Tuuri
@@ -34,7 +35,7 @@ the macro. The sort algorithm is mergesort which has logarithmic
worst case.
*/
-/***********************************************************************
+/*******************************************************************//**
This macro expands to the body of a standard sort function.
The sort function uses mergesort and must be defined separately
for each type of array.
diff --git a/storage/xtradb/include/ut0ut.h b/storage/xtradb/include/ut0ut.h
index 3ca14acd2ef..197b8401428 100644
--- a/storage/xtradb/include/ut0ut.h
+++ b/storage/xtradb/include/ut0ut.h
@@ -1,6 +1,13 @@
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Sun Microsystems, Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -16,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0ut.h
Various utilities
Created 1/20/1994 Heikki Tuuri
@@ -26,20 +34,52 @@ Created 1/20/1994 Heikki Tuuri
#define ut0ut_h
#include "univ.i"
+
+#ifndef UNIV_HOTBACKUP
+# include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+#endif /* UNIV_HOTBACKUP */
+
#include <time.h>
#ifndef MYSQL_SERVER
#include <ctype.h>
#endif
-#define TEMP_INDEX_PREFIX '\377' /* Index name prefix in fast index
- creation */
+/** Index name prefix in fast index creation */
+#define TEMP_INDEX_PREFIX '\377'
+/** Index name prefix in fast index creation, as a string constant */
+#define TEMP_INDEX_PREFIX_STR "\377"
+/** Time stamp */
typedef time_t ib_time_t;
-/*************************************************************************
-Delays execution for at most max_wait_us microseconds or returns earlier
-if cond becomes true; cond is evaluated every 2 ms. */
+#ifndef UNIV_HOTBACKUP
+#if defined(HAVE_IB_PAUSE_INSTRUCTION)
+# ifdef WIN32
+ /* In the Win32 API, the x86 PAUSE instruction is executed by calling
+ the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
+ independent way by using YieldProcessor.*/
+# define UT_RELAX_CPU() YieldProcessor()
+# else
+ /* According to the gcc info page, asm volatile means that the
+ instruction has important side-effects and must not be removed.
+ Also asm volatile may trigger a memory barrier (spilling all registers
+ to memory). */
+# define UT_RELAX_CPU() __asm__ __volatile__ ("pause")
+# endif
+#elif defined(HAVE_ATOMIC_BUILTINS)
+# define UT_RELAX_CPU() do { \
+ volatile lint volatile_var; \
+ os_compare_and_swap_lint(&volatile_var, 0, 1); \
+ } while (0)
+#else
+# define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */
+#endif
+/*********************************************************************//**
+Delays execution for at most max_wait_us microseconds or returns earlier
+if cond becomes true.
+@param cond in: condition to wait for; evaluated every 2 ms
+@param max_wait_us in: maximum delay to wait, in microseconds */
#define UT_WAIT_FOR(cond, max_wait_us) \
do { \
ullint start_us; \
@@ -50,219 +90,250 @@ do { \
os_thread_sleep(2000 /* 2 ms */); \
} \
} while (0)
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
+/********************************************************//**
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
but since there seem to be compiler bugs in both gcc and Visual C++,
-we do this by a special conversion. */
+we do this by a special conversion.
+@return a >> 32 */
UNIV_INTERN
ulint
ut_get_high32(
/*==========*/
- /* out: a >> 32 */
- ulint a); /* in: ulint */
-/**********************************************************
-Calculates the minimum of two ulints. */
+ ulint a); /*!< in: ulint */
+/******************************************************//**
+Calculates the minimum of two ulints.
+@return minimum */
UNIV_INLINE
ulint
ut_min(
/*===*/
- /* out: minimum */
- ulint n1, /* in: first number */
- ulint n2); /* in: second number */
-/**********************************************************
-Calculates the maximum of two ulints. */
+ ulint n1, /*!< in: first number */
+ ulint n2); /*!< in: second number */
+/******************************************************//**
+Calculates the maximum of two ulints.
+@return maximum */
UNIV_INLINE
ulint
ut_max(
/*===*/
- /* out: maximum */
- ulint n1, /* in: first number */
- ulint n2); /* in: second number */
-/********************************************************************
+ ulint n1, /*!< in: first number */
+ ulint n2); /*!< in: second number */
+/****************************************************************//**
Calculates minimum of two ulint-pairs. */
UNIV_INLINE
void
ut_pair_min(
/*========*/
- ulint* a, /* out: more significant part of minimum */
- ulint* b, /* out: less significant part of minimum */
- ulint a1, /* in: more significant part of first pair */
- ulint b1, /* in: less significant part of first pair */
- ulint a2, /* in: more significant part of second pair */
- ulint b2); /* in: less significant part of second pair */
-/**********************************************************
-Compares two ulints. */
+ ulint* a, /*!< out: more significant part of minimum */
+ ulint* b, /*!< out: less significant part of minimum */
+ ulint a1, /*!< in: more significant part of first pair */
+ ulint b1, /*!< in: less significant part of first pair */
+ ulint a2, /*!< in: more significant part of second pair */
+ ulint b2); /*!< in: less significant part of second pair */
+/******************************************************//**
+Compares two ulints.
+@return 1 if a > b, 0 if a == b, -1 if a < b */
UNIV_INLINE
int
ut_ulint_cmp(
/*=========*/
- /* out: 1 if a > b, 0 if a == b, -1 if a < b */
- ulint a, /* in: ulint */
- ulint b); /* in: ulint */
-/***********************************************************
-Compares two pairs of ulints. */
+ ulint a, /*!< in: ulint */
+ ulint b); /*!< in: ulint */
+/*******************************************************//**
+Compares two pairs of ulints.
+@return -1 if a < b, 0 if a == b, 1 if a > b */
UNIV_INLINE
int
ut_pair_cmp(
/*========*/
- /* out: -1 if a < b, 0 if a == b,
- 1 if a > b */
- ulint a1, /* in: more significant part of first pair */
- ulint a2, /* in: less significant part of first pair */
- ulint b1, /* in: more significant part of second pair */
- ulint b2); /* in: less significant part of second pair */
-/*****************************************************************
-Determines if a number is zero or a power of two. */
+ ulint a1, /*!< in: more significant part of first pair */
+ ulint a2, /*!< in: less significant part of first pair */
+ ulint b1, /*!< in: more significant part of second pair */
+ ulint b2); /*!< in: less significant part of second pair */
+/*************************************************************//**
+Determines if a number is zero or a power of two.
+@param n in: number
+@return nonzero if n is zero or a power of two; zero otherwise */
#define ut_is_2pow(n) UNIV_LIKELY(!((n) & ((n) - 1)))
-/*****************************************************************
-Calculates fast the remainder of n/m when m is a power of two. */
+/*************************************************************//**
+Calculates fast the remainder of n/m when m is a power of two.
+@param n in: numerator
+@param m in: denominator, must be a power of two
+@return the remainder of n/m */
#define ut_2pow_remainder(n, m) ((n) & ((m) - 1))
-/*****************************************************************
+/*************************************************************//**
Calculates the biggest multiple of m that is not bigger than n
-when m is a power of two. In other words, rounds n down to m * k. */
+when m is a power of two. In other words, rounds n down to m * k.
+@param n in: number to round down
+@param m in: alignment, must be a power of two
+@return n rounded down to the biggest possible integer multiple of m */
#define ut_2pow_round(n, m) ((n) & ~((m) - 1))
+/** Align a number down to a multiple of a power of two.
+@param n in: number to round down
+@param m in: alignment, must be a power of two
+@return n rounded down to the biggest possible integer multiple of m */
#define ut_calc_align_down(n, m) ut_2pow_round(n, m)
-/************************************************************
+/********************************************************//**
Calculates the smallest multiple of m that is not smaller than n
-when m is a power of two. In other words, rounds n up to m * k. */
+when m is a power of two. In other words, rounds n up to m * k.
+@param n in: number to round up
+@param m in: alignment, must be a power of two
+@return n rounded up to the smallest possible integer multiple of m */
#define ut_calc_align(n, m) (((n) + ((m) - 1)) & ~((m) - 1))
-/*****************************************************************
+/*************************************************************//**
Calculates fast the 2-logarithm of a number, rounded upward to an
-integer. */
+integer.
+@return logarithm in the base 2, rounded upward */
UNIV_INLINE
ulint
ut_2_log(
/*=====*/
- /* out: logarithm in the base 2, rounded upward */
- ulint n); /* in: number */
-/*****************************************************************
-Calculates 2 to power n. */
+ ulint n); /*!< in: number */
+/*************************************************************//**
+Calculates 2 to power n.
+@return 2 to power n */
UNIV_INLINE
ulint
ut_2_exp(
/*=====*/
- /* out: 2 to power n */
- ulint n); /* in: number */
-/*****************************************************************
-Calculates fast the number rounded up to the nearest power of 2. */
+ ulint n); /*!< in: number */
+/*************************************************************//**
+Calculates fast the number rounded up to the nearest power of 2.
+@return first power of 2 which is >= n */
UNIV_INTERN
ulint
ut_2_power_up(
/*==========*/
- /* out: first power of 2 which is >= n */
- ulint n) /* in: number != 0 */
+ ulint n) /*!< in: number != 0 */
__attribute__((const));
-/* Determine how many bytes (groups of 8 bits) are needed to
-store the given number of bits. */
+/** Determine how many bytes (groups of 8 bits) are needed to
+store the given number of bits.
+@param b in: bits
+@return number of bytes (octets) needed to represent b */
#define UT_BITS_IN_BYTES(b) (((b) + 7) / 8)
-/**************************************************************
+/**********************************************************//**
Returns system time. We do not specify the format of the time returned:
-the only way to manipulate it is to use the function ut_difftime. */
+the only way to manipulate it is to use the function ut_difftime.
+@return system time */
UNIV_INTERN
ib_time_t
ut_time(void);
/*=========*/
-/**************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
value -1 is returned and the global variable errno is set to indicate the
-error. */
+error.
+@return 0 on success, -1 otherwise */
UNIV_INTERN
int
ut_usectime(
/*========*/
- /* out: 0 on success, -1 otherwise */
- ulint* sec, /* out: seconds since the Epoch */
- ulint* ms); /* out: microseconds since the Epoch+*sec */
+ ulint* sec, /*!< out: seconds since the Epoch */
+ ulint* ms); /*!< out: microseconds since the Epoch+*sec */
-/**************************************************************
+/**********************************************************//**
Returns the number of microseconds since epoch. Similar to
time(3), the return value is also stored in *tloc, provided
-that tloc is non-NULL. */
+that tloc is non-NULL.
+@return us since epoch */
UNIV_INTERN
ullint
ut_time_us(
/*=======*/
- /* out: us since epoch */
- ullint* tloc); /* out: us since epoch, if non-NULL */
+ ullint* tloc); /*!< out: us since epoch, if non-NULL */
+/**********************************************************//**
+Returns the number of milliseconds since some epoch. The
+value may wrap around. It should only be used for heuristic
+purposes.
+@return ms since epoch */
+UNIV_INTERN
+ulint
+ut_time_ms(void);
+/*============*/
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************
-Returns the difference of two times in seconds. */
+/**********************************************************//**
+Returns the difference of two times in seconds.
+@return time2 - time1 expressed in seconds */
UNIV_INTERN
double
ut_difftime(
/*========*/
- /* out: time2 - time1 expressed in seconds */
- ib_time_t time2, /* in: time */
- ib_time_t time1); /* in: time */
-/**************************************************************
+ ib_time_t time2, /*!< in: time */
+ ib_time_t time1); /*!< in: time */
+/**********************************************************//**
Prints a timestamp to a file. */
UNIV_INTERN
void
ut_print_timestamp(
/*===============*/
- FILE* file); /* in: file where to print */
-/**************************************************************
+ FILE* file); /*!< in: file where to print */
+/**********************************************************//**
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
UNIV_INTERN
void
ut_sprintf_timestamp(
/*=================*/
- char* buf); /* in: buffer where to sprintf */
+ char* buf); /*!< in: buffer where to sprintf */
#ifdef UNIV_HOTBACKUP
-/**************************************************************
+/**********************************************************//**
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
replaced by '_'. */
UNIV_INTERN
void
ut_sprintf_timestamp_without_extra_chars(
/*=====================================*/
- char* buf); /* in: buffer where to sprintf */
-/**************************************************************
+ char* buf); /*!< in: buffer where to sprintf */
+/**********************************************************//**
Returns current year, month, day. */
UNIV_INTERN
void
ut_get_year_month_day(
/*==================*/
- ulint* year, /* out: current year */
- ulint* month, /* out: month */
- ulint* day); /* out: day */
-#endif /* UNIV_HOTBACKUP */
-/*****************************************************************
+ ulint* year, /*!< out: current year */
+ ulint* month, /*!< out: month */
+ ulint* day); /*!< out: day */
+#else /* UNIV_HOTBACKUP */
+/*************************************************************//**
Runs an idle loop on CPU. The argument gives the desired delay
-in microseconds on 100 MHz Pentium + Visual C++. */
+in microseconds on 100 MHz Pentium + Visual C++.
+@return dummy value */
UNIV_INTERN
ulint
ut_delay(
/*=====*/
- /* out: dummy value */
- ulint delay); /* in: delay in microseconds on 100 MHz Pentium */
-/*****************************************************************
+ ulint delay); /*!< in: delay in microseconds on 100 MHz Pentium */
+#endif /* UNIV_HOTBACKUP */
+/*************************************************************//**
Prints the contents of a memory buffer in hex and ascii. */
UNIV_INTERN
void
ut_print_buf(
/*=========*/
- FILE* file, /* in: file where to print */
- const void* buf, /* in: memory buffer */
- ulint len); /* in: length of the buffer */
+ FILE* file, /*!< in: file where to print */
+ const void* buf, /*!< in: memory buffer */
+ ulint len); /*!< in: length of the buffer */
-/**************************************************************************
+/**********************************************************************//**
Outputs a NUL-terminated file name, quoted with apostrophes. */
UNIV_INTERN
void
ut_print_filename(
/*==============*/
- FILE* f, /* in: output stream */
- const char* name); /* in: name to print */
+ FILE* f, /*!< in: output stream */
+ const char* name); /*!< in: name to print */
+#ifndef UNIV_HOTBACKUP
/* Forward declaration of transaction handle */
struct trx_struct;
-/**************************************************************************
+/**********************************************************************//**
Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
@@ -271,13 +342,13 @@ UNIV_INTERN
void
ut_print_name(
/*==========*/
- FILE* f, /* in: output stream */
- struct trx_struct*trx, /* in: transaction */
- ibool table_id,/* in: TRUE=print a table name,
+ FILE* f, /*!< in: output stream */
+ struct trx_struct*trx, /*!< in: transaction */
+ ibool table_id,/*!< in: TRUE=print a table name,
FALSE=print other identifier */
- const char* name); /* in: name to print */
+ const char* name); /*!< in: name to print */
-/**************************************************************************
+/**********************************************************************//**
Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
@@ -286,38 +357,42 @@ UNIV_INTERN
void
ut_print_namel(
/*===========*/
- FILE* f, /* in: output stream */
- struct trx_struct*trx, /* in: transaction (NULL=no quotes) */
- ibool table_id,/* in: TRUE=print a table name,
+ FILE* f, /*!< in: output stream */
+ struct trx_struct*trx, /*!< in: transaction (NULL=no quotes) */
+ ibool table_id,/*!< in: TRUE=print a table name,
FALSE=print other identifier */
- const char* name, /* in: name to print */
- ulint namelen);/* in: length of name */
+ const char* name, /*!< in: name to print */
+ ulint namelen);/*!< in: length of name */
-/**************************************************************************
+/**********************************************************************//**
Catenate files. */
UNIV_INTERN
void
ut_copy_file(
/*=========*/
- FILE* dest, /* in: output file */
- FILE* src); /* in: input file to be appended to output */
-
-/**************************************************************************
-snprintf(). */
+ FILE* dest, /*!< in: output file */
+ FILE* src); /*!< in: input file to be appended to output */
+#endif /* !UNIV_HOTBACKUP */
#ifdef __WIN__
+/**********************************************************************//**
+A substitute for snprintf(3), formatted output conversion into
+a limited buffer.
+@return number of characters that would have been printed if the size
+were unlimited, not including the terminating '\0'. */
+UNIV_INTERN
int
ut_snprintf(
- /* out: number of characters that would
- have been printed if the size were
- unlimited, not including the terminating
- '\0'. */
- char* str, /* out: string */
- size_t size, /* in: str size */
- const char* fmt, /* in: format */
- ...); /* in: format values */
+/*========*/
+ char* str, /*!< out: string */
+ size_t size, /*!< in: str size */
+ const char* fmt, /*!< in: format */
+ ...); /*!< in: format values */
#else
-#define ut_snprintf snprintf
+/**********************************************************************//**
+A wrapper for snprintf(3), formatted output conversion into
+a limited buffer. */
+# define ut_snprintf snprintf
#endif /* __WIN__ */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/ut0ut.ic b/storage/xtradb/include/ut0ut.ic
index e4e0a2acce6..6f55c7e410e 100644
--- a/storage/xtradb/include/ut0ut.ic
+++ b/storage/xtradb/include/ut0ut.ic
@@ -16,50 +16,51 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************************
+/**************************************************************//**
+@file include/ut0ut.ic
Various utilities
Created 5/30/1994 Heikki Tuuri
*******************************************************************/
-/**********************************************************
-Calculates the minimum of two ulints. */
+/******************************************************//**
+Calculates the minimum of two ulints.
+@return minimum */
UNIV_INLINE
ulint
ut_min(
/*===*/
- /* out: minimum */
- ulint n1, /* in: first number */
- ulint n2) /* in: second number */
+ ulint n1, /*!< in: first number */
+ ulint n2) /*!< in: second number */
{
return((n1 <= n2) ? n1 : n2);
}
-/**********************************************************
-Calculates the maximum of two ulints. */
+/******************************************************//**
+Calculates the maximum of two ulints.
+@return maximum */
UNIV_INLINE
ulint
ut_max(
/*===*/
- /* out: maximum */
- ulint n1, /* in: first number */
- ulint n2) /* in: second number */
+ ulint n1, /*!< in: first number */
+ ulint n2) /*!< in: second number */
{
return((n1 <= n2) ? n2 : n1);
}
-/********************************************************************
+/****************************************************************//**
Calculates minimum of two ulint-pairs. */
UNIV_INLINE
void
ut_pair_min(
/*========*/
- ulint* a, /* out: more significant part of minimum */
- ulint* b, /* out: less significant part of minimum */
- ulint a1, /* in: more significant part of first pair */
- ulint b1, /* in: less significant part of first pair */
- ulint a2, /* in: more significant part of second pair */
- ulint b2) /* in: less significant part of second pair */
+ ulint* a, /*!< out: more significant part of minimum */
+ ulint* b, /*!< out: less significant part of minimum */
+ ulint a1, /*!< in: more significant part of first pair */
+ ulint b1, /*!< in: less significant part of first pair */
+ ulint a2, /*!< in: more significant part of second pair */
+ ulint b2) /*!< in: less significant part of second pair */
{
if (a1 == a2) {
*a = a1;
@@ -73,15 +74,15 @@ ut_pair_min(
}
}
-/**********************************************************
-Compares two ulints. */
+/******************************************************//**
+Compares two ulints.
+@return 1 if a > b, 0 if a == b, -1 if a < b */
UNIV_INLINE
int
ut_ulint_cmp(
/*=========*/
- /* out: 1 if a > b, 0 if a == b, -1 if a < b */
- ulint a, /* in: ulint */
- ulint b) /* in: ulint */
+ ulint a, /*!< in: ulint */
+ ulint b) /*!< in: ulint */
{
if (a < b) {
return(-1);
@@ -92,17 +93,17 @@ ut_ulint_cmp(
}
}
-/***********************************************************
-Compares two pairs of ulints. */
+/*******************************************************//**
+Compares two pairs of ulints.
+@return -1 if a < b, 0 if a == b, 1 if a > b */
UNIV_INLINE
int
ut_pair_cmp(
/*========*/
- /* out: -1 if a < b, 0 if a == b, 1 if a > b */
- ulint a1, /* in: more significant part of first pair */
- ulint a2, /* in: less significant part of first pair */
- ulint b1, /* in: more significant part of second pair */
- ulint b2) /* in: less significant part of second pair */
+ ulint a1, /*!< in: more significant part of first pair */
+ ulint a2, /*!< in: less significant part of first pair */
+ ulint b1, /*!< in: more significant part of second pair */
+ ulint b2) /*!< in: less significant part of second pair */
{
if (a1 > b1) {
return(1);
@@ -117,15 +118,15 @@ ut_pair_cmp(
}
}
-/*****************************************************************
+/*************************************************************//**
Calculates fast the 2-logarithm of a number, rounded upward to an
-integer. */
+integer.
+@return logarithm in the base 2, rounded upward */
UNIV_INLINE
ulint
ut_2_log(
/*=====*/
- /* out: logarithm in the base 2, rounded upward */
- ulint n) /* in: number != 0 */
+ ulint n) /*!< in: number != 0 */
{
ulint res;
@@ -148,14 +149,14 @@ ut_2_log(
return(res + 1);
}
-/*****************************************************************
-Calculates 2 to power n. */
+/*************************************************************//**
+Calculates 2 to power n.
+@return 2 to power n */
UNIV_INLINE
ulint
ut_2_exp(
/*=====*/
- /* out: 2 to power n */
- ulint n) /* in: number */
+ ulint n) /*!< in: number */
{
return((ulint) 1 << n);
}
diff --git a/storage/xtradb/include/ut0vec.h b/storage/xtradb/include/ut0vec.h
index aeb7e168dc6..a770f671cfc 100644
--- a/storage/xtradb/include/ut0vec.h
+++ b/storage/xtradb/include/ut0vec.h
@@ -16,12 +16,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*******************************************************************//**
+@file include/ut0vec.h
+A vector of pointers to data items
+
+Created 4/6/2006 Osku Salerma
+************************************************************************/
+
#ifndef IB_VECTOR_H
#define IB_VECTOR_H
#include "univ.i"
#include "mem0mem.h"
+/** An automatically resizing vector data type. */
typedef struct ib_vector_struct ib_vector_t;
/* An automatically resizing vector datatype with the following properties:
@@ -38,76 +46,76 @@ typedef struct ib_vector_struct ib_vector_t;
relatively small or short-lived uses.
*/
-/********************************************************************
-Create a new vector with the given initial size. */
+/****************************************************************//**
+Create a new vector with the given initial size.
+@return vector */
UNIV_INTERN
ib_vector_t*
ib_vector_create(
/*=============*/
- /* out: vector */
- mem_heap_t* heap, /* in: heap */
- ulint size); /* in: initial size */
+ mem_heap_t* heap, /*!< in: heap */
+ ulint size); /*!< in: initial size */
-/********************************************************************
+/****************************************************************//**
Push a new element to the vector, increasing its size if necessary. */
UNIV_INTERN
void
ib_vector_push(
/*===========*/
- ib_vector_t* vec, /* in: vector */
- void* elem); /* in: data element */
+ ib_vector_t* vec, /*!< in: vector */
+ void* elem); /*!< in: data element */
-/********************************************************************
-Get the number of elements in the vector. */
+/****************************************************************//**
+Get the number of elements in the vector.
+@return number of elements in vector */
UNIV_INLINE
ulint
ib_vector_size(
/*===========*/
- /* out: number of elements in vector */
- const ib_vector_t* vec); /* in: vector */
+ const ib_vector_t* vec); /*!< in: vector */
-/********************************************************************
-Test whether a vector is empty or not. */
+/****************************************************************//**
+Test whether a vector is empty or not.
+@return TRUE if empty */
UNIV_INLINE
ibool
ib_vector_is_empty(
/*===============*/
- /* out: TRUE if empty */
- const ib_vector_t* vec); /* in: vector */
+ const ib_vector_t* vec); /*!< in: vector */
-/********************************************************************
-Get the n'th element. */
+/****************************************************************//**
+Get the n'th element.
+@return n'th element */
UNIV_INLINE
void*
ib_vector_get(
/*==========*/
- /* out: n'th element */
- ib_vector_t* vec, /* in: vector */
- ulint n); /* in: element index to get */
+ ib_vector_t* vec, /*!< in: vector */
+ ulint n); /*!< in: element index to get */
-/********************************************************************
+/****************************************************************//**
Remove the last element from the vector. */
UNIV_INLINE
void*
ib_vector_pop(
/*==========*/
- ib_vector_t* vec); /* in: vector */
+ ib_vector_t* vec); /*!< in: vector */
-/********************************************************************
+/****************************************************************//**
Free the underlying heap of the vector. Note that vec is invalid
after this call. */
UNIV_INLINE
void
ib_vector_free(
/*===========*/
- ib_vector_t* vec); /* in,own: vector */
+ ib_vector_t* vec); /*!< in,own: vector */
-/* See comment at beginning of file. */
+/** An automatically resizing vector data type. */
struct ib_vector_struct {
- mem_heap_t* heap; /* heap */
- void** data; /* data elements */
- ulint used; /* number of elements currently used */
- ulint total; /* number of elements allocated */
+ mem_heap_t* heap; /*!< heap */
+ void** data; /*!< data elements */
+ ulint used; /*!< number of elements currently used */
+ ulint total; /*!< number of elements allocated */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/ut0vec.ic b/storage/xtradb/include/ut0vec.ic
index b0e853717e3..02e881f9bca 100644
--- a/storage/xtradb/include/ut0vec.ic
+++ b/storage/xtradb/include/ut0vec.ic
@@ -16,41 +16,48 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/********************************************************************
-Get number of elements in vector. */
+/*******************************************************************//**
+@file include/ut0vec.ic
+A vector of pointers to data items
+
+Created 4/6/2006 Osku Salerma
+************************************************************************/
+
+/****************************************************************//**
+Get number of elements in vector.
+@return number of elements in vector */
UNIV_INLINE
ulint
ib_vector_size(
/*===========*/
- /* out: number of elements in vector */
- const ib_vector_t* vec) /* in: vector */
+ const ib_vector_t* vec) /*!< in: vector */
{
return(vec->used);
}
-/********************************************************************
-Get n'th element. */
+/****************************************************************//**
+Get n'th element.
+@return n'th element */
UNIV_INLINE
void*
ib_vector_get(
/*==========*/
- /* out: n'th element */
- ib_vector_t* vec, /* in: vector */
- ulint n) /* in: element index to get */
+ ib_vector_t* vec, /*!< in: vector */
+ ulint n) /*!< in: element index to get */
{
ut_a(n < vec->used);
return(vec->data[n]);
}
-/********************************************************************
-Remove the last element from the vector. */
+/****************************************************************//**
+Remove the last element from the vector.
+@return last vector element */
UNIV_INLINE
void*
ib_vector_pop(
/*==========*/
- /* out: last vector element */
- ib_vector_t* vec) /* in/out: vector */
+ ib_vector_t* vec) /*!< in/out: vector */
{
void* elem;
@@ -64,25 +71,26 @@ ib_vector_pop(
return(elem);
}
-/********************************************************************
+/****************************************************************//**
Free the underlying heap of the vector. Note that vec is invalid
after this call. */
UNIV_INLINE
void
ib_vector_free(
/*===========*/
- ib_vector_t* vec) /* in, own: vector */
+ ib_vector_t* vec) /*!< in, own: vector */
{
mem_heap_free(vec->heap);
}
-/********************************************************************
-Test whether a vector is empty or not. */
+/****************************************************************//**
+Test whether a vector is empty or not.
+@return TRUE if empty */
UNIV_INLINE
ibool
ib_vector_is_empty(
-/*===============*/ /* out: TRUE if empty else FALSE */
- const ib_vector_t* vec) /* in vector to test */
+/*===============*/
+ const ib_vector_t* vec) /*!< in: vector */
{
return(ib_vector_size(vec) == 0);
}
diff --git a/storage/xtradb/include/ut0wqueue.h b/storage/xtradb/include/ut0wqueue.h
index 6bb80dad532..2ec0f16ab05 100644
--- a/storage/xtradb/include/ut0wqueue.h
+++ b/storage/xtradb/include/ut0wqueue.h
@@ -16,7 +16,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/ut0wqueue.h
+A work queue
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
+/*******************************************************************//**
A Work queue. Threads can add work items to the queue and other threads can
wait for work items to be available and take them off the queue for
processing.
@@ -32,46 +39,47 @@ processing.
typedef struct ib_wqueue_struct ib_wqueue_t;
-/********************************************************************
-Create a new work queue. */
+/****************************************************************//**
+Create a new work queue.
+@return work queue */
UNIV_INTERN
ib_wqueue_t*
ib_wqueue_create(void);
/*===================*/
- /* out: work queue */
-/********************************************************************
+/****************************************************************//**
Free a work queue. */
UNIV_INTERN
void
ib_wqueue_free(
/*===========*/
- ib_wqueue_t* wq); /* in: work queue */
+ ib_wqueue_t* wq); /*!< in: work queue */
-/********************************************************************
+/****************************************************************//**
Add a work item to the queue. */
UNIV_INTERN
void
ib_wqueue_add(
/*==========*/
- ib_wqueue_t* wq, /* in: work queue */
- void* item, /* in: work item */
- mem_heap_t* heap); /* in: memory heap to use for allocating the
+ ib_wqueue_t* wq, /*!< in: work queue */
+ void* item, /*!< in: work item */
+ mem_heap_t* heap); /*!< in: memory heap to use for allocating the
list node */
-/********************************************************************
-Wait for a work item to appear in the queue. */
+/****************************************************************//**
+Wait for a work item to appear in the queue.
+@return work item */
UNIV_INTERN
void*
ib_wqueue_wait(
- /* out: work item */
- ib_wqueue_t* wq); /* in: work queue */
+/*===========*/
+ ib_wqueue_t* wq); /*!< in: work queue */
/* Work queue. */
struct ib_wqueue_struct {
- mutex_t mutex; /* mutex protecting everything */
- ib_list_t* items; /* work item list */
- os_event_t event; /* event we use to signal additions to list */
+ mutex_t mutex; /*!< mutex protecting everything */
+ ib_list_t* items; /*!< work item list */
+ os_event_t event; /*!< event we use to signal additions to list */
};
#endif
diff --git a/storage/xtradb/lock/lock0iter.c b/storage/xtradb/lock/lock0iter.c
index e7a128d0db3..51d1802ccde 100644
--- a/storage/xtradb/lock/lock0iter.c
+++ b/storage/xtradb/lock/lock0iter.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file lock/lock0iter.c
Lock queue iterator. Can iterate over table and record
lock queues.
@@ -35,7 +36,7 @@ Created July 16, 2007 Vasil Dimov
# include "srv0srv.h" /* kernel_mutex */
#endif /* UNIV_DEBUG */
-/***********************************************************************
+/*******************************************************************//**
Initialize lock queue iterator so that it starts to iterate from
"lock". bit_no specifies the record number within the heap where the
record is stored. It can be undefined (ULINT_UNDEFINED) in two cases:
@@ -48,9 +49,9 @@ UNIV_INTERN
void
lock_queue_iterator_reset(
/*======================*/
- lock_queue_iterator_t* iter, /* out: iterator */
- const lock_t* lock, /* in: lock to start from */
- ulint bit_no) /* in: record number in the
+ lock_queue_iterator_t* iter, /*!< out: iterator */
+ const lock_t* lock, /*!< in: lock to start from */
+ ulint bit_no) /*!< in: record number in the
heap */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -76,16 +77,16 @@ lock_queue_iterator_reset(
}
}
-/***********************************************************************
+/*******************************************************************//**
Gets the previous lock in the lock queue, returns NULL if there are no
more locks (i.e. the current lock is the first one). The iterator is
-receded (if not-NULL is returned). */
+receded (if not-NULL is returned).
+@return previous lock or NULL */
UNIV_INTERN
const lock_t*
lock_queue_iterator_get_prev(
/*=========================*/
- /* out: previous lock or NULL */
- lock_queue_iterator_t* iter) /* in/out: iterator */
+ lock_queue_iterator_t* iter) /*!< in/out: iterator */
{
const lock_t* prev_lock;
diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c
index 9e90e099428..d1a37b13cd0 100644
--- a/storage/xtradb/lock/lock0lock.c
+++ b/storage/xtradb/lock/lock0lock.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file lock/lock0lock.c
The transaction lock system
Created 5/7/1996 Heikki Tuuri
@@ -213,7 +214,7 @@ a waiting s-lock request on the next record? If this s-lock was placed
by a read cursor moving in the ascending order in the index, we cannot
do the insert immediately, because when we finally commit our transaction,
the read cursor should see also the new inserted record. So we should
-move the read cursor backward from the the next record for it to pass over
+move the read cursor backward from the next record for it to pass over
the new inserted record. This move backward may be too cumbersome to
implement. If we in this situation just enqueue a second x-lock request
for our transaction on the next record, then the deadlock mechanism
@@ -343,26 +344,25 @@ equal to mode2. */
#ifdef UNIV_DEBUG
UNIV_INTERN ibool lock_print_waits = FALSE;
-/*************************************************************************
-Validates the lock system. */
+/*********************************************************************//**
+Validates the lock system.
+@return TRUE if ok */
static
ibool
lock_validate(void);
/*===============*/
- /* out: TRUE if ok */
-/*************************************************************************
-Validates the record lock queues on a page. */
+/*********************************************************************//**
+Validates the record lock queues on a page.
+@return TRUE if ok */
static
ibool
lock_rec_validate_page(
/*===================*/
- /* out: TRUE if ok */
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
-
-/* Define the following in order to enable lock_rec_validate_page() checks. */
-# undef UNIV_DEBUG_LOCK_VALIDATE
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
+ ulint page_no);/*!< in: page number */
#endif /* UNIV_DEBUG */
/* The lock system */
@@ -377,51 +377,47 @@ UNIV_INTERN FILE* lock_latest_err_file;
#define LOCK_VICTIM_IS_START 1
#define LOCK_VICTIM_IS_OTHER 2
-/************************************************************************
-Checks if a lock request results in a deadlock. */
+/********************************************************************//**
+Checks if a lock request results in a deadlock.
+@return TRUE if a deadlock was detected and we chose trx as a victim;
+FALSE if no deadlock, or there was a deadlock, but we chose other
+transaction(s) as victim(s) */
static
ibool
lock_deadlock_occurs(
/*=================*/
- /* out: TRUE if a deadlock was detected and we
- chose trx as a victim; FALSE if no deadlock, or
- there was a deadlock, but we chose other
- transaction(s) as victim(s) */
- lock_t* lock, /* in: lock the transaction is requesting */
- trx_t* trx); /* in: transaction */
-/************************************************************************
-Looks recursively for a deadlock. */
+ lock_t* lock, /*!< in: lock the transaction is requesting */
+ trx_t* trx); /*!< in: transaction */
+/********************************************************************//**
+Looks recursively for a deadlock.
+@return 0 if no deadlock found, LOCK_VICTIM_IS_START if there was a
+deadlock and we chose 'start' as the victim, LOCK_VICTIM_IS_OTHER if a
+deadlock was found and we chose some other trx as a victim: we must do
+the search again in this last case because there may be another
+deadlock! */
static
ulint
lock_deadlock_recursive(
/*====================*/
- /* out: 0 if no deadlock found,
- LOCK_VICTIM_IS_START if there was a deadlock
- and we chose 'start' as the victim,
- LOCK_VICTIM_IS_OTHER if a deadlock
- was found and we chose some other trx as a
- victim: we must do the search again in this
- last case because there may be another
- deadlock! */
- trx_t* start, /* in: recursion starting point */
- trx_t* trx, /* in: a transaction waiting for a lock */
- lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
- ulint* cost, /* in/out: number of calculation steps thus
+ trx_t* start, /*!< in: recursion starting point */
+ trx_t* trx, /*!< in: a transaction waiting for a lock */
+ lock_t* wait_lock, /*!< in: the lock trx is waiting to be granted */
+ ulint* cost, /*!< in/out: number of calculation steps thus
far: if this exceeds LOCK_MAX_N_STEPS_...
we return LOCK_VICTIM_IS_START */
- ulint depth); /* in: recursion depth: if this exceeds
+ ulint depth); /*!< in: recursion depth: if this exceeds
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
return LOCK_VICTIM_IS_START */
-/*************************************************************************
-Gets the nth bit of a record lock. */
+/*********************************************************************//**
+Gets the nth bit of a record lock.
+@return TRUE if bit set */
UNIV_INLINE
ibool
lock_rec_get_nth_bit(
/*=================*/
- /* out: TRUE if bit set */
- const lock_t* lock, /* in: record lock */
- ulint i) /* in: index of the bit */
+ const lock_t* lock, /*!< in: record lock */
+ ulint i) /*!< in: index of the bit */
{
ulint byte_index;
ulint bit_index;
@@ -445,18 +441,18 @@ lock_rec_get_nth_bit(
#define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex)
#define lock_mutex_exit_kernel() mutex_exit(&kernel_mutex)
-/*************************************************************************
-Checks that a transaction id is sensible, i.e., not in the future. */
+/*********************************************************************//**
+Checks that a transaction id is sensible, i.e., not in the future.
+@return TRUE if ok */
UNIV_INTERN
ibool
lock_check_trx_id_sanity(
/*=====================*/
- /* out: TRUE if ok */
- dulint 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) */
- ibool has_kernel_mutex)/* in: TRUE if the caller owns the
+ 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) */
+ ibool has_kernel_mutex)/*!< in: TRUE if the caller owns the
kernel mutex */
{
ibool is_ok = TRUE;
@@ -496,21 +492,21 @@ lock_check_trx_id_sanity(
return(is_ok);
}
-/*************************************************************************
-Checks that a record is seen in a consistent read. */
+/*********************************************************************//**
+Checks that a record is seen in a consistent read.
+@return TRUE if sees, or FALSE if an earlier version of the record
+should be retrieved */
UNIV_INTERN
ibool
lock_clust_rec_cons_read_sees(
/*==========================*/
- /* out: TRUE if sees, or FALSE if an earlier
- version of the record should be retrieved */
- const rec_t* rec, /* in: user record which should be read or
+ 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) */
- read_view_t* view) /* in: consistent read view */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ read_view_t* view) /*!< in: consistent read view */
{
- dulint trx_id;
+ trx_id_t trx_id;
ut_ad(dict_index_is_clust(index));
ut_ad(page_rec_is_user_rec(rec));
@@ -525,31 +521,26 @@ lock_clust_rec_cons_read_sees(
return(read_view_sees_trx_id(view, trx_id));
}
-/*************************************************************************
-Checks that a non-clustered index record is seen in a consistent read. */
+/*********************************************************************//**
+Checks that a non-clustered index record is seen in a consistent read.
+
+NOTE that a non-clustered index page contains so little information on
+its modifications that also in the case FALSE, the present version of
+rec may be the right, but we must check this from the clustered index
+record.
+
+@return TRUE if certainly sees, or FALSE if an earlier version of the
+clustered index record might be needed */
UNIV_INTERN
ulint
lock_sec_rec_cons_read_sees(
/*========================*/
- /* out: TRUE if certainly
- sees, or FALSE if an earlier
- version of the clustered index
- record might be needed: NOTE
- that a non-clustered index
- page contains so little
- information on its
- modifications that also in the
- case FALSE, the present
- version of rec may be the
- right, but we must check this
- from the clustered index
- record */
- const rec_t* rec, /* in: user record which
+ const rec_t* rec, /*!< in: user record which
should be read or passed over
by a read cursor */
- const read_view_t* view) /* in: consistent read view */
+ const read_view_t* view) /*!< in: consistent read view */
{
- dulint max_trx_id;
+ trx_id_t max_trx_id;
ut_ad(page_rec_is_user_rec(rec));
@@ -563,17 +554,18 @@ lock_sec_rec_cons_read_sees(
}
max_trx_id = page_get_max_trx_id(page_align(rec));
+ ut_ad(!ut_dulint_is_zero(max_trx_id));
return(ut_dulint_cmp(max_trx_id, view->up_limit_id) < 0);
}
-/*************************************************************************
+/*********************************************************************//**
Creates the lock system at database start. */
UNIV_INTERN
void
lock_sys_create(
/*============*/
- ulint n_cells) /* in: number of slots in lock hash table */
+ ulint n_cells) /*!< in: number of slots in lock hash table */
{
lock_sys = mem_alloc(sizeof(lock_sys_t));
@@ -585,39 +577,56 @@ lock_sys_create(
ut_a(lock_latest_err_file);
}
-/*************************************************************************
-Gets the size of a lock struct. */
+/*********************************************************************//**
+Closes the lock system at database shutdown. */
+UNIV_INTERN
+void
+lock_sys_close(void)
+/*================*/
+{
+ if (lock_latest_err_file != NULL) {
+ fclose(lock_latest_err_file);
+ lock_latest_err_file = NULL;
+ }
+
+ hash_table_free(lock_sys->rec_hash);
+ mem_free(lock_sys);
+ lock_sys = NULL;
+}
+
+/*********************************************************************//**
+Gets the size of a lock struct.
+@return size in bytes */
UNIV_INTERN
ulint
lock_get_size(void)
/*===============*/
- /* out: size in bytes */
{
return((ulint)sizeof(lock_t));
}
-/*************************************************************************
-Gets the mode of a lock. */
+/*********************************************************************//**
+Gets the mode of a lock.
+@return mode */
UNIV_INLINE
enum lock_mode
lock_get_mode(
/*==========*/
- /* out: mode */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_ad(lock);
return(lock->type_mode & LOCK_MODE_MASK);
}
-/*************************************************************************
-Gets the wait flag of a lock. */
+/*********************************************************************//**
+Gets the wait flag of a lock.
+@return TRUE if waiting */
UNIV_INLINE
ibool
lock_get_wait(
/*==========*/
- /* out: TRUE if waiting */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_ad(lock);
@@ -629,21 +638,20 @@ lock_get_wait(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the source table of an ALTER TABLE transaction. The table must be
-covered by an IX or IS table lock. */
+covered by an IX or IS table lock.
+@return the source table of transaction, if it is covered by an IX or
+IS table lock; dest if there is no source table, and NULL if the
+transaction is locking more than two tables or an inconsistency is
+found */
UNIV_INTERN
dict_table_t*
lock_get_src_table(
/*===============*/
- /* out: the source table of transaction,
- if it is covered by an IX or IS table lock;
- dest if there is no source table, and
- NULL if the transaction is locking more than
- two tables or an inconsistency is found */
- trx_t* trx, /* in: transaction */
- dict_table_t* dest, /* in: destination of ALTER TABLE */
- enum lock_mode* mode) /* out: lock mode of the source table */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* dest, /*!< in: destination of ALTER TABLE */
+ enum lock_mode* mode) /*!< out: lock mode of the source table */
{
dict_table_t* src;
lock_t* lock;
@@ -699,18 +707,18 @@ lock_get_src_table(
return(src);
}
-/*************************************************************************
+/*********************************************************************//**
Determine if the given table is exclusively "owned" by the given
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
-on the table. */
+on the table.
+@return TRUE if table is only locked by trx, with LOCK_IX, and
+possibly LOCK_AUTO_INC */
UNIV_INTERN
ibool
lock_is_table_exclusive(
/*====================*/
- /* out: TRUE if table is only locked by trx,
- with LOCK_IX, and possibly LOCK_AUTO_INC */
- dict_table_t* table, /* in: table */
- trx_t* trx) /* in: transaction */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx) /*!< in: transaction */
{
const lock_t* lock;
ibool ok = FALSE;
@@ -756,14 +764,14 @@ func_exit:
return(ok);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the wait flag of a lock and the back pointer in trx to lock. */
UNIV_INLINE
void
lock_set_lock_and_trx_wait(
/*=======================*/
- lock_t* lock, /* in: lock */
- trx_t* trx) /* in: trx */
+ lock_t* lock, /*!< in: lock */
+ trx_t* trx) /*!< in: trx */
{
ut_ad(lock);
ut_ad(trx->wait_lock == NULL);
@@ -772,14 +780,14 @@ lock_set_lock_and_trx_wait(
lock->type_mode |= LOCK_WAIT;
}
-/**************************************************************************
+/**********************************************************************//**
The back pointer to a waiting lock request in the transaction is set to NULL
and the wait bit in lock type_mode is reset. */
UNIV_INLINE
void
lock_reset_lock_and_trx_wait(
/*=========================*/
- lock_t* lock) /* in: record lock */
+ lock_t* lock) /*!< in: record lock */
{
ut_ad((lock->trx)->wait_lock == lock);
ut_ad(lock_get_wait(lock));
@@ -790,14 +798,14 @@ lock_reset_lock_and_trx_wait(
lock->type_mode &= ~LOCK_WAIT;
}
-/*************************************************************************
-Gets the gap flag of a record lock. */
+/*********************************************************************//**
+Gets the gap flag of a record lock.
+@return TRUE if gap flag set */
UNIV_INLINE
ibool
lock_rec_get_gap(
/*=============*/
- /* out: TRUE if gap flag set */
- const lock_t* lock) /* in: record lock */
+ const lock_t* lock) /*!< in: record lock */
{
ut_ad(lock);
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -810,14 +818,14 @@ lock_rec_get_gap(
return(FALSE);
}
-/*************************************************************************
-Gets the LOCK_REC_NOT_GAP flag of a record lock. */
+/*********************************************************************//**
+Gets the LOCK_REC_NOT_GAP flag of a record lock.
+@return TRUE if LOCK_REC_NOT_GAP flag set */
UNIV_INLINE
ibool
lock_rec_get_rec_not_gap(
/*=====================*/
- /* out: TRUE if LOCK_REC_NOT_GAP flag set */
- const lock_t* lock) /* in: record lock */
+ const lock_t* lock) /*!< in: record lock */
{
ut_ad(lock);
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -830,14 +838,14 @@ lock_rec_get_rec_not_gap(
return(FALSE);
}
-/*************************************************************************
-Gets the waiting insert flag of a record lock. */
+/*********************************************************************//**
+Gets the waiting insert flag of a record lock.
+@return TRUE if gap flag set */
UNIV_INLINE
ibool
lock_rec_get_insert_intention(
/*==========================*/
- /* out: TRUE if gap flag set */
- const lock_t* lock) /* in: record lock */
+ const lock_t* lock) /*!< in: record lock */
{
ut_ad(lock);
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -850,16 +858,15 @@ lock_rec_get_insert_intention(
return(FALSE);
}
-/*************************************************************************
-Calculates if lock mode 1 is stronger or equal to lock mode 2. */
+/*********************************************************************//**
+Calculates if lock mode 1 is stronger or equal to lock mode 2.
+@return nonzero if mode1 stronger or equal to mode2 */
UNIV_INLINE
ulint
lock_mode_stronger_or_eq(
/*=====================*/
- /* out: nonzero
- if mode1 stronger or equal to mode2 */
- enum lock_mode mode1, /* in: lock mode */
- enum lock_mode mode2) /* in: lock mode */
+ enum lock_mode mode1, /*!< in: lock mode */
+ enum lock_mode mode2) /*!< in: lock mode */
{
ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
@@ -869,15 +876,15 @@ lock_mode_stronger_or_eq(
return((LOCK_MODE_STRONGER_OR_EQ) & LK(mode1, mode2));
}
-/*************************************************************************
-Calculates if lock mode 1 is compatible with lock mode 2. */
+/*********************************************************************//**
+Calculates if lock mode 1 is compatible with lock mode 2.
+@return nonzero if mode1 compatible with mode2 */
UNIV_INLINE
ulint
lock_mode_compatible(
/*=================*/
- /* out: nonzero if mode1 compatible with mode2 */
- enum lock_mode mode1, /* in: lock mode */
- enum lock_mode mode2) /* in: lock mode */
+ enum lock_mode mode1, /*!< in: lock mode */
+ enum lock_mode mode2) /*!< in: lock mode */
{
ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
@@ -887,24 +894,23 @@ lock_mode_compatible(
return((LOCK_MODE_COMPATIBILITY) & LK(mode1, mode2));
}
-/*************************************************************************
-Checks if a lock request for a new lock has to wait for request lock2. */
+/*********************************************************************//**
+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 */
UNIV_INLINE
ibool
lock_rec_has_to_wait(
/*=================*/
- /* out: TRUE if new lock has to wait
- for lock2 to be removed */
- const trx_t* trx, /* in: trx of new lock */
- ulint type_mode,/* in: precise mode of the new lock
+ const trx_t* trx, /*!< in: trx of new lock */
+ ulint type_mode,/*!< in: precise mode of the new lock
to set: LOCK_S or LOCK_X, possibly
ORed to LOCK_GAP or LOCK_REC_NOT_GAP,
LOCK_INSERT_INTENTION */
- const lock_t* lock2, /* in: another record lock; NOTE that
+ const lock_t* lock2, /*!< in: another record lock; NOTE that
it is assumed that this has a lock bit
set on the same record as in the new
lock we are setting */
- ibool lock_is_on_supremum) /* in: TRUE if we are setting the
+ ibool lock_is_on_supremum) /*!< in: TRUE if we are setting the
lock on the 'supremum' record of an
index page: we know then that the lock
request is really for a 'gap' type lock */
@@ -970,16 +976,15 @@ lock_rec_has_to_wait(
return(FALSE);
}
-/*************************************************************************
-Checks if a lock request lock1 has to wait for request lock2. */
+/*********************************************************************//**
+Checks if a lock request lock1 has to wait for request lock2.
+@return TRUE if lock1 has to wait for lock2 to be removed */
UNIV_INTERN
ibool
lock_has_to_wait(
/*=============*/
- /* out: TRUE if lock1 has to wait for
- lock2 to be removed */
- const lock_t* lock1, /* in: waiting lock */
- const lock_t* lock2) /* in: another lock; NOTE that it is
+ const lock_t* lock1, /*!< in: waiting lock */
+ const lock_t* lock2) /*!< in: another lock; NOTE that it is
assumed that this has a lock bit set
on the same record as in lock1 if the
locks are record locks */
@@ -1009,26 +1014,26 @@ lock_has_to_wait(
/*============== RECORD LOCK BASIC FUNCTIONS ============================*/
-/*************************************************************************
-Gets the number of bits in a record lock bitmap. */
+/*********************************************************************//**
+Gets the number of bits in a record lock bitmap.
+@return number of bits */
UNIV_INLINE
ulint
lock_rec_get_n_bits(
/*================*/
- /* out: number of bits */
- const lock_t* lock) /* in: record lock */
+ const lock_t* lock) /*!< in: record lock */
{
return(lock->un_member.rec_lock.n_bits);
}
-/**************************************************************************
+/**********************************************************************//**
Sets the nth bit of a record lock to TRUE. */
UNIV_INLINE
void
lock_rec_set_nth_bit(
/*=================*/
- lock_t* lock, /* in: record lock */
- ulint i) /* in: index of the bit */
+ lock_t* lock, /*!< in: record lock */
+ ulint i) /*!< in: index of the bit */
{
ulint byte_index;
ulint bit_index;
@@ -1043,16 +1048,16 @@ lock_rec_set_nth_bit(
((byte*) &lock[1])[byte_index] |= 1 << bit_index;
}
-/**************************************************************************
+/**********************************************************************//**
Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED,
-if none found. */
+if none found.
+@return bit index == heap number of the record, or ULINT_UNDEFINED if
+none found */
UNIV_INTERN
ulint
lock_rec_find_set_bit(
/*==================*/
- /* out: bit index == heap number of
- the record, or ULINT_UNDEFINED if none found */
- const lock_t* lock) /* in: record lock with at least one bit set */
+ const lock_t* lock) /*!< in: record lock with at least one bit set */
{
ulint i;
@@ -1067,14 +1072,14 @@ lock_rec_find_set_bit(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
+/**********************************************************************//**
Resets the nth bit of a record lock. */
UNIV_INLINE
void
lock_rec_reset_nth_bit(
/*===================*/
- lock_t* lock, /* in: record lock */
- ulint i) /* in: index of the bit which must be set to TRUE
+ lock_t* lock, /*!< in: record lock */
+ ulint i) /*!< in: index of the bit which must be set to TRUE
when this function is called */
{
ulint byte_index;
@@ -1090,14 +1095,14 @@ lock_rec_reset_nth_bit(
((byte*) &lock[1])[byte_index] &= ~(1 << bit_index);
}
-/*************************************************************************
-Gets the first or next record lock on a page. */
+/*********************************************************************//**
+Gets the first or next record lock on a page.
+@return next lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_next_on_page(
/*======================*/
- /* out: next lock, NULL if none exists */
- lock_t* lock) /* in: a record lock */
+ lock_t* lock) /*!< in: a record lock */
{
ulint space;
ulint page_no;
@@ -1126,16 +1131,16 @@ lock_rec_get_next_on_page(
return(lock);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the first record lock on a page, where the page is identified by its
-file address. */
+file address.
+@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first_on_page_addr(
/*============================*/
- /* out: first lock, NULL if none exists */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
lock_t* lock;
@@ -1156,16 +1161,15 @@ lock_rec_get_first_on_page_addr(
return(lock);
}
-/*************************************************************************
-Returns TRUE if there are explicit record locks on a page. */
+/*********************************************************************//**
+Returns TRUE if there are explicit record locks on a page.
+@return TRUE if there are explicit record locks on the page */
UNIV_INTERN
ibool
lock_rec_expl_exist_on_page(
/*========================*/
- /* out: TRUE if there are explicit record locks on
- the page */
- ulint space, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
ibool ret;
@@ -1182,16 +1186,15 @@ lock_rec_expl_exist_on_page(
return(ret);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the first record lock on a page, where the page is identified by a
-pointer to it. */
+pointer to it.
+@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first_on_page(
/*=======================*/
- /* out: first lock, NULL if
- none exists */
- const buf_block_t* block) /* in: buffer block */
+ const buf_block_t* block) /*!< in: buffer block */
{
ulint hash;
lock_t* lock;
@@ -1217,15 +1220,15 @@ lock_rec_get_first_on_page(
return(lock);
}
-/*************************************************************************
-Gets the next explicit lock request on a record. */
+/*********************************************************************//**
+Gets the next explicit lock request on a record.
+@return next lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_next(
/*==============*/
- /* out: next lock, NULL if none exists */
- ulint heap_no,/* in: heap number of the record */
- lock_t* lock) /* in: lock */
+ ulint heap_no,/*!< in: heap number of the record */
+ lock_t* lock) /*!< in: lock */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -1237,16 +1240,15 @@ lock_rec_get_next(
return(lock);
}
-/*************************************************************************
-Gets the first explicit lock request on a record. */
+/*********************************************************************//**
+Gets the first explicit lock request on a record.
+@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first(
/*===============*/
- /* out: first lock, NULL if
- none exists */
- const buf_block_t* block, /* in: block containing the record */
- ulint heap_no)/* in: heap number of the record */
+ const buf_block_t* block, /*!< in: block containing the record */
+ ulint heap_no)/*!< in: heap number of the record */
{
lock_t* lock;
@@ -1262,7 +1264,7 @@ lock_rec_get_first(
return(lock);
}
-/*************************************************************************
+/*********************************************************************//**
Resets the record lock bitmap to zero. NOTE: does not touch the wait_lock
pointer in the transaction! This function is used in lock object creation
and resetting. */
@@ -1270,7 +1272,7 @@ static
void
lock_rec_bitmap_reset(
/*==================*/
- lock_t* lock) /* in: record lock */
+ lock_t* lock) /*!< in: record lock */
{
ulint n_bytes;
@@ -1286,15 +1288,15 @@ lock_rec_bitmap_reset(
memset(&lock[1], 0, n_bytes);
}
-/*************************************************************************
-Copies a record lock to heap. */
+/*********************************************************************//**
+Copies a record lock to heap.
+@return copy of lock */
static
lock_t*
lock_rec_copy(
/*==========*/
- /* out: copy of lock */
- const lock_t* lock, /* in: record lock */
- mem_heap_t* heap) /* in: memory heap */
+ const lock_t* lock, /*!< in: record lock */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ulint size;
@@ -1305,16 +1307,15 @@ lock_rec_copy(
return(mem_heap_dup(heap, lock, size));
}
-/*************************************************************************
-Gets the previous record lock set on a record. */
+/*********************************************************************//**
+Gets the previous record lock set on a record.
+@return previous lock on the same record, NULL if none exists */
UNIV_INTERN
const lock_t*
lock_rec_get_prev(
/*==============*/
- /* out: previous lock on the same
- record, NULL if none exists */
- const lock_t* in_lock,/* in: record lock */
- ulint heap_no)/* in: heap number of the record */
+ const lock_t* in_lock,/*!< in: record lock */
+ ulint heap_no)/*!< in: heap number of the record */
{
lock_t* lock;
ulint space;
@@ -1348,16 +1349,16 @@ lock_rec_get_prev(
/*============= FUNCTIONS FOR ANALYZING TABLE LOCK QUEUE ================*/
-/*************************************************************************
-Checks if a transaction has the specified table lock, or stronger. */
+/*********************************************************************//**
+Checks if a transaction has the specified table lock, or stronger.
+@return lock or NULL */
UNIV_INLINE
lock_t*
lock_table_has(
/*===========*/
- /* out: lock or NULL */
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table */
- enum lock_mode mode) /* in: lock mode */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table */
+ enum lock_mode mode) /*!< in: lock mode */
{
lock_t* lock;
@@ -1388,23 +1389,23 @@ lock_table_has(
/*============= FUNCTIONS FOR ANALYZING RECORD LOCK QUEUE ================*/
-/*************************************************************************
+/*********************************************************************//**
Checks if a transaction has a GRANTED explicit lock on rec stronger or equal
-to precise_mode. */
+to precise_mode.
+@return lock or NULL */
UNIV_INLINE
lock_t*
lock_rec_has_expl(
/*==============*/
- /* out: lock or NULL */
- ulint precise_mode,/* in: LOCK_S or LOCK_X
+ ulint precise_mode,/*!< in: LOCK_S or LOCK_X
possibly ORed to LOCK_GAP or
LOCK_REC_NOT_GAP, for a
supremum record we regard this
always a gap type request */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- trx_t* trx) /* in: transaction */
+ ulint heap_no,/*!< in: heap number of the record */
+ trx_t* trx) /*!< in: transaction */
{
lock_t* lock;
@@ -1438,25 +1439,24 @@ lock_rec_has_expl(
}
#ifdef UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
-/*************************************************************************
-Checks if some other transaction has a lock request in the queue. */
+/*********************************************************************//**
+Checks if some other transaction has a lock request in the queue.
+@return lock or NULL */
static
lock_t*
lock_rec_other_has_expl_req(
/*========================*/
- /* out: lock or NULL */
- enum lock_mode mode, /* in: LOCK_S or LOCK_X */
- ulint gap, /* in: LOCK_GAP if also gap
+ enum lock_mode mode, /*!< in: LOCK_S or LOCK_X */
+ ulint gap, /*!< in: LOCK_GAP if also gap
locks are taken into account,
or 0 if not */
- ulint wait, /* in: LOCK_WAIT if also
+ ulint wait, /*!< in: LOCK_WAIT if also
waiting locks are taken into
account, or 0 if not */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- const trx_t* trx) /* in: transaction, or NULL if
+ ulint heap_no,/*!< in: heap number of the record */
+ const trx_t* trx) /*!< in: transaction, or NULL if
requests by all transactions
are taken into account */
{
@@ -1485,25 +1485,24 @@ lock_rec_other_has_expl_req(
return(NULL);
}
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
-/*************************************************************************
+/*********************************************************************//**
Checks if some other transaction has a conflicting explicit lock request
-in the queue, so that we have to wait. */
+in the queue, so that we have to wait.
+@return lock or NULL */
static
lock_t*
lock_rec_other_has_conflicting(
/*===========================*/
- /* out: lock or NULL */
- enum lock_mode mode, /* in: LOCK_S or LOCK_X,
+ enum lock_mode mode, /*!< in: LOCK_S or LOCK_X,
possibly ORed to LOCK_GAP or
LOC_REC_NOT_GAP,
LOCK_INSERT_INTENTION */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- trx_t* trx) /* in: our transaction */
+ ulint heap_no,/*!< in: heap number of the record */
+ trx_t* trx) /*!< in: our transaction */
{
lock_t* lock;
@@ -1538,19 +1537,19 @@ lock_rec_other_has_conflicting(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Looks for a suitable type record lock struct by the same trx on the same page.
This can be used to save space when a new record lock should be set on a page:
-no new struct is needed, if a suitable old is found. */
+no new struct is needed, if a suitable old is found.
+@return lock or NULL */
UNIV_INLINE
lock_t*
lock_rec_find_similar_on_page(
/*==========================*/
- /* out: lock or NULL */
- ulint type_mode, /* in: lock type_mode field */
- ulint heap_no, /* in: heap number of the record */
- lock_t* lock, /* in: lock_rec_get_first_on_page() */
- const trx_t* trx) /* in: transaction */
+ ulint type_mode, /*!< in: lock type_mode field */
+ ulint heap_no, /*!< in: heap number of the record */
+ lock_t* lock, /*!< in: lock_rec_get_first_on_page() */
+ const trx_t* trx) /*!< in: transaction */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -1568,18 +1567,17 @@ lock_rec_find_similar_on_page(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if some transaction has an implicit x-lock on a record in a secondary
-index. */
+index.
+@return transaction which has the x-lock, or NULL */
static
trx_t*
lock_sec_rec_some_has_impl_off_kernel(
/*==================================*/
- /* out: transaction which has the x-lock, or
- NULL */
- 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_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: secondary index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
const page_t* page = page_align(rec);
@@ -1616,7 +1614,7 @@ lock_sec_rec_some_has_impl_off_kernel(
return(row_vers_impl_x_locked_off_kernel(rec, index, offsets));
}
-/*************************************************************************
+/*********************************************************************//**
Return approximate number or record locks (bits set in the bitmap) for
this transaction. Since delete-marked records may be removed, the
record count will not be precise. */
@@ -1624,7 +1622,7 @@ UNIV_INTERN
ulint
lock_number_of_rows_locked(
/*=======================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
lock_t* lock;
ulint n_records = 0;
@@ -1652,22 +1650,22 @@ lock_number_of_rows_locked(
/*============== RECORD LOCK CREATION AND QUEUE MANAGEMENT =============*/
-/*************************************************************************
+/*********************************************************************//**
Creates a new record lock and inserts it to the lock queue. Does NOT check
-for deadlocks or lock compatibility! */
+for deadlocks or lock compatibility!
+@return created lock */
static
lock_t*
lock_rec_create(
/*============*/
- /* out: created lock */
- ulint type_mode,/* in: lock mode and wait
+ ulint type_mode,/*!< in: lock mode and wait
flag, type is ignored and
replaced by LOCK_REC */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- dict_index_t* index, /* in: index of record */
- trx_t* trx) /* in: transaction */
+ ulint heap_no,/*!< in: heap number of the record */
+ dict_index_t* index, /*!< in: index of record */
+ trx_t* trx) /*!< in: transaction */
{
lock_t* lock;
ulint page_no;
@@ -1729,23 +1727,18 @@ lock_rec_create(
return(lock);
}
-/*************************************************************************
+/*********************************************************************//**
Enqueues a waiting request for a lock which cannot be granted immediately.
-Checks for deadlocks. */
+Checks for deadlocks.
+@return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or
+DB_SUCCESS; DB_SUCCESS means that there was a deadlock, but another
+transaction was chosen as a victim, and we got the lock immediately:
+no need to wait then */
static
ulint
lock_rec_enqueue_waiting(
/*=====================*/
- /* out: DB_LOCK_WAIT,
- DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED, or
- DB_SUCCESS; DB_SUCCESS means
- that there was a deadlock, but
- another transaction was chosen
- as a victim, and we got the
- lock immediately: no need to
- wait then */
- ulint type_mode,/* in: lock mode this
+ ulint type_mode,/*!< in: lock mode this
transaction is requesting:
LOCK_S or LOCK_X, possibly
ORed with LOCK_GAP or
@@ -1754,14 +1747,16 @@ lock_rec_enqueue_waiting(
waiting lock request is set
when performing an insert of
an index record */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- dict_index_t* index, /* in: index of record */
- que_thr_t* thr) /* in: query thread */
+ ulint heap_no,/*!< in: heap number of the record */
+ dict_index_t* index, /*!< in: index of record */
+ que_thr_t* thr) /*!< in: query thread */
{
lock_t* lock;
trx_t* trx;
+ ulint sec;
+ ulint ms;
ut_ad(mutex_own(&kernel_mutex));
@@ -1820,6 +1815,10 @@ lock_rec_enqueue_waiting(
trx->que_state = TRX_QUE_LOCK_WAIT;
trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
+ }
ut_a(que_thr_stop(thr));
@@ -1834,26 +1833,26 @@ lock_rec_enqueue_waiting(
return(DB_LOCK_WAIT);
}
-/*************************************************************************
+/*********************************************************************//**
Adds a record lock request in the record queue. The request is normally
added as the last in the queue, but if there are no waiting lock requests
on the record, and the request to be added is not a waiting request, we
can reuse a suitable record lock object already existing on the same page,
just setting the appropriate bit in its bitmap. This is a low-level function
-which does NOT check for deadlocks or lock compatibility! */
+which does NOT check for deadlocks or lock compatibility!
+@return lock where the bit was set */
static
lock_t*
lock_rec_add_to_queue(
/*==================*/
- /* out: lock where the bit was set */
- ulint type_mode,/* in: lock mode, wait, gap
+ ulint type_mode,/*!< in: lock mode, wait, gap
etc. flags; type is ignored
and replaced by LOCK_REC */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- dict_index_t* index, /* in: index of record */
- trx_t* trx) /* in: transaction */
+ ulint heap_no,/*!< in: heap number of the record */
+ dict_index_t* index, /*!< in: index of record */
+ trx_t* trx) /*!< in: transaction */
{
lock_t* lock;
@@ -1930,30 +1929,30 @@ somebody_waits:
return(lock_rec_create(type_mode, block, heap_no, index, trx));
}
-/*************************************************************************
+/*********************************************************************//**
This is a fast routine for locking a record in the most common cases:
there are no explicit locks on the page, or there is just one lock, owned
by this transaction, and of the right type_mode. This is a low-level function
which does NOT look at implicit locks! Checks lock compatibility within
explicit locks. This function sets a normal next-key lock, or in the case of
-a page supremum record, a gap type lock. */
+a page supremum record, a gap type lock.
+@return TRUE if locking succeeded */
UNIV_INLINE
ibool
lock_rec_lock_fast(
/*===============*/
- /* out: TRUE if locking succeeded */
- ibool impl, /* in: if TRUE, no lock is set
+ ibool impl, /*!< in: if TRUE, no lock is set
if no wait is necessary: we
assume that the caller will
set an implicit lock */
- ulint mode, /* in: lock mode: LOCK_X or
+ ulint mode, /*!< in: lock mode: LOCK_X or
LOCK_S possibly ORed to either
LOCK_GAP or LOCK_REC_NOT_GAP */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of record */
- dict_index_t* index, /* in: index of record */
- que_thr_t* thr) /* in: query thread */
+ ulint heap_no,/*!< in: heap number of record */
+ dict_index_t* index, /*!< in: index of record */
+ que_thr_t* thr) /*!< in: query thread */
{
lock_t* lock;
trx_t* trx;
@@ -2005,29 +2004,28 @@ lock_rec_lock_fast(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
This is the general, and slower, routine for locking a record. This is a
low-level function which does NOT look at implicit locks! Checks lock
compatibility within explicit locks. This function sets a normal next-key
-lock, or in the case of a page supremum record, a gap type lock. */
+lock, or in the case of a page supremum record, a gap type lock.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
static
ulint
lock_rec_lock_slow(
/*===============*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, or error code */
- ibool impl, /* in: if TRUE, no lock is set
+ ibool impl, /*!< in: if TRUE, no lock is set
if no wait is necessary: we
assume that the caller will
set an implicit lock */
- ulint mode, /* in: lock mode: LOCK_X or
+ ulint mode, /*!< in: lock mode: LOCK_X or
LOCK_S possibly ORed to either
LOCK_GAP or LOCK_REC_NOT_GAP */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of record */
- dict_index_t* index, /* in: index of record */
- que_thr_t* thr) /* in: query thread */
+ ulint heap_no,/*!< in: heap number of record */
+ dict_index_t* index, /*!< in: index of record */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
ulint err;
@@ -2072,30 +2070,29 @@ lock_rec_lock_slow(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Tries to lock the specified record in the mode requested. If not immediately
possible, enqueues a waiting lock request. This is a low-level function
which does NOT look at implicit locks! Checks lock compatibility within
explicit locks. This function sets a normal next-key lock, or in the case
-of a page supremum record, a gap type lock. */
+of a page supremum record, a gap type lock.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
static
ulint
lock_rec_lock(
/*==========*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, or error code */
- ibool impl, /* in: if TRUE, no lock is set
+ ibool impl, /*!< in: if TRUE, no lock is set
if no wait is necessary: we
assume that the caller will
set an implicit lock */
- ulint mode, /* in: lock mode: LOCK_X or
+ ulint mode, /*!< in: lock mode: LOCK_X or
LOCK_S possibly ORed to either
LOCK_GAP or LOCK_REC_NOT_GAP */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of record */
- dict_index_t* index, /* in: index of record */
- que_thr_t* thr) /* in: query thread */
+ ulint heap_no,/*!< in: heap number of record */
+ dict_index_t* index, /*!< in: index of record */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -2124,14 +2121,14 @@ lock_rec_lock(
return(err);
}
-/*************************************************************************
-Checks if a waiting record lock request still has to wait in a queue. */
+/*********************************************************************//**
+Checks if a waiting record lock request still has to wait in a queue.
+@return TRUE if still has to wait */
static
ibool
lock_rec_has_to_wait_in_queue(
/*==========================*/
- /* out: TRUE if still has to wait */
- lock_t* wait_lock) /* in: waiting record lock */
+ lock_t* wait_lock) /*!< in: waiting record lock */
{
lock_t* lock;
ulint space;
@@ -2162,14 +2159,14 @@ lock_rec_has_to_wait_in_queue(
return(FALSE);
}
-/*****************************************************************
+/*************************************************************//**
Grants a lock to a waiting lock request and releases the waiting
transaction. */
static
void
lock_grant(
/*=======*/
- lock_t* lock) /* in/out: waiting lock request */
+ lock_t* lock) /*!< in/out: waiting lock request */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -2207,7 +2204,7 @@ lock_grant(
}
}
-/*****************************************************************
+/*************************************************************//**
Cancels a waiting record lock request and releases the waiting transaction
that requested it. NOTE: does NOT check if waiting lock requests behind this
one can now be granted! */
@@ -2215,7 +2212,7 @@ static
void
lock_rec_cancel(
/*============*/
- lock_t* lock) /* in: waiting record lock request */
+ lock_t* lock) /*!< in: waiting record lock request */
{
ut_ad(mutex_own(&kernel_mutex));
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -2232,7 +2229,7 @@ lock_rec_cancel(
trx_end_lock_wait(lock->trx);
}
-/*****************************************************************
+/*************************************************************//**
Removes a record lock request, waiting or granted, from the queue and
grants locks to other transactions in the queue if they now are entitled
to a lock. NOTE: all record locks contained in in_lock are removed. */
@@ -2240,7 +2237,7 @@ static
void
lock_rec_dequeue_from_page(
/*=======================*/
- lock_t* in_lock)/* in: record lock object: all record locks which
+ lock_t* in_lock)/*!< in: record lock object: all record locks which
are contained in this lock object are removed;
transactions waiting behind will get their lock
requests granted, if they are now qualified to it */
@@ -2280,13 +2277,13 @@ lock_rec_dequeue_from_page(
}
}
-/*****************************************************************
+/*************************************************************//**
Removes a record lock request, waiting or granted, from the queue. */
static
void
lock_rec_discard(
/*=============*/
- lock_t* in_lock)/* in: record lock object: all record locks which
+ lock_t* in_lock)/*!< in: record lock object: all record locks which
are contained in this lock object are removed */
{
ulint space;
@@ -2307,7 +2304,7 @@ lock_rec_discard(
UT_LIST_REMOVE(trx_locks, trx->trx_locks, in_lock);
}
-/*****************************************************************
+/*************************************************************//**
Removes record lock objects set on an index page which is discarded. This
function does not move locks, or check for waiting locks, therefore the
lock bitmaps must already be reset when this function is called. */
@@ -2315,7 +2312,7 @@ static
void
lock_rec_free_all_from_discard_page(
/*================================*/
- const buf_block_t* block) /* in: page to be discarded */
+ const buf_block_t* block) /*!< in: page to be discarded */
{
ulint space;
ulint page_no;
@@ -2343,16 +2340,16 @@ lock_rec_free_all_from_discard_page(
/*============= RECORD LOCK MOVING AND INHERITING ===================*/
-/*****************************************************************
+/*************************************************************//**
Resets the lock bits for a single record. Releases transactions waiting for
lock requests here. */
static
void
lock_rec_reset_and_release_wait(
/*============================*/
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no)/* in: heap number of record */
+ ulint heap_no)/*!< in: heap number of record */
{
lock_t* lock;
@@ -2371,7 +2368,7 @@ lock_rec_reset_and_release_wait(
}
}
-/*****************************************************************
+/*************************************************************//**
Makes a record to inherit the locks (except LOCK_INSERT_INTENTION type)
of another record as gap type locks, but does not reset the lock bits of
the other record. Also waiting lock requests on rec are inherited as
@@ -2380,15 +2377,15 @@ static
void
lock_rec_inherit_to_gap(
/*====================*/
- const buf_block_t* heir_block, /* in: block containing the
+ const buf_block_t* heir_block, /*!< in: block containing the
record which inherits */
- const buf_block_t* block, /* in: block containing the
+ const buf_block_t* block, /*!< in: block containing the
record from which inherited;
does NOT reset the locks on
this record */
- ulint heir_heap_no, /* in: heap_no of the
+ ulint heir_heap_no, /*!< in: heap_no of the
inheriting record */
- ulint heap_no) /* in: heap_no of the
+ ulint heap_no) /*!< in: heap_no of the
donating record */
{
lock_t* lock;
@@ -2420,7 +2417,7 @@ lock_rec_inherit_to_gap(
}
}
-/*****************************************************************
+/*************************************************************//**
Makes a record to inherit the gap locks (except LOCK_INSERT_INTENTION type)
of another record as gap type locks, but does not reset the lock bits of the
other record. Also waiting lock requests are inherited as GRANTED gap locks. */
@@ -2428,10 +2425,10 @@ static
void
lock_rec_inherit_to_gap_if_gap_lock(
/*================================*/
- const buf_block_t* block, /* in: buffer block */
- ulint heir_heap_no, /* in: heap_no of
+ const buf_block_t* block, /*!< in: buffer block */
+ ulint heir_heap_no, /*!< in: heap_no of
record which inherits */
- ulint heap_no) /* in: heap_no of record
+ ulint heap_no) /*!< in: heap_no of record
from which inherited;
does NOT reset the locks
on this record */
@@ -2457,22 +2454,22 @@ lock_rec_inherit_to_gap_if_gap_lock(
}
}
-/*****************************************************************
+/*************************************************************//**
Moves the locks of a record to another record and resets the lock bits of
the donating record. */
static
void
lock_rec_move(
/*==========*/
- const buf_block_t* receiver, /* in: buffer block containing
+ const buf_block_t* receiver, /*!< in: buffer block containing
the receiving record */
- const buf_block_t* donator, /* in: buffer block containing
+ const buf_block_t* donator, /*!< in: buffer block containing
the donating record */
- ulint receiver_heap_no,/* in: heap_no of the record
+ ulint receiver_heap_no,/*!< in: heap_no of the record
which gets the locks; there
must be no lock requests
on it! */
- ulint donator_heap_no)/* in: heap_no of the record
+ ulint donator_heap_no)/*!< in: heap_no of the record
which gives the locks */
{
lock_t* lock;
@@ -2503,7 +2500,7 @@ lock_rec_move(
ut_ad(lock_rec_get_first(donator, donator_heap_no) == NULL);
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when we have reorganized a page. NOTE: we copy
also the locks set on the infimum of the page; the infimum may carry
locks if an update of a record is occurring on the page, and its locks
@@ -2512,9 +2509,9 @@ UNIV_INTERN
void
lock_move_reorganize_page(
/*======================*/
- const buf_block_t* block, /* in: old index page, now
+ const buf_block_t* block, /*!< in: old index page, now
reorganized */
- const buf_block_t* oblock) /* in: copy of the old, not
+ const buf_block_t* oblock) /*!< in: copy of the old, not
reorganized page */
{
lock_t* lock;
@@ -2647,20 +2644,21 @@ lock_move_reorganize_page(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
#endif
}
-/*****************************************************************
+/*************************************************************//**
Moves the explicit locks on user records to another page if a record
list end is moved to another page. */
UNIV_INTERN
void
lock_move_rec_list_end(
/*===================*/
- const buf_block_t* new_block, /* in: index page to move to */
- const buf_block_t* block, /* in: index page */
- const rec_t* rec) /* in: record on page: this
+ const buf_block_t* new_block, /*!< in: index page to move to */
+ const buf_block_t* block, /*!< in: index page */
+ const rec_t* rec) /*!< in: record on page: this
is the first record moved */
{
lock_t* lock;
@@ -2736,25 +2734,27 @@ lock_move_rec_list_end(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
ut_ad(lock_rec_validate_page(buf_block_get_space(new_block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(new_block)));
#endif
}
-/*****************************************************************
+/*************************************************************//**
Moves the explicit locks on user records to another page if a record
list start is moved to another page. */
UNIV_INTERN
void
lock_move_rec_list_start(
/*=====================*/
- const buf_block_t* new_block, /* in: index page to move to */
- const buf_block_t* block, /* in: index page */
- const rec_t* rec, /* in: record on page:
+ const buf_block_t* new_block, /*!< in: index page to move to */
+ const buf_block_t* block, /*!< in: index page */
+ const rec_t* rec, /*!< in: record on page:
this is the first
record NOT copied */
- const rec_t* old_end) /* in: old
+ const rec_t* old_end) /*!< in: old
previous-to-last
record on new_page
before the records
@@ -2847,18 +2847,19 @@ lock_move_rec_list_start(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
#endif
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is split to the right. */
UNIV_INTERN
void
lock_update_split_right(
/*====================*/
- const buf_block_t* right_block, /* in: right page */
- const buf_block_t* left_block) /* in: left page */
+ const buf_block_t* right_block, /*!< in: right page */
+ const buf_block_t* left_block) /*!< in: left page */
{
ulint heap_no = lock_get_min_heap_no(right_block);
@@ -2879,19 +2880,19 @@ lock_update_split_right(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is merged to the right. */
UNIV_INTERN
void
lock_update_merge_right(
/*====================*/
- const buf_block_t* right_block, /* in: right page to
+ const buf_block_t* right_block, /*!< in: right page to
which merged */
- const rec_t* orig_succ, /* in: original
+ const rec_t* orig_succ, /*!< in: original
successor of infimum
on the right page
before merge */
- const buf_block_t* left_block) /* in: merged index
+ const buf_block_t* left_block) /*!< in: merged index
page which will be
discarded */
{
@@ -2916,7 +2917,7 @@ lock_update_merge_right(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when the root page is copied to another in
btr_root_raise_and_insert. Note that we leave lock structs on the
root page, even though they do not make sense on other than leaf
@@ -2927,8 +2928,8 @@ UNIV_INTERN
void
lock_update_root_raise(
/*===================*/
- const buf_block_t* block, /* in: index page to which copied */
- const buf_block_t* root) /* in: root page */
+ const buf_block_t* block, /*!< in: index page to which copied */
+ const buf_block_t* root) /*!< in: root page */
{
lock_mutex_enter_kernel();
@@ -2940,16 +2941,16 @@ lock_update_root_raise(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is copied to another and the original page
is removed from the chain of leaf pages, except if page is the root! */
UNIV_INTERN
void
lock_update_copy_and_discard(
/*=========================*/
- const buf_block_t* new_block, /* in: index page to
+ const buf_block_t* new_block, /*!< in: index page to
which copied */
- const buf_block_t* block) /* in: index page;
+ const buf_block_t* block) /*!< in: index page;
NOT the root! */
{
lock_mutex_enter_kernel();
@@ -2964,14 +2965,14 @@ lock_update_copy_and_discard(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is split to the left. */
UNIV_INTERN
void
lock_update_split_left(
/*===================*/
- const buf_block_t* right_block, /* in: right page */
- const buf_block_t* left_block) /* in: left page */
+ const buf_block_t* right_block, /*!< in: right page */
+ const buf_block_t* left_block) /*!< in: left page */
{
ulint heap_no = lock_get_min_heap_no(right_block);
@@ -2986,18 +2987,18 @@ lock_update_split_left(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is merged to the left. */
UNIV_INTERN
void
lock_update_merge_left(
/*===================*/
- const buf_block_t* left_block, /* in: left page to
+ const buf_block_t* left_block, /*!< in: left page to
which merged */
- const rec_t* orig_pred, /* in: original predecessor
+ const rec_t* orig_pred, /*!< in: original predecessor
of supremum on the left page
before merge */
- const buf_block_t* right_block) /* in: merged index page
+ const buf_block_t* right_block) /*!< in: merged index page
which will be discarded */
{
const rec_t* left_next_rec;
@@ -3035,22 +3036,22 @@ lock_update_merge_left(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Resets the original locks on heir and replaces them with gap type locks
inherited from rec. */
UNIV_INTERN
void
lock_rec_reset_and_inherit_gap_locks(
/*=================================*/
- const buf_block_t* heir_block, /* in: block containing the
+ const buf_block_t* heir_block, /*!< in: block containing the
record which inherits */
- const buf_block_t* block, /* in: block containing the
+ const buf_block_t* block, /*!< in: block containing the
record from which inherited;
does NOT reset the locks on
this record */
- ulint heir_heap_no, /* in: heap_no of the
+ ulint heir_heap_no, /*!< in: heap_no of the
inheriting record */
- ulint heap_no) /* in: heap_no of the
+ ulint heap_no) /*!< in: heap_no of the
donating record */
{
mutex_enter(&kernel_mutex);
@@ -3062,17 +3063,17 @@ lock_rec_reset_and_inherit_gap_locks(
mutex_exit(&kernel_mutex);
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is discarded. */
UNIV_INTERN
void
lock_update_discard(
/*================*/
- const buf_block_t* heir_block, /* in: index page
+ const buf_block_t* heir_block, /*!< in: index page
which will inherit the locks */
- ulint heir_heap_no, /* in: heap_no of the record
+ ulint heir_heap_no, /*!< in: heap_no of the record
which will inherit the locks */
- const buf_block_t* block) /* in: index page
+ const buf_block_t* block) /*!< in: index page
which will be discarded */
{
const page_t* page = block->frame;
@@ -3125,14 +3126,14 @@ lock_update_discard(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a new user record is inserted. */
UNIV_INTERN
void
lock_update_insert(
/*===============*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec) /* in: the inserted record */
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec) /*!< in: the inserted record */
{
ulint receiver_heap_no;
ulint donator_heap_no;
@@ -3158,14 +3159,14 @@ lock_update_insert(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a record is removed. */
UNIV_INTERN
void
lock_update_delete(
/*===============*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec) /* in: the record to be removed */
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec) /*!< in: the record to be removed */
{
const page_t* page = block->frame;
ulint heap_no;
@@ -3198,7 +3199,7 @@ lock_update_delete(
lock_mutex_exit_kernel();
}
-/*************************************************************************
+/*********************************************************************//**
Stores on the page infimum record the explicit locks of another record.
This function is used to store the lock state of a record when it is
updated and the size of the record changes in the update. The record
@@ -3209,8 +3210,8 @@ UNIV_INTERN
void
lock_rec_store_on_page_infimum(
/*===========================*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec) /* in: record whose lock state
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec) /*!< in: record whose lock state
is stored on the infimum
record of the same page; lock
bits are reset on the
@@ -3227,17 +3228,17 @@ lock_rec_store_on_page_infimum(
lock_mutex_exit_kernel();
}
-/*************************************************************************
+/*********************************************************************//**
Restores the state of explicit lock requests on a single record, where the
state was stored on the infimum of the page. */
UNIV_INTERN
void
lock_rec_restore_from_page_infimum(
/*===============================*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record whose lock state
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record whose lock state
is restored */
- const buf_block_t* donator)/* in: page (rec is not
+ const buf_block_t* donator)/*!< in: page (rec is not
necessarily on this page)
whose infimum stored the lock
state; lock bits are reset on
@@ -3254,18 +3255,17 @@ lock_rec_restore_from_page_infimum(
/*=========== DEADLOCK CHECKING ======================================*/
-/************************************************************************
-Checks if a lock request results in a deadlock. */
+/********************************************************************//**
+Checks if a lock request results in a deadlock.
+@return TRUE if a deadlock was detected and we chose trx as a victim;
+FALSE if no deadlock, or there was a deadlock, but we chose other
+transaction(s) as victim(s) */
static
ibool
lock_deadlock_occurs(
/*=================*/
- /* out: TRUE if a deadlock was detected and we
- chose trx as a victim; FALSE if no deadlock, or
- there was a deadlock, but we chose other
- transaction(s) as victim(s) */
- lock_t* lock, /* in: lock the transaction is requesting */
- trx_t* trx) /* in: transaction */
+ lock_t* lock, /*!< in: lock the transaction is requesting */
+ trx_t* trx) /*!< in: transaction */
{
dict_table_t* table;
dict_index_t* index;
@@ -3317,27 +3317,24 @@ retry:
return(FALSE);
}
-/************************************************************************
-Looks recursively for a deadlock. */
+/********************************************************************//**
+Looks recursively for a deadlock.
+@return 0 if no deadlock found, LOCK_VICTIM_IS_START if there was a
+deadlock and we chose 'start' as the victim, LOCK_VICTIM_IS_OTHER if a
+deadlock was found and we chose some other trx as a victim: we must do
+the search again in this last case because there may be another
+deadlock! */
static
ulint
lock_deadlock_recursive(
/*====================*/
- /* out: 0 if no deadlock found,
- LOCK_VICTIM_IS_START if there was a deadlock
- and we chose 'start' as the victim,
- LOCK_VICTIM_IS_OTHER if a deadlock
- was found and we chose some other trx as a
- victim: we must do the search again in this
- last case because there may be another
- deadlock! */
- trx_t* start, /* in: recursion starting point */
- trx_t* trx, /* in: a transaction waiting for a lock */
- lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
- ulint* cost, /* in/out: number of calculation steps thus
+ trx_t* start, /*!< in: recursion starting point */
+ trx_t* trx, /*!< in: a transaction waiting for a lock */
+ lock_t* wait_lock, /*!< in: the lock trx is waiting to be granted */
+ ulint* cost, /*!< in/out: number of calculation steps thus
far: if this exceeds LOCK_MAX_N_STEPS_...
we return LOCK_VICTIM_IS_START */
- ulint depth) /* in: recursion depth: if this exceeds
+ ulint depth) /*!< in: recursion depth: if this exceeds
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
return LOCK_VICTIM_IS_START */
{
@@ -3513,18 +3510,18 @@ lock_deadlock_recursive(
/*========================= TABLE LOCKS ==============================*/
-/*************************************************************************
+/*********************************************************************//**
Creates a table lock object and adds it as the last in the lock queue
-of the table. Does NOT check for deadlocks or lock compatibility. */
+of the table. Does NOT check for deadlocks or lock compatibility.
+@return own: new lock object */
UNIV_INLINE
lock_t*
lock_table_create(
/*==============*/
- /* out, own: new lock object */
- dict_table_t* table, /* in: database table in dictionary cache */
- ulint type_mode,/* in: lock mode possibly ORed with
+ dict_table_t* table, /*!< in: database table in dictionary cache */
+ ulint type_mode,/*!< in: lock mode possibly ORed with
LOCK_WAIT */
- trx_t* trx) /* in: trx */
+ trx_t* trx) /*!< in: trx */
{
lock_t* lock;
@@ -3566,7 +3563,7 @@ lock_table_create(
return(lock);
}
-/*****************************************************************
+/*************************************************************//**
Removes a table lock request from the queue and the trx list of locks;
this is a low-level function which does NOT check if waiting requests
can now be granted. */
@@ -3574,7 +3571,7 @@ UNIV_INLINE
void
lock_table_remove_low(
/*==================*/
- lock_t* lock) /* in: table lock */
+ lock_t* lock) /*!< in: table lock */
{
trx_t* trx;
dict_table_t* table;
@@ -3603,7 +3600,8 @@ lock_table_remove_low(
and lock_grant()). Therefore it can be empty and we
need to check for that. */
- if (!ib_vector_is_empty(trx->autoinc_locks)) {
+ if (!lock_get_wait(lock)
+ && !ib_vector_is_empty(trx->autoinc_locks)) {
lock_t* autoinc_lock;
autoinc_lock = ib_vector_pop(trx->autoinc_locks);
@@ -3618,26 +3616,26 @@ lock_table_remove_low(
UT_LIST_REMOVE(un_member.tab_lock.locks, table->locks, lock);
}
-/*************************************************************************
+/*********************************************************************//**
Enqueues a waiting request for a table lock which cannot be granted
-immediately. Checks for deadlocks. */
+immediately. Checks for deadlocks.
+@return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or
+DB_SUCCESS; DB_SUCCESS means that there was a deadlock, but another
+transaction was chosen as a victim, and we got the lock immediately:
+no need to wait then */
static
ulint
lock_table_enqueue_waiting(
/*=======================*/
- /* out: DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED, or DB_SUCCESS;
- DB_SUCCESS means that there was a deadlock,
- but another transaction was chosen as a
- victim, and we got the lock immediately:
- no need to wait then */
- ulint mode, /* in: lock mode this transaction is
+ ulint mode, /*!< in: lock mode this transaction is
requesting */
- dict_table_t* table, /* in: table */
- que_thr_t* thr) /* in: query thread */
+ dict_table_t* table, /*!< in: table */
+ que_thr_t* thr) /*!< in: query thread */
{
lock_t* lock;
trx_t* trx;
+ ulint sec;
+ ulint ms;
ut_ad(mutex_own(&kernel_mutex));
@@ -3678,8 +3676,10 @@ lock_table_enqueue_waiting(
if (lock_deadlock_occurs(lock, trx)) {
- lock_reset_lock_and_trx_wait(lock);
+ /* The order here is important, we don't want to
+ lose the state of the lock before calling remove. */
lock_table_remove_low(lock);
+ lock_reset_lock_and_trx_wait(lock);
return(DB_DEADLOCK);
}
@@ -3691,6 +3691,10 @@ lock_table_enqueue_waiting(
return(DB_SUCCESS);
}
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
+ }
trx->que_state = TRX_QUE_LOCK_WAIT;
trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
@@ -3700,19 +3704,19 @@ lock_table_enqueue_waiting(
return(DB_LOCK_WAIT);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if other transactions have an incompatible mode lock request in
the lock queue. */
UNIV_INLINE
ibool
lock_table_other_has_incompatible(
/*==============================*/
- trx_t* trx, /* in: transaction, or NULL if all
+ trx_t* trx, /*!< in: transaction, or NULL if all
transactions should be included */
- ulint wait, /* in: LOCK_WAIT if also waiting locks are
+ ulint wait, /*!< in: LOCK_WAIT if also waiting locks are
taken into account, or 0 if not */
- dict_table_t* table, /* in: table */
- enum lock_mode mode) /* in: lock mode */
+ dict_table_t* table, /*!< in: table */
+ enum lock_mode mode) /*!< in: lock mode */
{
lock_t* lock;
@@ -3735,20 +3739,19 @@ lock_table_other_has_incompatible(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Locks the specified database table in the mode given. If the lock cannot
-be granted immediately, the query thread is put to wait. */
+be granted immediately, the query thread is put to wait.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_table(
/*=======*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing */
- dict_table_t* table, /* in: database table in dictionary cache */
- enum lock_mode mode, /* in: lock mode */
- que_thr_t* thr) /* in: query thread */
+ dict_table_t* table, /*!< in: database table in dictionary cache */
+ enum lock_mode mode, /*!< in: lock mode */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
ulint err;
@@ -3799,40 +3802,14 @@ lock_table(
return(DB_SUCCESS);
}
-/*************************************************************************
-Checks if there are any locks set on the table. */
-UNIV_INTERN
-ibool
-lock_is_on_table(
-/*=============*/
- /* out: TRUE if there are lock(s) */
- dict_table_t* table) /* in: database table in dictionary cache */
-{
- ibool ret;
-
- ut_ad(table);
-
- lock_mutex_enter_kernel();
-
- if (UT_LIST_GET_LAST(table->locks)) {
- ret = TRUE;
- } else {
- ret = FALSE;
- }
-
- lock_mutex_exit_kernel();
-
- return(ret);
-}
-
-/*************************************************************************
-Checks if a waiting table lock request still has to wait in a queue. */
+/*********************************************************************//**
+Checks if a waiting table lock request still has to wait in a queue.
+@return TRUE if still has to wait */
static
ibool
lock_table_has_to_wait_in_queue(
/*============================*/
- /* out: TRUE if still has to wait */
- lock_t* wait_lock) /* in: waiting table lock */
+ lock_t* wait_lock) /*!< in: waiting table lock */
{
dict_table_t* table;
lock_t* lock;
@@ -3857,7 +3834,7 @@ lock_table_has_to_wait_in_queue(
return(FALSE);
}
-/*****************************************************************
+/*************************************************************//**
Removes a table lock request, waiting or granted, from the queue and grants
locks to other transactions in the queue, if they now are entitled to a
lock. */
@@ -3865,7 +3842,7 @@ static
void
lock_table_dequeue(
/*===============*/
- lock_t* in_lock)/* in: table lock object; transactions waiting
+ lock_t* in_lock)/*!< in: table lock object; transactions waiting
behind will get their lock requests granted, if
they are now qualified to it */
{
@@ -3896,7 +3873,7 @@ lock_table_dequeue(
/*=========================== LOCK RELEASE ==============================*/
-/*****************************************************************
+/*************************************************************//**
Removes a granted record lock of a transaction from the queue and grants
locks to other transactions waiting in the queue if they now are entitled
to a lock. */
@@ -3904,11 +3881,11 @@ UNIV_INTERN
void
lock_rec_unlock(
/*============*/
- trx_t* trx, /* in: transaction that has
+ trx_t* trx, /*!< in: transaction that has
set a record lock */
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record */
- enum lock_mode lock_mode)/* in: LOCK_S or LOCK_X */
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record */
+ enum lock_mode lock_mode)/*!< in: LOCK_S or LOCK_X */
{
lock_t* lock;
lock_t* release_lock = NULL;
@@ -3968,30 +3945,14 @@ lock_rec_unlock(
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
-Releases a table lock.
-Releases possible other transactions waiting for this lock. */
-UNIV_INTERN
-void
-lock_table_unlock(
-/*==============*/
- lock_t* lock) /* in: lock */
-{
- mutex_enter(&kernel_mutex);
-
- lock_table_dequeue(lock);
-
- mutex_exit(&kernel_mutex);
-}
-
-/*************************************************************************
+/*********************************************************************//**
Releases transaction locks, and releases possible other transactions waiting
because of these locks. */
UNIV_INTERN
void
lock_release_off_kernel(
/*====================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
dict_table_t* table;
ulint count;
@@ -4048,14 +4009,14 @@ lock_release_off_kernel(
mem_heap_empty(trx->lock_heap);
}
-/*************************************************************************
+/*********************************************************************//**
Cancels a waiting lock request and releases possible other transactions
waiting behind it. */
UNIV_INTERN
void
lock_cancel_waiting_and_release(
/*============================*/
- lock_t* lock) /* in: waiting lock request */
+ lock_t* lock) /*!< in: waiting lock request */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -4088,7 +4049,7 @@ lock_cancel_waiting_and_release(
|| lock_get_mode(lock) == LOCK_X)
-/*************************************************************************
+/*********************************************************************//**
Removes locks of a transaction on a table to be dropped.
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
@@ -4097,9 +4058,9 @@ static
void
lock_remove_all_on_table_for_trx(
/*=============================*/
- dict_table_t* table, /* in: table to be dropped */
- trx_t* trx, /* in: a transaction */
- ibool remove_also_table_sx_locks)/* in: also removes
+ dict_table_t* table, /*!< in: table to be dropped */
+ trx_t* trx, /*!< in: a transaction */
+ ibool remove_also_table_sx_locks)/*!< in: also removes
table S and X locks */
{
lock_t* lock;
@@ -4131,7 +4092,7 @@ lock_remove_all_on_table_for_trx(
}
}
-/*************************************************************************
+/*********************************************************************//**
Removes locks on a table to be dropped or truncated.
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
@@ -4140,9 +4101,9 @@ UNIV_INTERN
void
lock_remove_all_on_table(
/*=====================*/
- dict_table_t* table, /* in: table to be dropped
+ dict_table_t* table, /*!< in: table to be dropped
or truncated */
- ibool remove_also_table_sx_locks)/* in: also removes
+ ibool remove_also_table_sx_locks)/*!< in: also removes
table S and X locks */
{
lock_t* lock;
@@ -4198,14 +4159,14 @@ lock_remove_all_on_table(
/*===================== VALIDATION AND DEBUGGING ====================*/
-/*************************************************************************
+/*********************************************************************//**
Prints info of a table lock. */
UNIV_INTERN
void
lock_table_print(
/*=============*/
- FILE* file, /* in: file where to print */
- const lock_t* lock) /* in: table type lock */
+ FILE* file, /*!< in: file where to print */
+ const lock_t* lock) /*!< in: table type lock */
{
ut_ad(mutex_own(&kernel_mutex));
ut_a(lock_get_type_low(lock) == LOCK_TABLE);
@@ -4238,14 +4199,14 @@ lock_table_print(
putc('\n', file);
}
-/*************************************************************************
+/*********************************************************************//**
Prints info of a record lock. */
UNIV_INTERN
void
lock_rec_print(
/*===========*/
- FILE* file, /* in: file where to print */
- const lock_t* lock) /* in: record type lock */
+ FILE* file, /*!< in: file where to print */
+ const lock_t* lock) /*!< in: record type lock */
{
const buf_block_t* block;
ulint space;
@@ -4330,8 +4291,6 @@ lock_rec_print(
}
}
-#ifndef UNIV_HOTBACKUP
-
#ifdef UNIV_DEBUG
/* Print the number of lock structs from lock_print_info_summary() only
in non-production builds for performance reasons, see
@@ -4340,8 +4299,9 @@ http://bugs.mysql.com/36942 */
#endif /* UNIV_DEBUG */
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
-/*************************************************************************
-Calculates the number of record lock structs in the record lock hash table. */
+/*********************************************************************//**
+Calculates the number of record lock structs in the record lock hash table.
+@return number of record locks */
static
ulint
lock_get_n_rec_locks(void)
@@ -4368,13 +4328,13 @@ lock_get_n_rec_locks(void)
}
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
-/*************************************************************************
+/*********************************************************************//**
Prints info of locks for all transactions. */
UNIV_INTERN
void
lock_print_info_summary(
/*====================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
/* We must protect the MySQL thd->query field with a MySQL mutex, and
because the MySQL mutex must be reserved before the kernel_mutex of
@@ -4415,13 +4375,13 @@ lock_print_info_summary(
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
}
-/*************************************************************************
+/*********************************************************************//**
Prints info of locks for each transaction. */
UNIV_INTERN
void
lock_print_info_all_transactions(
/*=============================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
lock_t* lock;
ibool load_page_first = TRUE;
@@ -4532,6 +4492,20 @@ loop:
ulint zip_size= fil_space_get_zip_size(space);
ulint page_no = lock->un_member.rec_lock.page_no;
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+
+ /* It is a single table tablespace and
+ the .ibd file is missing (TRUNCATE
+ TABLE probably stole the locks): just
+ print the lock without attempting to
+ load the page in the buffer pool. */
+
+ fprintf(file, "RECORD LOCKS on"
+ " non-existing space %lu\n",
+ (ulong) space);
+ goto print_rec;
+ }
+
lock_mutex_exit_kernel();
innobase_mysql_end_print_arbitrary_thd();
@@ -4550,6 +4524,7 @@ loop:
goto loop;
}
+print_rec:
lock_rec_print(file, lock);
} else {
ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
@@ -4575,15 +4550,15 @@ loop:
goto loop;
}
-# ifdef UNIV_DEBUG
-/*************************************************************************
-Validates the lock queue on a table. */
+#ifdef UNIV_DEBUG
+/*********************************************************************//**
+Validates the lock queue on a table.
+@return TRUE if ok */
static
ibool
lock_table_queue_validate(
/*======================*/
- /* out: TRUE if ok */
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
lock_t* lock;
@@ -4612,17 +4587,17 @@ lock_table_queue_validate(
return(TRUE);
}
-/*************************************************************************
-Validates the lock queue on a single record. */
+/*********************************************************************//**
+Validates the lock queue on a single record.
+@return TRUE if ok */
static
ibool
lock_rec_queue_validate(
/*====================*/
- /* out: TRUE if ok */
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record to look at */
- dict_index_t* index, /* in: index, or NULL if not known */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record to look at */
+ dict_index_t* index, /*!< in: index, or NULL if not known */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
trx_t* impl_trx;
lock_t* lock;
@@ -4687,6 +4662,10 @@ lock_rec_queue_validate(
next function call: we have to release lock table mutex
to obey the latching order */
+ /* If this thread is holding the file space latch
+ (fil_space_t::latch), the following check WILL break
+ latching order and may cause a deadlock of threads. */
+
impl_trx = lock_sec_rec_some_has_impl_off_kernel(
rec, index, offsets);
@@ -4736,15 +4715,17 @@ lock_rec_queue_validate(
return(TRUE);
}
-/*************************************************************************
-Validates the record lock queues on a page. */
+/*********************************************************************//**
+Validates the record lock queues on a page.
+@return TRUE if ok */
static
ibool
lock_rec_validate_page(
/*===================*/
- /* out: TRUE if ok */
- ulint space, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
+ ulint page_no)/*!< in: page number */
{
dict_index_t* index;
buf_block_t* block;
@@ -4764,8 +4745,8 @@ lock_rec_validate_page(
mtr_start(&mtr);
- block = buf_page_get(space, fil_space_get_zip_size(space),
- page_no, RW_X_LATCH, &mtr);
+ ut_ad(zip_size != ULINT_UNDEFINED);
+ block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
page = block->frame;
@@ -4808,6 +4789,11 @@ loop:
lock_mutex_exit_kernel();
+ /* If this thread is holding the file space
+ latch (fil_space_t::latch), the following
+ check WILL break the latching order and may
+ cause a deadlock of threads. */
+
lock_rec_queue_validate(block, rec, index, offsets);
lock_mutex_enter_kernel();
@@ -4834,13 +4820,13 @@ function_exit:
return(TRUE);
}
-/*************************************************************************
-Validates the lock system. */
+/*********************************************************************//**
+Validates the lock system.
+@return TRUE if ok */
static
ibool
lock_validate(void)
/*===============*/
- /* out: TRUE if ok */
{
lock_t* lock;
trx_t* trx;
@@ -4898,7 +4884,9 @@ lock_validate(void)
lock_mutex_exit_kernel();
- lock_rec_validate_page(space, page_no);
+ lock_rec_validate_page(space,
+ fil_space_get_zip_size(space),
+ page_no);
lock_mutex_enter_kernel();
@@ -4910,29 +4898,28 @@ lock_validate(void)
return(TRUE);
}
-# endif /* UNIV_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
/*============ RECORD LOCK CHECKS FOR ROW OPERATIONS ====================*/
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate insert of
a record. If they do, first tests if the query thread should anyway
be suspended for some reason; if not, then puts the transaction and
the query thread to the lock wait state and inserts a waiting request
-for a gap x-lock to the lock queue. */
+for a gap x-lock to the lock queue.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_rec_insert_check_and_lock(
/*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is
set, does nothing */
- rec_t* rec, /* in: record after which to insert */
- buf_block_t* block, /* in/out: buffer block of rec */
- dict_index_t* index, /* in: index */
- que_thr_t* thr, /* in: query thread */
- ibool* inherit)/* out: set to TRUE if the new
+ const rec_t* rec, /*!< in: record after which to insert */
+ buf_block_t* block, /*!< in/out: buffer block of rec */
+ dict_index_t* index, /*!< in: index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+ ibool* inherit)/*!< out: set to TRUE if the new
inserted record maybe should inherit
LOCK_GAP type locks from the successor
record */
@@ -4951,7 +4938,7 @@ lock_rec_insert_check_and_lock(
}
trx = thr_get_trx(thr);
- next_rec = page_rec_get_next(rec);
+ next_rec = page_rec_get_next((rec_t*) rec);
next_rec_heap_no = page_rec_get_heap_no(next_rec);
lock_mutex_enter_kernel();
@@ -4974,7 +4961,7 @@ lock_rec_insert_check_and_lock(
/* Update the page max trx id field */
page_update_max_trx_id(block,
buf_block_get_page_zip(block),
- trx->id);
+ trx->id, mtr);
}
*inherit = FALSE;
@@ -5013,7 +5000,7 @@ lock_rec_insert_check_and_lock(
/* Update the page max trx id field */
page_update_max_trx_id(block,
buf_block_get_page_zip(block),
- trx->id);
+ trx->id, mtr);
}
#ifdef UNIV_DEBUG
@@ -5036,7 +5023,7 @@ lock_rec_insert_check_and_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
If a transaction has an implicit x-lock on a record, but no explicit x-lock
set on the record, sets one for it. NOTE that in the case of a secondary
index, the kernel mutex may get temporarily released. */
@@ -5044,10 +5031,10 @@ static
void
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 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) */
{
trx_t* impl_trx;
@@ -5079,28 +5066,26 @@ lock_rec_convert_impl_to_expl(
}
}
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify (update,
delete mark, or delete unmark) of a clustered index record. If they do,
first tests if the query thread should anyway be suspended for some
reason; if not, then puts the transaction and the query thread to the
lock wait state and inserts a waiting request for a record x-lock to the
-lock queue. */
+lock queue.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_modify_check_and_lock(
/*=================================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: record which should be
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ 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) */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
ulint heap_no;
@@ -5137,25 +5122,25 @@ lock_clust_rec_modify_check_and_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify (delete
-mark or delete unmark) of a secondary index record. */
+mark or delete unmark) of a secondary index record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_sec_rec_modify_check_and_lock(
/*===============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- buf_block_t* block, /* in/out: buffer block of rec */
- rec_t* rec, /* in: record which should be
+ buf_block_t* block, /*!< in/out: buffer block of rec */
+ const rec_t* rec, /*!< in: record which should be
modified; NOTE: as this is a secondary
index, we always have to modify the
clustered index record first: see the
comment below */
- dict_index_t* index, /* in: secondary index */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: secondary index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint err;
ulint heap_no;
@@ -5204,39 +5189,37 @@ lock_sec_rec_modify_check_and_lock(
/* Update the page max trx id field */
page_update_max_trx_id(block,
buf_block_get_page_zip(block),
- thr_get_trx(thr)->id);
+ thr_get_trx(thr)->id, mtr);
}
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Like the counterpart for a clustered index below, but now we read a
-secondary index record. */
+secondary index record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_sec_rec_read_check_and_lock(
/*=============================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
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) */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: secondary index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
ulint heap_no;
@@ -5283,37 +5266,35 @@ lock_sec_rec_read_check_and_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
if the query thread should anyway be suspended for some reason; if not, then
puts the transaction and the query thread to the lock wait state and inserts a
waiting request for a record lock to the lock queue. Sets the requested mode
-lock on the record. */
+lock on the record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_read_check_and_lock(
/*===============================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum 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) */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
ulint heap_no;
@@ -5353,7 +5334,7 @@ lock_clust_rec_read_check_and_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
if the query thread should anyway be suspended for some reason; if not, then
@@ -5361,30 +5342,28 @@ puts the transaction and the query thread to the lock wait state and inserts a
waiting request for a record lock to the lock queue. Sets the requested mode
lock on the record. This is an alternative version of
lock_clust_rec_read_check_and_lock() that does not require the parameter
-"offsets". */
+"offsets".
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_read_check_and_lock_alt(
/*===================================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
be read or passed over by a
read cursor */
- dict_index_t* index, /* in: clustered index */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: clustered index */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* tmp_heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -5402,13 +5381,13 @@ lock_clust_rec_read_check_and_lock_alt(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Release the last lock from the transaction's autoinc locks. */
UNIV_INLINE
void
lock_release_autoinc_last_lock(
/*===========================*/
- ib_vector_t* autoinc_locks) /* in/out: vector of AUTOINC locks */
+ ib_vector_t* autoinc_locks) /*!< in/out: vector of AUTOINC locks */
{
ulint last;
lock_t* lock;
@@ -5430,13 +5409,27 @@ lock_release_autoinc_last_lock(
lock_table_dequeue(lock);
}
-/***********************************************************************
+/*******************************************************************//**
+Check if a transaction holds any autoinc locks.
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+ const trx_t* trx) /*!< in: transaction */
+{
+ ut_a(trx->autoinc_locks != NULL);
+
+ return(!ib_vector_is_empty(trx->autoinc_locks));
+}
+
+/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
lock_release_autoinc_locks(
/*=======================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -5456,40 +5449,40 @@ lock_release_autoinc_locks(
ut_a(ib_vector_is_empty(trx->autoinc_locks));
}
-/***********************************************************************
+/*******************************************************************//**
Gets the type of a lock. Non-inline version for using outside of the
-lock module. */
+lock module.
+@return LOCK_TABLE or LOCK_REC */
UNIV_INTERN
ulint
lock_get_type(
/*==========*/
- /* out: LOCK_TABLE or LOCK_REC */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
return(lock_get_type_low(lock));
}
-/***********************************************************************
-Gets the id of the transaction owning a lock. */
+/*******************************************************************//**
+Gets the id of the transaction owning a lock.
+@return transaction id */
UNIV_INTERN
ullint
lock_get_trx_id(
/*============*/
- /* out: transaction id */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
return(trx_get_id(lock->trx));
}
-/***********************************************************************
+/*******************************************************************//**
Gets the mode of a lock in a human readable string.
-The string should not be free()'d or modified. */
+The string should not be free()'d or modified.
+@return lock mode */
UNIV_INTERN
const char*
lock_get_mode_str(
/*==============*/
- /* out: lock mode */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ibool is_gap_lock;
@@ -5528,15 +5521,15 @@ lock_get_mode_str(
}
}
-/***********************************************************************
+/*******************************************************************//**
Gets the type of a lock in a human readable string.
-The string should not be free()'d or modified. */
+The string should not be free()'d or modified.
+@return lock type */
UNIV_INTERN
const char*
lock_get_type_str(
/*==============*/
- /* out: lock type */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
switch (lock_get_type_low(lock)) {
case LOCK_REC:
@@ -5548,14 +5541,14 @@ lock_get_type_str(
}
}
-/***********************************************************************
-Gets the table on which the lock is. */
+/*******************************************************************//**
+Gets the table on which the lock is.
+@return table */
UNIV_INLINE
dict_table_t*
lock_get_table(
/*===========*/
- /* out: table */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
switch (lock_get_type_low(lock)) {
case LOCK_REC:
@@ -5568,14 +5561,14 @@ lock_get_table(
}
}
-/***********************************************************************
-Gets the id of the table on which the lock is. */
+/*******************************************************************//**
+Gets the id of the table on which the lock is.
+@return id of the table */
UNIV_INTERN
ullint
lock_get_table_id(
/*==============*/
- /* out: id of the table */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
dict_table_t* table;
@@ -5584,15 +5577,15 @@ lock_get_table_id(
return((ullint)ut_conv_dulint_to_longlong(table->id));
}
-/***********************************************************************
+/*******************************************************************//**
Gets the name of the table on which the lock is.
-The string should not be free()'d or modified. */
+The string should not be free()'d or modified.
+@return name of the table */
UNIV_INTERN
const char*
lock_get_table_name(
/*================*/
- /* out: name of the table */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
dict_table_t* table;
@@ -5601,57 +5594,57 @@ lock_get_table_name(
return(table->name);
}
-/***********************************************************************
-For a record lock, gets the index on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the index on which the lock is.
+@return index */
UNIV_INTERN
const dict_index_t*
lock_rec_get_index(
/*===============*/
- /* out: index */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_a(lock_get_type_low(lock) == LOCK_REC);
return(lock->index);
}
-/***********************************************************************
+/*******************************************************************//**
For a record lock, gets the name of the index on which the lock is.
-The string should not be free()'d or modified. */
+The string should not be free()'d or modified.
+@return name of the index */
UNIV_INTERN
const char*
lock_rec_get_index_name(
/*====================*/
- /* out: name of the index */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_a(lock_get_type_low(lock) == LOCK_REC);
return(lock->index->name);
}
-/***********************************************************************
-For a record lock, gets the tablespace number on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the tablespace number on which the lock is.
+@return tablespace number */
UNIV_INTERN
ulint
lock_rec_get_space_id(
/*==================*/
- /* out: tablespace number */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_a(lock_get_type_low(lock) == LOCK_REC);
return(lock->un_member.rec_lock.space);
}
-/***********************************************************************
-For a record lock, gets the page number on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the page number on which the lock is.
+@return page number */
UNIV_INTERN
ulint
lock_rec_get_page_no(
/*=================*/
- /* out: page number */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_a(lock_get_type_low(lock) == LOCK_REC);
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c
index a41b02c32fa..5d54b75b725 100644
--- a/storage/xtradb/log/log0log.c
+++ b/storage/xtradb/log/log0log.c
@@ -15,8 +15,33 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*****************************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Google Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Google, Inc. Those modifications are gratefully acknowledged and are described
+briefly in the InnoDB documentation. The contributions by Google are
+incorporated with their permission, and subject to the conditions contained in
+the file COPYING.Google.
+
+This program is free 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
+
+*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file log/log0log.c
Database log
Created 12/9/1995 Heikki Tuuri
@@ -28,6 +53,7 @@ Created 12/9/1995 Heikki Tuuri
#include "log0log.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#include "mem0mem.h"
#include "buf0buf.h"
#include "buf0flu.h"
@@ -75,8 +101,6 @@ UNIV_INTERN log_t* log_sys = NULL;
#ifdef UNIV_DEBUG
UNIV_INTERN ibool log_do_write = TRUE;
-
-UNIV_INTERN ibool log_debug_writes = FALSE;
#endif /* UNIV_DEBUG */
/* These control how often we print warnings if the last checkpoint is too
@@ -129,14 +153,14 @@ the previous */
#define LOG_ARCHIVE_READ 1
#define LOG_ARCHIVE_WRITE 2
-/**********************************************************
+/******************************************************//**
Completes a checkpoint write i/o to a log file. */
static
void
log_io_complete_checkpoint(void);
/*============================*/
#ifdef UNIV_LOG_ARCHIVE
-/**********************************************************
+/******************************************************//**
Completes an archiving i/o. */
static
void
@@ -144,7 +168,7 @@ log_io_complete_archive(void);
/*=========================*/
#endif /* UNIV_LOG_ARCHIVE */
-/********************************************************************
+/****************************************************************//**
Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint,
so that we know that the limit has been written to a log checkpoint field
on disk. */
@@ -152,7 +176,7 @@ UNIV_INTERN
void
log_fsp_current_free_limit_set_and_checkpoint(
/*==========================================*/
- ulint limit) /* in: limit to set */
+ ulint limit) /*!< in: limit to set */
{
ibool success;
@@ -171,9 +195,10 @@ log_fsp_current_free_limit_set_and_checkpoint(
}
}
-/********************************************************************
+/****************************************************************//**
Returns the oldest modified block lsn in the pool, or log_sys->lsn if none
-exists. */
+exists.
+@return LSN of oldest modification */
static
ib_uint64_t
log_buf_pool_get_oldest_modification(void)
@@ -193,15 +218,15 @@ log_buf_pool_get_oldest_modification(void)
return(lsn);
}
-/****************************************************************
+/************************************************************//**
Opens the log for log_write_low. The log must be closed with log_close and
-released with log_release. */
+released with log_release.
+@return start lsn of the log record */
UNIV_INTERN
ib_uint64_t
log_reserve_and_open(
/*=================*/
- /* out: start lsn of the log record */
- ulint len) /* in: length of data to be catenated */
+ ulint len) /*!< in: length of data to be catenated */
{
log_t* log = log_sys;
ulint len_upper_limit;
@@ -216,6 +241,7 @@ log_reserve_and_open(
ut_a(len < log->buf_size / 2);
loop:
mutex_enter(&(log->mutex));
+ ut_ad(!recv_no_log_write);
/* Calculate an upper limit for the space the string may take in the
log buffer */
@@ -267,15 +293,15 @@ loop:
return(log->lsn);
}
-/****************************************************************
+/************************************************************//**
Writes to the log the string given. It is assumed that the caller holds the
log mutex. */
UNIV_INTERN
void
log_write_low(
/*==========*/
- byte* str, /* in: string */
- ulint str_len) /* in: string length */
+ byte* str, /*!< in: string */
+ ulint str_len) /*!< in: string length */
{
log_t* log = log_sys;
ulint len;
@@ -284,6 +310,7 @@ log_write_low(
ut_ad(mutex_own(&(log->mutex)));
part_loop:
+ ut_ad(!recv_no_log_write);
/* Calculate a part length */
data_len = (log->buf_free % OS_FILE_LOG_BLOCK_SIZE) + str_len;
@@ -336,13 +363,40 @@ part_loop:
srv_log_write_requests++;
}
-/****************************************************************
-Closes the log. */
+/************************************************************//**
+*/
+UNIV_INLINE
+ulint
+log_max_modified_age_async()
+{
+ if (srv_checkpoint_age_target) {
+ return(ut_min(log_sys->max_modified_age_async,
+ srv_checkpoint_age_target
+ - srv_checkpoint_age_target / 8));
+ } else {
+ return(log_sys->max_modified_age_async);
+ }
+}
+
+UNIV_INLINE
+ulint
+log_max_checkpoint_age_async()
+{
+ if (srv_checkpoint_age_target) {
+ return(ut_min(log_sys->max_checkpoint_age_async,
+ srv_checkpoint_age_target));
+ } else {
+ return(log_sys->max_checkpoint_age_async);
+ }
+}
+
+/************************************************************//**
+Closes the log.
+@return lsn */
UNIV_INTERN
ib_uint64_t
log_close(void)
/*===========*/
- /* out: lsn */
{
byte* log_block;
ulint first_rec_group;
@@ -352,6 +406,7 @@ log_close(void)
ib_uint64_t checkpoint_age;
ut_ad(mutex_own(&(log->mutex)));
+ ut_ad(!recv_no_log_write);
lsn = log->lsn;
@@ -404,7 +459,7 @@ log_close(void)
}
}
- if (checkpoint_age <= log->max_modified_age_async) {
+ if (checkpoint_age <= log_max_modified_age_async()) {
goto function_exit;
}
@@ -412,8 +467,8 @@ log_close(void)
oldest_lsn = buf_pool_get_oldest_modification();
if (!oldest_lsn
- || lsn - oldest_lsn > log->max_modified_age_async
- || checkpoint_age > log->max_checkpoint_age_async) {
+ || lsn - oldest_lsn > log_max_modified_age_async()
+ || checkpoint_age > log_max_checkpoint_age_async()) {
log->check_flush_or_checkpoint = TRUE;
}
@@ -428,7 +483,7 @@ function_exit:
}
#ifdef UNIV_LOG_ARCHIVE
-/**********************************************************
+/******************************************************//**
Pads the current log block full with dummy log records. Used in producing
consistent archived log files. */
static
@@ -461,47 +516,49 @@ log_pad_current_log_block(void)
}
#endif /* UNIV_LOG_ARCHIVE */
-/**********************************************************
+/******************************************************//**
Calculates the data capacity of a log group, when the log file headers are not
-included. */
+included.
+@return capacity in bytes */
UNIV_INTERN
ulint
log_group_get_capacity(
/*===================*/
- /* out: capacity in bytes */
- log_group_t* group) /* in: log group */
+ const log_group_t* group) /*!< in: log group */
{
ut_ad(mutex_own(&(log_sys->mutex)));
return((group->file_size - LOG_FILE_HDR_SIZE) * group->n_files);
}
-/**********************************************************
+/******************************************************//**
Calculates the offset within a log group, when the log file headers are not
-included. */
+included.
+@return size offset (<= offset) */
UNIV_INLINE
ulint
log_group_calc_size_offset(
/*=======================*/
- /* out: size offset (<= offset) */
- ulint offset, /* in: real offset within the log group */
- log_group_t* group) /* in: log group */
+ ulint offset, /*!< in: real offset within the
+ log group */
+ const log_group_t* group) /*!< in: log group */
{
ut_ad(mutex_own(&(log_sys->mutex)));
return(offset - LOG_FILE_HDR_SIZE * (1 + offset / group->file_size));
}
-/**********************************************************
+/******************************************************//**
Calculates the offset within a log group, when the log file headers are
-included. */
+included.
+@return real offset (>= offset) */
UNIV_INLINE
ulint
log_group_calc_real_offset(
/*=======================*/
- /* out: real offset (>= offset) */
- ulint offset, /* in: size offset within the log group */
- log_group_t* group) /* in: log group */
+ ulint offset, /*!< in: size offset within the
+ log group */
+ const log_group_t* group) /*!< in: log group */
{
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -509,16 +566,16 @@ log_group_calc_real_offset(
* (1 + offset / (group->file_size - LOG_FILE_HDR_SIZE)));
}
-/**********************************************************
-Calculates the offset of an lsn within a log group. */
+/******************************************************//**
+Calculates the offset of an lsn within a log group.
+@return offset within the log group */
static
ulint
log_group_calc_lsn_offset(
/*======================*/
- /* out: offset within the log group */
- ib_uint64_t lsn, /* in: lsn, must be within 4 GB of
- group->lsn */
- log_group_t* group) /* in: log group */
+ ib_uint64_t lsn, /*!< in: lsn, must be within 4 GB of
+ group->lsn */
+ const log_group_t* group) /*!< in: log group */
{
ib_uint64_t gr_lsn;
ib_int64_t gr_lsn_size_offset;
@@ -560,23 +617,28 @@ log_group_calc_lsn_offset(
return(log_group_calc_real_offset((ulint)offset, group));
}
+#endif /* !UNIV_HOTBACKUP */
+
+#ifdef UNIV_DEBUG
+UNIV_INTERN ibool log_debug_writes = FALSE;
+#endif /* UNIV_DEBUG */
-/***********************************************************************
-Calculates where in log files we find a specified lsn. */
+/*******************************************************************//**
+Calculates where in log files we find a specified lsn.
+@return log file number */
UNIV_INTERN
ulint
log_calc_where_lsn_is(
/*==================*/
- /* out: log file number */
- ib_int64_t* log_file_offset, /* out: offset in that file
+ ib_int64_t* log_file_offset, /*!< out: offset in that file
(including the header) */
- ib_uint64_t first_header_lsn, /* in: first log file start
+ ib_uint64_t first_header_lsn, /*!< in: first log file start
lsn */
- ib_uint64_t lsn, /* in: lsn whose position to
+ ib_uint64_t lsn, /*!< in: lsn whose position to
determine */
- ulint n_log_files, /* in: total number of log
+ ulint n_log_files, /*!< in: total number of log
files */
- ib_int64_t log_file_size) /* in: log file size
+ ib_int64_t log_file_size) /*!< in: log file size
(including the header) */
{
ib_int64_t capacity = log_file_size - LOG_FILE_HDR_SIZE;
@@ -601,7 +663,8 @@ log_calc_where_lsn_is(
return(file_no);
}
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Sets the field values in group to correspond to a given lsn. For this function
to work, the values must already be correctly initialized to correspond to
some lsn, for instance, a checkpoint lsn. */
@@ -609,24 +672,23 @@ UNIV_INTERN
void
log_group_set_fields(
/*=================*/
- log_group_t* group, /* in: group */
- ib_uint64_t lsn) /* in: lsn for which the values should be
+ log_group_t* group, /*!< in/out: group */
+ ib_uint64_t lsn) /*!< in: lsn for which the values should be
set */
{
group->lsn_offset = log_group_calc_lsn_offset(lsn, group);
group->lsn = lsn;
}
-/*********************************************************************
+/*****************************************************************//**
Calculates the recommended highest values for lsn - last_checkpoint_lsn,
-lsn - buf_get_oldest_modification(), and lsn - max_archive_lsn_age. */
+lsn - buf_get_oldest_modification(), and lsn - max_archive_lsn_age.
+@return error value FALSE if the smallest log group is too small to
+accommodate the number of OS threads in the database server */
static
ibool
log_calc_max_ages(void)
/*===================*/
- /* out: error value FALSE if the smallest log group is
- too small to accommodate the number of OS threads in
- the database server */
{
log_group_t* group;
ulint margin;
@@ -636,8 +698,6 @@ log_calc_max_ages(void)
ulint archive_margin;
ulint smallest_archive_margin;
- ut_ad(!mutex_own(&(log_sys->mutex)));
-
mutex_enter(&(log_sys->mutex));
group = UT_LIST_GET_FIRST(log_sys->log_groups);
@@ -720,8 +780,7 @@ failure:
" After an ERROR-FREE shutdown\n"
"InnoDB: of mysqld you can adjust the size of"
" ib_logfiles, as explained in\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "adding-and-removing.html\n"
+ "InnoDB: " REFMAN "adding-and-removing.html\n"
"InnoDB: Cannot continue operation."
" Calling exit(1).\n",
(ulong)srv_thread_concurrency);
@@ -732,15 +791,13 @@ failure:
return(success);
}
-/**********************************************************
+/******************************************************//**
Initializes the log. */
UNIV_INTERN
void
log_init(void)
/*==========*/
{
- byte* buf;
-
log_sys = mem_alloc(sizeof(log_t));
mutex_create(&log_sys->mutex, SYNC_LOG);
@@ -755,8 +812,8 @@ log_init(void)
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
- buf = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
- log_sys->buf = ut_align(buf, OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->buf_ptr = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->buf = ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE);
log_sys->buf_size = LOG_BUFFER_SIZE;
@@ -801,9 +858,9 @@ log_init(void)
rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK);
- log_sys->checkpoint_buf
- = ut_align(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),
- OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->checkpoint_buf = ut_align(log_sys->checkpoint_buf_ptr,
+ OS_FILE_LOG_BLOCK_SIZE);
memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
/*----------------------------*/
@@ -842,7 +899,7 @@ log_init(void)
#ifdef UNIV_LOG_DEBUG
recv_sys_create();
- recv_sys_init(FALSE, buf_pool_get_curr_size());
+ recv_sys_init(buf_pool_get_curr_size());
recv_sys->parse_start_lsn = log_sys->lsn;
recv_sys->scanned_lsn = log_sys->lsn;
@@ -852,20 +909,20 @@ log_init(void)
#endif
}
-/**********************************************************************
+/******************************************************************//**
Inits a log group to the log system. */
UNIV_INTERN
void
log_group_init(
/*===========*/
- ulint id, /* in: group id */
- ulint n_files, /* in: number of log files */
- ulint file_size, /* in: log file size in bytes */
- ulint space_id, /* in: space id of the file space
+ ulint id, /*!< in: group id */
+ ulint n_files, /*!< in: number of log files */
+ ulint file_size, /*!< in: log file size in bytes */
+ ulint space_id, /*!< in: space id of the file space
which contains the log files of this
group */
ulint archive_space_id __attribute__((unused)))
- /* in: space id of the file space
+ /*!< in: space id of the file space
which contains some archived log
files for this group; currently, only
for the first log group this is
@@ -886,23 +943,33 @@ log_group_init(
group->lsn_offset = LOG_FILE_HDR_SIZE;
group->n_pending_writes = 0;
+ group->file_header_bufs_ptr = mem_alloc(sizeof(byte*) * n_files);
group->file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
#ifdef UNIV_LOG_ARCHIVE
+ group->archive_file_header_bufs_ptr = mem_alloc(
+ sizeof(byte*) * n_files);
group->archive_file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
#endif /* UNIV_LOG_ARCHIVE */
for (i = 0; i < n_files; i++) {
- *(group->file_header_bufs + i) = ut_align(
- mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
+ group->file_header_bufs_ptr[i] = mem_alloc(
+ LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+
+ group->file_header_bufs[i] = ut_align(
+ group->file_header_bufs_ptr[i],
OS_FILE_LOG_BLOCK_SIZE);
memset(*(group->file_header_bufs + i), '\0',
LOG_FILE_HDR_SIZE);
#ifdef UNIV_LOG_ARCHIVE
- *(group->archive_file_header_bufs + i) = ut_align(
- mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
+ group->archive_file_header_bufs_ptr[i] = mem_alloc(
+ LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+
+ group->archive_file_header_bufs[i] = ut_align(
+ group->archive_file_header_bufs_ptr[i],
OS_FILE_LOG_BLOCK_SIZE);
+
memset(*(group->archive_file_header_bufs + i), '\0',
LOG_FILE_HDR_SIZE);
#endif /* UNIV_LOG_ARCHIVE */
@@ -915,8 +982,9 @@ log_group_init(
group->archived_offset = 0;
#endif /* UNIV_LOG_ARCHIVE */
- group->checkpoint_buf = ut_align(
- mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE);
+ group->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
+ group->checkpoint_buf = ut_align(group->checkpoint_buf_ptr,
+ OS_FILE_LOG_BLOCK_SIZE);
memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
@@ -925,13 +993,13 @@ log_group_init(
ut_a(log_calc_max_ages());
}
-/**********************************************************************
+/******************************************************************//**
Does the unlockings needed in flush i/o completion. */
UNIV_INLINE
void
log_flush_do_unlocks(
/*=================*/
- ulint code) /* in: any ORed combination of LOG_UNLOCK_FLUSH_LOCK
+ ulint code) /*!< in: any ORed combination of LOG_UNLOCK_FLUSH_LOCK
and LOG_UNLOCK_NONE_FLUSHED_LOCK */
{
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -956,15 +1024,15 @@ log_flush_do_unlocks(
}
}
-/**********************************************************************
+/******************************************************************//**
Checks if a flush is completed for a log group and does the completion
-routine if yes. */
+routine if yes.
+@return LOG_UNLOCK_NONE_FLUSHED_LOCK or 0 */
UNIV_INLINE
ulint
log_group_check_flush_completion(
/*=============================*/
- /* out: LOG_UNLOCK_NONE_FLUSHED_LOCK or 0 */
- log_group_t* group) /* in: log group */
+ log_group_t* group) /*!< in: log group */
{
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -992,13 +1060,13 @@ log_group_check_flush_completion(
return(0);
}
-/**********************************************************
-Checks if a flush is completed and does the completion routine if yes. */
+/******************************************************//**
+Checks if a flush is completed and does the completion routine if yes.
+@return LOG_UNLOCK_FLUSH_LOCK or 0 */
static
ulint
log_sys_check_flush_completion(void)
/*================================*/
- /* out: LOG_UNLOCK_FLUSH_LOCK or 0 */
{
ulint move_start;
ulint move_end;
@@ -1033,13 +1101,13 @@ log_sys_check_flush_completion(void)
return(0);
}
-/**********************************************************
+/******************************************************//**
Completes an i/o to a log file. */
UNIV_INTERN
void
log_io_complete(
/*============*/
- log_group_t* group) /* in: log group or a dummy pointer */
+ log_group_t* group) /*!< in: log group or a dummy pointer */
{
ulint unlock;
@@ -1075,7 +1143,7 @@ log_io_complete(
return;
}
- ut_error; /* We currently use synchronous writing of the
+ ut_error; /*!< We currently use synchronous writing of the
logs and cannot end up here! */
if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
@@ -1086,6 +1154,7 @@ log_io_complete(
}
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
ut_a(group->n_pending_writes > 0);
ut_a(log_sys->n_pending_writes > 0);
@@ -1101,22 +1170,23 @@ log_io_complete(
mutex_exit(&(log_sys->mutex));
}
-/**********************************************************
+/******************************************************//**
Writes a log file header to a log file space. */
static
void
log_group_file_header_flush(
/*========================*/
- log_group_t* group, /* in: log group */
- ulint nth_file, /* in: header to the nth file in the
+ log_group_t* group, /*!< in: log group */
+ ulint nth_file, /*!< in: header to the nth file in the
log file space */
- ib_uint64_t start_lsn) /* in: log file data starts at this
+ ib_uint64_t start_lsn) /*!< in: log file data starts at this
lsn */
{
byte* buf;
ulint dest_offset;
ut_ad(mutex_own(&(log_sys->mutex)));
+ ut_ad(!recv_no_log_write);
ut_a(nth_file < group->n_files);
buf = *(group->file_header_bufs + nth_file);
@@ -1151,7 +1221,7 @@ log_group_file_header_flush(
}
}
-/**********************************************************
+/******************************************************//**
Stores a 4-byte checksum to the trailer checksum field of a log block
before writing it to a log file. This checksum is used in recovery to
check the consistency of a log block. */
@@ -1159,25 +1229,25 @@ static
void
log_block_store_checksum(
/*=====================*/
- byte* block) /* in/out: pointer to a log block */
+ byte* block) /*!< in/out: pointer to a log block */
{
log_block_set_checksum(block, log_block_calc_checksum(block));
}
-/**********************************************************
+/******************************************************//**
Writes a buffer to a log file group. */
UNIV_INTERN
void
log_group_write_buf(
/*================*/
- log_group_t* group, /* in: log group */
- byte* buf, /* in: buffer */
- ulint len, /* in: buffer len; must be divisible
+ log_group_t* group, /*!< in: log group */
+ byte* buf, /*!< in: buffer */
+ ulint len, /*!< in: buffer len; must be divisible
by OS_FILE_LOG_BLOCK_SIZE */
- ib_uint64_t start_lsn, /* in: start lsn of the buffer; must
+ ib_uint64_t start_lsn, /*!< in: start lsn of the buffer; must
be divisible by
OS_FILE_LOG_BLOCK_SIZE */
- ulint new_data_offset)/* in: start offset of new data in
+ ulint new_data_offset)/*!< in: start offset of new data in
buf: this parameter is used to decide
if we have to write a new log file
header */
@@ -1188,6 +1258,7 @@ log_group_write_buf(
ulint i;
ut_ad(mutex_own(&(log_sys->mutex)));
+ ut_ad(!recv_no_log_write);
ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a(((ulint) start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -1281,7 +1352,7 @@ loop:
}
}
-/**********************************************************
+/******************************************************//**
This function is called, e.g., when a transaction wants to commit. It checks
that the log has been written to the log file up to the last log entry written
by the transaction. If there is a flush running, it waits and checks if the
@@ -1290,13 +1361,13 @@ UNIV_INTERN
void
log_write_up_to(
/*============*/
- ib_uint64_t lsn, /* in: log sequence number up to which
+ ib_uint64_t lsn, /*!< in: log sequence number up to which
the log should be written,
IB_ULONGLONG_MAX if not specified */
- ulint wait, /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
+ ulint wait, /*!< in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
or LOG_WAIT_ALL_GROUPS */
ibool flush_to_disk)
- /* in: TRUE if we want the written log
+ /*!< in: TRUE if we want the written log
also to be flushed to disk */
{
log_group_t* group;
@@ -1330,6 +1401,7 @@ loop:
#endif
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
if (flush_to_disk
&& log_sys->flushed_to_disk_lsn >= lsn) {
@@ -1398,7 +1470,7 @@ loop:
log_sys->n_pending_writes++;
group = UT_LIST_GET_FIRST(log_sys->log_groups);
- group->n_pending_writes++; /* We assume here that we have only
+ group->n_pending_writes++; /*!< We assume here that we have only
one log group! */
os_event_reset(log_sys->no_flush_event);
@@ -1507,7 +1579,7 @@ do_waits:
}
}
-/********************************************************************
+/****************************************************************//**
Does a syncronous flush of the log buffer to disk. */
UNIV_INTERN
void
@@ -1525,13 +1597,16 @@ log_buffer_flush_to_disk(void)
log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE);
}
-/********************************************************************
-Flush the log buffer. Force it to disk depending on the value of
-innodb_flush_log_at_trx_commit. */
+/****************************************************************//**
+This functions writes the log buffer to the log file and if 'flush'
+is set it forces a flush of the log file as well. This is meant to be
+called from background master thread only as it does not wait for
+the write (+ possible flush) to finish. */
UNIV_INTERN
void
-log_buffer_flush_maybe_sync(void)
-/*=============================*/
+log_buffer_sync_in_background(
+/*==========================*/
+ ibool flush) /*!< in: flush the logs to disk */
{
ib_uint64_t lsn;
@@ -1541,11 +1616,11 @@ log_buffer_flush_maybe_sync(void)
mutex_exit(&(log_sys->mutex));
- /* Force log buffer to disk when innodb_flush_log_at_trx_commit = 1. */
- log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS,
- srv_flush_log_at_trx_commit == 1 ? TRUE : FALSE);
+ log_write_up_to(lsn, LOG_NO_WAIT, flush);
}
+
/********************************************************************
+
Tries to establish a big enough margin of free space in the log buffer, such
that a new log entry can be catenated without an immediate need for a flush. */
static
@@ -1575,23 +1650,20 @@ log_flush_margin(void)
}
}
-/********************************************************************
+/****************************************************************//**
Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool. NOTE: this function may only be called if the calling thread owns
-no synchronization objects! */
+no synchronization objects!
+@return FALSE if there was a flush batch of the same type running,
+which means that we could not start this flush batch */
UNIV_INTERN
ibool
log_preflush_pool_modified_pages(
/*=============================*/
- /* out: FALSE if there was a
- flush batch of the same type
- running, which means that we
- could not start this flush
- batch */
- ib_uint64_t new_oldest, /* in: try to advance
+ ib_uint64_t new_oldest, /*!< in: try to advance
oldest_modified_lsn at least
to this lsn */
- ibool sync) /* in: TRUE if synchronous
+ ibool sync) /*!< in: TRUE if synchronous
operation is desired */
{
ulint n_pages;
@@ -1623,7 +1695,7 @@ log_preflush_pool_modified_pages(
return(TRUE);
}
-/**********************************************************
+/******************************************************//**
Completes a checkpoint. */
static
void
@@ -1640,7 +1712,7 @@ log_complete_checkpoint(void)
rw_lock_x_unlock_gen(&(log_sys->checkpoint_lock), LOG_CHECKPOINT);
}
-/**********************************************************
+/******************************************************//**
Completes an asynchronous checkpoint info write i/o to a log file. */
static
void
@@ -1660,16 +1732,16 @@ log_io_complete_checkpoint(void)
mutex_exit(&(log_sys->mutex));
}
-/***********************************************************************
+/*******************************************************************//**
Writes info to a checkpoint about a log group. */
static
void
log_checkpoint_set_nth_group_info(
/*==============================*/
- byte* buf, /* in: buffer for checkpoint info */
- ulint n, /* in: nth slot */
- ulint file_no,/* in: archived file number */
- ulint offset) /* in: archived file offset */
+ byte* buf, /*!< in: buffer for checkpoint info */
+ ulint n, /*!< in: nth slot */
+ ulint file_no,/*!< in: archived file number */
+ ulint offset) /*!< in: archived file offset */
{
ut_ad(n < LOG_MAX_N_GROUPS);
@@ -1679,16 +1751,16 @@ log_checkpoint_set_nth_group_info(
+ 8 * n + LOG_CHECKPOINT_ARCHIVED_OFFSET, offset);
}
-/***********************************************************************
+/*******************************************************************//**
Gets info from a checkpoint about a log group. */
UNIV_INTERN
void
log_checkpoint_get_nth_group_info(
/*==============================*/
- byte* buf, /* in: buffer containing checkpoint info */
- ulint n, /* in: nth slot */
- ulint* file_no,/* out: archived file number */
- ulint* offset) /* out: archived file offset */
+ const byte* buf, /*!< in: buffer containing checkpoint info */
+ ulint n, /*!< in: nth slot */
+ ulint* file_no,/*!< out: archived file number */
+ ulint* offset) /*!< out: archived file offset */
{
ut_ad(n < LOG_MAX_N_GROUPS);
@@ -1698,13 +1770,13 @@ log_checkpoint_get_nth_group_info(
+ 8 * n + LOG_CHECKPOINT_ARCHIVED_OFFSET);
}
-/**********************************************************
+/******************************************************//**
Writes the checkpoint info to a log group header. */
static
void
log_group_checkpoint(
/*=================*/
- log_group_t* group) /* in: log group */
+ log_group_t* group) /*!< in: log group */
{
log_group_t* group2;
#ifdef UNIV_LOG_ARCHIVE
@@ -1817,18 +1889,19 @@ log_group_checkpoint(
ut_ad(((ulint)group & 0x1UL) == 0);
}
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_HOTBACKUP
-/**********************************************************
+/******************************************************//**
Writes info to a buffer of a log group when log files are created in
backup restoration. */
UNIV_INTERN
void
log_reset_first_header_and_checkpoint(
/*==================================*/
- byte* hdr_buf,/* in: buffer which will be written to the
+ byte* hdr_buf,/*!< in: buffer which will be written to the
start of the first log file */
- ib_uint64_t start) /* in: lsn of the start of the first log file;
+ ib_uint64_t start) /*!< in: lsn of the start of the first log file;
we pretend that there is a checkpoint at
start + LOG_BLOCK_HDR_SIZE */
{
@@ -1872,14 +1945,15 @@ log_reset_first_header_and_checkpoint(
}
#endif /* UNIV_HOTBACKUP */
-/**********************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************//**
Reads a checkpoint info from a log group header to log_sys->checkpoint_buf. */
UNIV_INTERN
void
log_group_read_checkpoint_info(
/*===========================*/
- log_group_t* group, /* in: log group */
- ulint field) /* in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */
+ log_group_t* group, /*!< in: log group */
+ ulint field) /*!< in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */
{
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -1890,7 +1964,7 @@ log_group_read_checkpoint_info(
OS_FILE_LOG_BLOCK_SIZE, log_sys->checkpoint_buf, NULL);
}
-/**********************************************************
+/******************************************************//**
Writes checkpoint info to groups. */
UNIV_INTERN
void
@@ -1910,20 +1984,19 @@ log_groups_write_checkpoint_info(void)
}
}
-/**********************************************************
+/******************************************************//**
Makes a checkpoint. Note that this function does not flush dirty
blocks from the buffer pool: it only checks what is lsn of the oldest
modification in the pool, and writes information about the lsn in
-log files. Use log_make_checkpoint_at to flush also the pool. */
+log files. Use log_make_checkpoint_at to flush also the pool.
+@return TRUE if success, FALSE if a checkpoint write was already running */
UNIV_INTERN
ibool
log_checkpoint(
/*===========*/
- /* out: TRUE if success, FALSE if a checkpoint
- write was already running */
- ibool sync, /* in: TRUE if synchronous operation is
+ ibool sync, /*!< in: TRUE if synchronous operation is
desired */
- ibool write_always) /* in: the function normally checks if the
+ ibool write_always) /*!< in: the function normally checks if the
the new checkpoint would have a greater
lsn than the previous one: if not, then no
physical write is done; by setting this
@@ -1942,6 +2015,7 @@ log_checkpoint(
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
oldest_lsn = log_buf_pool_get_oldest_modification();
mutex_exit(&(log_sys->mutex));
@@ -2005,17 +2079,17 @@ log_checkpoint(
return(TRUE);
}
-/********************************************************************
+/****************************************************************//**
Makes a checkpoint at a given lsn or later. */
UNIV_INTERN
void
log_make_checkpoint_at(
/*===================*/
- ib_uint64_t lsn, /* in: make a checkpoint at this or a
+ ib_uint64_t lsn, /*!< in: make a checkpoint at this or a
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
- ibool write_always) /* in: the function normally checks if
- the the new checkpoint would have a
+ ibool write_always) /*!< in: the function normally checks if
+ the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
by setting this parameter TRUE, a
@@ -2029,7 +2103,7 @@ log_make_checkpoint_at(
while (!log_checkpoint(TRUE, write_always));
}
-/********************************************************************
+/****************************************************************//**
Tries to establish a big enough margin of free space in the log groups, such
that a new log entry can be catenated without an immediate need for a
checkpoint. NOTE: this function may only be called if the calling thread
@@ -2054,6 +2128,7 @@ loop:
do_checkpoint = FALSE;
mutex_enter(&(log->mutex));
+ ut_ad(!recv_no_log_write);
if (log->check_flush_or_checkpoint == FALSE) {
mutex_exit(&(log->mutex));
@@ -2071,10 +2146,10 @@ loop:
sync = TRUE;
advance = 2 * (age - log->max_modified_age_sync);
- } else if (age > log->max_modified_age_async) {
+ } else if (age > log_max_modified_age_async()) {
/* A flush is not urgent: we do an asynchronous preflush */
- advance = age - log->max_modified_age_async;
+ advance = age - log_max_modified_age_async();
} else {
advance = 0;
}
@@ -2088,7 +2163,7 @@ loop:
do_checkpoint = TRUE;
- } else if (checkpoint_age > log->max_checkpoint_age_async) {
+ } else if (checkpoint_age > log_max_checkpoint_age_async()) {
/* A checkpoint is not urgent: do it asynchronously */
do_checkpoint = TRUE;
@@ -2131,17 +2206,17 @@ loop:
}
}
-/**********************************************************
+/******************************************************//**
Reads a specified log segment to a buffer. */
UNIV_INTERN
void
log_group_read_log_seg(
/*===================*/
- ulint type, /* in: LOG_ARCHIVE or LOG_RECOVER */
- byte* buf, /* in: buffer where to read */
- log_group_t* group, /* in: log group */
- ib_uint64_t start_lsn, /* in: read area start */
- ib_uint64_t end_lsn) /* in: read area end */
+ ulint type, /*!< in: LOG_ARCHIVE or LOG_RECOVER */
+ byte* buf, /*!< in: buffer where to read */
+ log_group_t* group, /*!< in: log group */
+ ib_uint64_t start_lsn, /*!< in: read area start */
+ ib_uint64_t end_lsn) /*!< in: read area end */
{
ulint len;
ulint source_offset;
@@ -2185,32 +2260,32 @@ loop:
}
#ifdef UNIV_LOG_ARCHIVE
-/**********************************************************
+/******************************************************//**
Generates an archived log file name. */
UNIV_INTERN
void
log_archived_file_name_gen(
/*=======================*/
- char* buf, /* in: buffer where to write */
+ char* buf, /*!< in: buffer where to write */
ulint id __attribute__((unused)),
- /* in: group id;
+ /*!< in: group id;
currently we only archive the first group */
- ulint file_no)/* in: file number */
+ ulint file_no)/*!< in: file number */
{
sprintf(buf, "%sib_arch_log_%010lu", srv_arch_dir, (ulong) file_no);
}
-/**********************************************************
+/******************************************************//**
Writes a log file header to a log file space. */
static
void
log_group_archive_file_header_write(
/*================================*/
- log_group_t* group, /* in: log group */
- ulint nth_file, /* in: header to the nth file in the
+ log_group_t* group, /*!< in: log group */
+ ulint nth_file, /*!< in: header to the nth file in the
archive log file space */
- ulint file_no, /* in: archived file number */
- ib_uint64_t start_lsn) /* in: log file data starts at this
+ ulint file_no, /*!< in: archived file number */
+ ib_uint64_t start_lsn) /*!< in: log file data starts at this
lsn */
{
byte* buf;
@@ -2239,16 +2314,16 @@ log_group_archive_file_header_write(
buf, &log_archive_io);
}
-/**********************************************************
+/******************************************************//**
Writes a log file header to a completed archived log file. */
static
void
log_group_archive_completed_header_write(
/*=====================================*/
- log_group_t* group, /* in: log group */
- ulint nth_file, /* in: header to the nth file in the
+ log_group_t* group, /*!< in: log group */
+ ulint nth_file, /*!< in: header to the nth file in the
archive log file space */
- ib_uint64_t end_lsn) /* in: end lsn of the file */
+ ib_uint64_t end_lsn) /*!< in: end lsn of the file */
{
byte* buf;
ulint dest_offset;
@@ -2273,13 +2348,13 @@ log_group_archive_completed_header_write(
&log_archive_io);
}
-/**********************************************************
+/******************************************************//**
Does the archive writes for a single log group. */
static
void
log_group_archive(
/*==============*/
- log_group_t* group) /* in: log group */
+ log_group_t* group) /*!< in: log group */
{
os_file_t file_handle;
ib_uint64_t start_lsn;
@@ -2414,7 +2489,7 @@ loop:
ut_a(group->next_archived_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
}
-/*********************************************************
+/*****************************************************//**
(Writes to the archive of each log group.) Currently, only the first
group is archived. */
static
@@ -2431,7 +2506,7 @@ log_archive_groups(void)
log_group_archive(group);
}
-/*********************************************************
+/*****************************************************//**
Completes the archiving write phase for (each log group), currently,
the first log group. */
static
@@ -2505,7 +2580,7 @@ log_archive_write_complete_groups(void)
#endif /* UNIV_DEBUG */
}
-/**********************************************************
+/******************************************************//**
Completes an archiving i/o. */
static
void
@@ -2541,7 +2616,7 @@ log_archive_check_completion_low(void)
}
}
-/**********************************************************
+/******************************************************//**
Completes an archiving i/o. */
static
void
@@ -2569,16 +2644,15 @@ log_io_complete_archive(void)
mutex_exit(&(log_sys->mutex));
}
-/************************************************************************
-Starts an archiving operation. */
+/********************************************************************//**
+Starts an archiving operation.
+@return TRUE if succeed, FALSE if an archiving operation was already running */
UNIV_INTERN
ibool
log_archive_do(
/*===========*/
- /* out: TRUE if succeed, FALSE if an archiving
- operation was already running */
- ibool sync, /* in: TRUE if synchronous operation is desired */
- ulint* n_bytes)/* out: archive log buffer size, 0 if nothing to
+ ibool sync, /*!< in: TRUE if synchronous operation is desired */
+ ulint* n_bytes)/*!< out: archive log buffer size, 0 if nothing to
archive */
{
ibool calc_new_limit;
@@ -2684,7 +2758,7 @@ arch_none:
return(TRUE);
}
-/********************************************************************
+/****************************************************************//**
Writes the log contents to the archive at least up to the lsn when this
function was called. */
static
@@ -2725,14 +2799,14 @@ log_archive_all(void)
}
}
-/*********************************************************
+/*****************************************************//**
Closes the possible open archive log file (for each group) the first group,
and if it was open, increments the group file count by 2, if desired. */
static
void
log_archive_close_groups(
/*=====================*/
- ibool increment_file_count) /* in: TRUE if we want to increment
+ ibool increment_file_count) /*!< in: TRUE if we want to increment
the file count */
{
log_group_t* group;
@@ -2777,16 +2851,16 @@ log_archive_close_groups(
}
}
-/********************************************************************
+/****************************************************************//**
Writes the log contents to the archive up to the lsn when this function was
called, and stops the archiving. When archiving is started again, the archived
log file numbers start from 2 higher, so that the archiving will not write
-again to the archived log files which exist when this function returns. */
+again to the archived log files which exist when this function returns.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_stop(void)
/*==================*/
- /* out: DB_SUCCESS or DB_ERROR */
{
ibool success;
@@ -2844,13 +2918,13 @@ log_archive_stop(void)
return(DB_SUCCESS);
}
-/********************************************************************
-Starts again archiving which has been stopped. */
+/****************************************************************//**
+Starts again archiving which has been stopped.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_start(void)
/*===================*/
- /* out: DB_SUCCESS or DB_ERROR */
{
mutex_enter(&(log_sys->mutex));
@@ -2870,13 +2944,13 @@ log_archive_start(void)
return(DB_SUCCESS);
}
-/********************************************************************
-Stop archiving the log so that a gap may occur in the archived log files. */
+/****************************************************************//**
+Stop archiving the log so that a gap may occur in the archived log files.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_noarchivelog(void)
/*==========================*/
- /* out: DB_SUCCESS or DB_ERROR */
{
loop:
mutex_enter(&(log_sys->mutex));
@@ -2902,13 +2976,13 @@ loop:
goto loop;
}
-/********************************************************************
-Start archiving the log so that a gap may occur in the archived log files. */
+/****************************************************************//**
+Start archiving the log so that a gap may occur in the archived log files.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_archivelog(void)
/*========================*/
- /* out: DB_SUCCESS or DB_ERROR */
{
mutex_enter(&(log_sys->mutex));
@@ -2929,7 +3003,7 @@ log_archive_archivelog(void)
return(DB_ERROR);
}
-/********************************************************************
+/****************************************************************//**
Tries to establish a big enough margin of free space in the log groups, such
that a new log entry can be catenated without an immediate need for
archiving. */
@@ -2984,7 +3058,7 @@ loop:
}
#endif /* UNIV_LOG_ARCHIVE */
-/************************************************************************
+/********************************************************************//**
Checks that there is enough free space in the log to start a new query step.
Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this
function may only be called if the calling thread owns no synchronization
@@ -3004,6 +3078,7 @@ loop:
#endif /* UNIV_LOG_ARCHIVE */
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
if (log_sys->check_flush_or_checkpoint) {
@@ -3015,7 +3090,7 @@ loop:
mutex_exit(&(log_sys->mutex));
}
-/********************************************************************
+/****************************************************************//**
Makes a checkpoint at the latest lsn and writes it to first page of each
data file in the database, so that we know that the file spaces contain
all modifications up to that lsn. This can only be called at database
@@ -3089,6 +3164,16 @@ loop:
goto loop;
}
+ /* Check that the purge threads ended */
+ if (srv_use_purge_thread
+ && (srv_n_threads_active[SRV_PURGE] != 0
+ || srv_n_threads_active[SRV_PURGE_WORKER] != 0)) {
+
+ mutex_exit(&kernel_mutex);
+
+ goto loop;
+ }
+
mutex_exit(&kernel_mutex);
mutex_enter(&(log_sys->mutex));
@@ -3203,23 +3288,24 @@ loop:
ut_a(lsn == log_sys->lsn);
}
-/**********************************************************
+#ifdef UNIV_LOG_DEBUG
+/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
- byte* buf, /* in: pointer to the start of
+ const byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
- ulint len, /* in: segment length in bytes */
- ib_uint64_t buf_start_lsn) /* in: buffer start lsn */
+ ulint len, /*!< in: segment length in bytes */
+ ib_uint64_t buf_start_lsn) /*!< in: buffer start lsn */
{
ib_uint64_t contiguous_lsn;
ib_uint64_t scanned_lsn;
- byte* start;
- byte* end;
+ const byte* start;
+ const byte* end;
byte* buf1;
byte* scan_buf;
@@ -3238,8 +3324,7 @@ log_check_log_recs(
ut_memcpy(scan_buf, start, end - start);
- recv_scan_log_recs(TRUE,
- (buf_pool->curr_size
+ recv_scan_log_recs((buf_pool->curr_size
- recv_n_pool_free_frames) * UNIV_PAGE_SIZE,
FALSE, scan_buf, end - start,
ut_uint64_align_down(buf_start_lsn,
@@ -3253,16 +3338,16 @@ log_check_log_recs(
return(TRUE);
}
+#endif /* UNIV_LOG_DEBUG */
-/**********************************************************
-Peeks the current lsn. */
+/******************************************************//**
+Peeks the current lsn.
+@return TRUE if success, FALSE if could not get the log system mutex */
UNIV_INTERN
ibool
log_peek_lsn(
/*=========*/
- /* out: TRUE if success, FALSE if
- could not get the log system mutex */
- ib_uint64_t* lsn) /* out: if returns TRUE, current lsn is here */
+ ib_uint64_t* lsn) /*!< out: if returns TRUE, current lsn is here */
{
if (0 == mutex_enter_nowait(&(log_sys->mutex))) {
*lsn = log_sys->lsn;
@@ -3275,13 +3360,13 @@ log_peek_lsn(
return(FALSE);
}
-/**********************************************************
+/******************************************************//**
Prints info of the log. */
UNIV_INTERN
void
log_print(
/*======*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
double time_elapsed;
time_t current_time;
@@ -3297,10 +3382,12 @@ log_print(
log_sys->last_checkpoint_lsn);
fprintf(file,
- "Max checkpoint age %lu\n"
- "Modified age %lu\n"
- "Checkpoint age %lu\n",
+ "Max checkpoint age %lu\n"
+ "Checkpoint age target %lu\n"
+ "Modified age %lu\n"
+ "Checkpoint age %lu\n",
(ulong) log_sys->max_checkpoint_age,
+ (ulong) log_max_checkpoint_age_async(),
(ulong) (log_sys->lsn -
log_buf_pool_get_oldest_modification()),
(ulong) (log_sys->lsn - log_sys->last_checkpoint_lsn));
@@ -3324,7 +3411,7 @@ log_print(
mutex_exit(&(log_sys->mutex));
}
-/**************************************************************************
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -3334,3 +3421,95 @@ log_refresh_stats(void)
log_sys->n_log_ios_old = log_sys->n_log_ios;
log_sys->last_printout_time = time(NULL);
}
+
+/**********************************************************************
+Closes a log group. */
+static
+void
+log_group_close(
+/*===========*/
+ log_group_t* group) /* in,own: log group to close */
+{
+ ulint i;
+
+ for (i = 0; i < group->n_files; i++) {
+ mem_free(group->file_header_bufs_ptr[i]);
+#ifdef UNIV_LOG_ARCHIVE
+ mem_free(group->archive_file_header_bufs_ptr[i]);
+#endif /* UNIV_LOG_ARCHIVE */
+ }
+
+ mem_free(group->file_header_bufs_ptr);
+ mem_free(group->file_header_bufs);
+
+#ifdef UNIV_LOG_ARCHIVE
+ mem_free(group->archive_file_header_bufs_ptr);
+ mem_free(group->archive_file_header_bufs);
+#endif /* UNIV_LOG_ARCHIVE */
+
+ mem_free(group->checkpoint_buf_ptr);
+
+ mem_free(group);
+}
+
+/**********************************************************
+Shutdown the log system but do not release all the memory. */
+UNIV_INTERN
+void
+log_shutdown(void)
+/*==============*/
+{
+ log_group_t* group;
+
+ group = UT_LIST_GET_FIRST(log_sys->log_groups);
+
+ while (UT_LIST_GET_LEN(log_sys->log_groups) > 0) {
+ log_group_t* prev_group = group;
+
+ group = UT_LIST_GET_NEXT(log_groups, group);
+ UT_LIST_REMOVE(log_groups, log_sys->log_groups, prev_group);
+
+ log_group_close(prev_group);
+ }
+
+ mem_free(log_sys->buf_ptr);
+ log_sys->buf_ptr = NULL;
+ log_sys->buf = NULL;
+ mem_free(log_sys->checkpoint_buf_ptr);
+ log_sys->checkpoint_buf_ptr = NULL;
+ log_sys->checkpoint_buf = NULL;
+
+ os_event_free(log_sys->no_flush_event);
+ os_event_free(log_sys->one_flushed_event);
+
+ rw_lock_free(&log_sys->checkpoint_lock);
+
+ mutex_free(&log_sys->mutex);
+
+#ifdef UNIV_LOG_ARCHIVE
+ rw_lock_free(&log_sys->archive_lock);
+ os_event_create(log_sys->archiving_on);
+#endif /* UNIV_LOG_ARCHIVE */
+
+#ifdef UNIV_LOG_DEBUG
+ recv_sys_debug_free();
+#endif
+
+ recv_sys_close();
+}
+
+/**********************************************************
+Free the log system data structures. */
+UNIV_INTERN
+void
+log_mem_free(void)
+/*==============*/
+{
+ if (log_sys != NULL) {
+ recv_sys_mem_free();
+ mem_free(log_sys);
+
+ log_sys = NULL;
+ }
+}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c
index f0f5ae8d6cc..77902b48a6f 100644
--- a/storage/xtradb/log/log0recv.c
+++ b/storage/xtradb/log/log0recv.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file log/log0recv.c
Recovery
Created 9/20/1997 Heikki Tuuri
@@ -31,42 +32,64 @@ Created 9/20/1997 Heikki Tuuri
#include "mem0mem.h"
#include "buf0buf.h"
#include "buf0flu.h"
-#include "buf0rea.h"
-#include "srv0srv.h"
-#include "srv0start.h"
+#include "mtr0mtr.h"
#include "mtr0log.h"
#include "page0cur.h"
#include "page0zip.h"
+#include "btr0btr.h"
#include "btr0cur.h"
#include "ibuf0ibuf.h"
#include "trx0undo.h"
#include "trx0rec.h"
-#include "trx0roll.h"
-#include "row0merge.h"
-
-#ifdef UNIV_HOTBACKUP
-/* This is set to FALSE if the backup was originally taken with the
+#include "fil0fil.h"
+#ifndef UNIV_HOTBACKUP
+# include "buf0rea.h"
+# include "srv0srv.h"
+# include "srv0start.h"
+# include "trx0roll.h"
+# include "row0merge.h"
+# include "sync0sync.h"
+#else /* !UNIV_HOTBACKUP */
+
+/** This is set to FALSE if the backup was originally taken with the
ibbackup --include regexp option: then we do not want to create tables in
directories which were not included */
UNIV_INTERN ibool recv_replay_file_ops = TRUE;
-#endif /* UNIV_HOTBACKUP */
+#endif /* !UNIV_HOTBACKUP */
-/* Log records are stored in the hash table in chunks at most of this size;
+/** 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 */
#define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t))
-/* Read-ahead area in applying log records to file pages */
+/** Read-ahead area in applying log records to file pages */
#define RECV_READ_AHEAD_AREA 32
+/** The recovery system */
UNIV_INTERN recv_sys_t* recv_sys = NULL;
-UNIV_INTERN ibool recv_recovery_on = FALSE;
-UNIV_INTERN ibool recv_recovery_from_backup_on = FALSE;
-
-UNIV_INTERN ibool recv_needed_recovery = FALSE;
-
-UNIV_INTERN ibool recv_lsn_checks_on = FALSE;
+/** TRUE when applying redo log records during crash recovery; FALSE
+otherwise. Note that this is FALSE while a background thread is
+rolling back incomplete transactions. */
+UNIV_INTERN ibool recv_recovery_on;
+#ifdef UNIV_LOG_ARCHIVE
+/** TRUE when applying redo log records from an archived log file */
+UNIV_INTERN ibool recv_recovery_from_backup_on;
+#endif /* UNIV_LOG_ARCHIVE */
-/* There are two conditions under which we scan the logs, the first
+#ifndef UNIV_HOTBACKUP
+/** TRUE when recv_init_crash_recovery() has been called. */
+UNIV_INTERN ibool recv_needed_recovery;
+# ifdef UNIV_DEBUG
+/** TRUE if writing to the redo log (mtr_commit) is forbidden.
+Protected by log_sys->mutex. */
+UNIV_INTERN ibool recv_no_log_write = FALSE;
+# endif /* UNIV_DEBUG */
+
+/** TRUE if buf_page_is_corrupted() should check if the log sequence
+number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
+recv_recovery_from_checkpoint_start_func(). */
+UNIV_INTERN ibool recv_lsn_checks_on;
+
+/** There are two conditions under which we scan the logs, the first
is normal startup and the second is when we do a recovery from an
archive.
This flag is set if we are doing a scan from the last checkpoint during
@@ -74,61 +97,68 @@ startup. If we find log entries that were written after the last checkpoint
we know that the server was not cleanly shutdown. We must then initialize
the crash recovery environment before attempting to store these entries in
the log hash table. */
-UNIV_INTERN ibool recv_log_scan_is_startup_type = FALSE;
+static ibool recv_log_scan_is_startup_type;
-/* If the following is TRUE, the buffer pool file pages must be invalidated
+/** If the following is TRUE, the buffer pool file pages must be invalidated
after recovery and no ibuf operations are allowed; this becomes TRUE if
the log record hash table becomes too full, and log records must be merged
to file pages already before the recovery is finished: in this case no
ibuf operations are allowed, as they could modify the pages read in the
-buffer pool before the pages have been recovered to the up-to-date state */
-
-/* Recovery is running and no operations on the log files are allowed
-yet: the variable name is misleading */
-
-UNIV_INTERN ibool recv_no_ibuf_operations = FALSE;
-
-/* The following counter is used to decide when to print info on
-log scan */
-UNIV_INTERN ulint recv_scan_print_counter = 0;
-
+buffer pool before the pages have been recovered to the up-to-date state.
+
+TRUE means that recovery is running and no operations on the log files
+are allowed yet: the variable name is misleading. */
+UNIV_INTERN ibool recv_no_ibuf_operations;
+/** TRUE when the redo log is being backed up */
+# define recv_is_making_a_backup FALSE
+/** TRUE when recovering from a backed up redo log file */
+# define recv_is_from_backup FALSE
+#else /* !UNIV_HOTBACKUP */
+# define recv_needed_recovery FALSE
+/** TRUE when the redo log is being backed up */
+UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
+/** TRUE when recovering from a backed up redo log file */
UNIV_INTERN ibool recv_is_from_backup = FALSE;
-#ifdef UNIV_HOTBACKUP
-UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
-#else
-# define recv_is_making_a_backup FALSE
-#endif /* UNIV_HOTBACKUP */
+# define buf_pool_get_curr_size() (5 * 1024 * 1024)
+#endif /* !UNIV_HOTBACKUP */
+/** The following counter is used to decide when to print info on
+log scan */
+static ulint recv_scan_print_counter;
-UNIV_INTERN ulint recv_previous_parsed_rec_type = 999999;
-UNIV_INTERN ulint recv_previous_parsed_rec_offset = 0;
-UNIV_INTERN ulint recv_previous_parsed_rec_is_multi = 0;
+/** The type of the previous parsed redo log record */
+static ulint recv_previous_parsed_rec_type;
+/** The offset of the previous parsed redo log record */
+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;
-UNIV_INTERN ulint recv_max_parsed_page_no = 0;
+/** Maximum page number encountered in the redo log */
+UNIV_INTERN ulint recv_max_parsed_page_no;
-/* This many frames must be left free in the buffer pool when we scan
+/** 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. */
+UNIV_INTERN ulint recv_n_pool_free_frames;
-UNIV_INTERN ulint recv_n_pool_free_frames = 1024;
-
-/* The maximum lsn we see for a page during the recovery process. If this
+/** 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. */
-
UNIV_INTERN ib_uint64_t recv_max_page_lsn;
/* prototypes */
-/***********************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************//**
Initialize crash recovery environment. Can be called iff
recv_needed_recovery == FALSE. */
static
void
recv_init_crash_recovery(void);
/*===========================*/
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
+/********************************************************//**
Creates the recovery system. */
UNIV_INTERN
void
@@ -140,12 +170,116 @@ recv_sys_create(void)
return;
}
- recv_sys = mem_alloc(sizeof(recv_sys_t));
+ recv_sys = mem_alloc(sizeof(*recv_sys));
+ memset(recv_sys, 0x0, sizeof(*recv_sys));
mutex_create(&recv_sys->mutex, SYNC_RECV);
recv_sys->heap = NULL;
recv_sys->addr_hash = NULL;
+
+ recv_sys->stats_recv_start_time = time(NULL);
+ recv_sys->stats_oldest_modified_lsn = IB_ULONGLONG_MAX;
+}
+
+/********************************************************//**
+Release recovery system mutexes. */
+UNIV_INTERN
+void
+recv_sys_close(void)
+/*================*/
+{
+ if (recv_sys != NULL) {
+ if (recv_sys->addr_hash != NULL) {
+ hash_table_free(recv_sys->addr_hash);
+ }
+
+ if (recv_sys->heap != NULL) {
+ mem_heap_free(recv_sys->heap);
+ }
+
+ if (recv_sys->buf != NULL) {
+ ut_free(recv_sys->buf);
+ }
+
+ if (recv_sys->last_block_buf_start != NULL) {
+ mem_free(recv_sys->last_block_buf_start);
+ }
+
+ mutex_free(&recv_sys->mutex);
+
+ mem_free(recv_sys);
+ recv_sys = NULL;
+ }
+}
+
+/********************************************************//**
+Frees the recovery system memory. */
+UNIV_INTERN
+void
+recv_sys_mem_free(void)
+/*===================*/
+{
+ if (recv_sys != NULL) {
+ if (recv_sys->addr_hash != NULL) {
+ hash_table_free(recv_sys->addr_hash);
+ }
+
+ if (recv_sys->heap != NULL) {
+ mem_heap_free(recv_sys->heap);
+ }
+
+ if (recv_sys->buf != NULL) {
+ ut_free(recv_sys->buf);
+ }
+
+ if (recv_sys->last_block_buf_start != NULL) {
+ mem_free(recv_sys->last_block_buf_start);
+ }
+
+ mem_free(recv_sys);
+ recv_sys = NULL;
+ }
+}
+
+/************************************************************
+Reset the state of the recovery system variables. */
+UNIV_INTERN
+void
+recv_sys_var_init(void)
+/*===================*/
+{
+ recv_lsn_checks_on = FALSE;
+
+ recv_n_pool_free_frames = 1024;
+
+ recv_recovery_on = FALSE;
+
+#ifdef UNIV_LOG_ARCHIVE
+ recv_recovery_from_backup_on = FALSE;
+#endif /* UNIV_LOG_ARCHIVE */
+
+ recv_needed_recovery = FALSE;
+
+ recv_lsn_checks_on = FALSE;
+
+ recv_log_scan_is_startup_type = FALSE;
+
+ recv_no_ibuf_operations = FALSE;
+
+ recv_scan_print_counter = 0;
+
+ recv_previous_parsed_rec_type = 999999;
+
+ recv_previous_parsed_rec_offset = 0;
+
+ recv_previous_parsed_rec_is_multi = 0;
+
+ recv_max_parsed_page_no = 0;
+
+ recv_n_pool_free_frames = 1024;
+
+ recv_max_page_lsn = 0;
}
/************************************************************
@@ -154,9 +288,7 @@ UNIV_INTERN
void
recv_sys_init(
/*==========*/
- ibool recover_from_backup, /* in: TRUE if this is called
- to recover from a hot backup */
- ulint available_memory) /* in: available memory in bytes */
+ ulint available_memory) /*!< in: available memory in bytes */
{
if (recv_sys->heap != NULL) {
@@ -165,12 +297,12 @@ recv_sys_init(
mutex_enter(&(recv_sys->mutex));
- if (!recover_from_backup) {
- recv_sys->heap = mem_heap_create_in_buffer(256);
- } else {
- recv_sys->heap = mem_heap_create(256);
- recv_is_from_backup = TRUE;
- }
+#ifndef UNIV_HOTBACKUP
+ recv_sys->heap = mem_heap_create_in_buffer(256);
+#else /* !UNIV_HOTBACKUP */
+ recv_sys->heap = mem_heap_create(256);
+ recv_is_from_backup = TRUE;
+#endif /* !UNIV_HOTBACKUP */
recv_sys->buf = ut_malloc(RECV_PARSING_BUF_SIZE);
recv_sys->len = 0;
@@ -193,7 +325,7 @@ recv_sys_init(
mutex_exit(&(recv_sys->mutex));
}
-/************************************************************
+/********************************************************//**
Empties the hash table when it has been fully processed. */
static
void
@@ -219,13 +351,14 @@ recv_sys_empty_hash(void)
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256);
}
-#ifndef UNIV_LOG_DEBUG
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+# ifndef UNIV_LOG_DEBUG
+/********************************************************//**
Frees the recovery system. */
static
void
-recv_sys_free(void)
-/*===============*/
+recv_sys_debug_free(void)
+/*=====================*/
{
mutex_enter(&(recv_sys->mutex));
@@ -234,27 +367,29 @@ recv_sys_free(void)
ut_free(recv_sys->buf);
mem_free(recv_sys->last_block_buf_start);
- recv_sys->addr_hash = NULL;
+ recv_sys->buf = NULL;
recv_sys->heap = NULL;
+ recv_sys->addr_hash = NULL;
+ recv_sys->last_block_buf_start = NULL;
mutex_exit(&(recv_sys->mutex));
}
-#endif /* UNIV_LOG_DEBUG */
+# endif /* UNIV_LOG_DEBUG */
-/************************************************************
+/********************************************************//**
Truncates possible corrupted or extra records from a log group. */
static
void
recv_truncate_group(
/*================*/
- log_group_t* group, /* in: log group */
- ib_uint64_t recovered_lsn, /* in: recovery succeeded up to this
+ log_group_t* group, /*!< in: log group */
+ ib_uint64_t recovered_lsn, /*!< in: recovery succeeded up to this
lsn */
- ib_uint64_t limit_lsn, /* in: this was the limit for
+ ib_uint64_t limit_lsn, /*!< in: this was the limit for
recovery */
- ib_uint64_t checkpoint_lsn, /* in: recovery was started from this
+ ib_uint64_t checkpoint_lsn, /*!< in: recovery was started from this
checkpoint */
- ib_uint64_t archived_lsn) /* in: the log has been archived up to
+ ib_uint64_t archived_lsn) /*!< in: the log has been archived up to
this lsn */
{
ib_uint64_t start_lsn;
@@ -341,18 +476,18 @@ recv_truncate_group(
}
}
-/************************************************************
+/********************************************************//**
Copies the log segment between group->recovered_lsn and recovered_lsn from the
most up-to-date log group to group, so that it contains the latest log data. */
static
void
recv_copy_group(
/*============*/
- log_group_t* up_to_date_group, /* in: the most up-to-date log
+ log_group_t* up_to_date_group, /*!< in: the most up-to-date log
group */
- log_group_t* group, /* in: copy to this log
+ log_group_t* group, /*!< in: copy to this log
group */
- ib_uint64_t recovered_lsn) /* in: recovery succeeded up
+ ib_uint64_t recovered_lsn) /*!< in: recovery succeeded up
to this lsn */
{
ib_uint64_t start_lsn;
@@ -392,7 +527,7 @@ recv_copy_group(
}
}
-/************************************************************
+/********************************************************//**
Copies a log segment from the most up-to-date log group to the other log
groups, so that they all contain the latest log data. Also writes the info
about the latest checkpoint to the groups, and inits the fields in the group
@@ -401,7 +536,7 @@ static
void
recv_synchronize_groups(
/*====================*/
- log_group_t* up_to_date_group) /* in: the most up-to-date
+ log_group_t* up_to_date_group) /*!< in: the most up-to-date
log group */
{
log_group_t* group;
@@ -459,15 +594,16 @@ recv_synchronize_groups(
mutex_enter(&(log_sys->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
-Checks the consistency of the checkpoint info */
+/***********************************************************************//**
+Checks the consistency of the checkpoint info
+@return TRUE if ok */
static
ibool
recv_check_cp_is_consistent(
/*========================*/
- /* out: TRUE if ok */
- byte* buf) /* in: buffer containing checkpoint info */
+ const byte* buf) /*!< in: buffer containing checkpoint info */
{
ulint fold;
@@ -489,15 +625,16 @@ recv_check_cp_is_consistent(
return(TRUE);
}
-/************************************************************
-Looks for the maximum consistent checkpoint from the log groups. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
+Looks for the maximum consistent checkpoint from the log groups.
+@return error code or DB_SUCCESS */
static
ulint
recv_find_max_checkpoint(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- log_group_t** max_group, /* out: max group */
- ulint* max_field) /* out: LOG_CHECKPOINT_1 or
+ log_group_t** max_group, /*!< out: max group */
+ ulint* max_field) /*!< out: LOG_CHECKPOINT_1 or
LOG_CHECKPOINT_2 */
{
log_group_t* group;
@@ -582,37 +719,35 @@ not_consistent:
"InnoDB: to create the InnoDB data files,"
" but log file creation failed.\n"
"InnoDB: If that is the case, please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "error-creating-innodb.html\n");
+ "InnoDB: " REFMAN "error-creating-innodb.html\n");
return(DB_ERROR);
}
return(DB_SUCCESS);
}
-
-#ifdef UNIV_HOTBACKUP
-/***********************************************************************
-Reads the checkpoint info needed in hot backup. */
+#else /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
+Reads the checkpoint info needed in hot backup.
+@return TRUE if success */
UNIV_INTERN
ibool
recv_read_cp_info_for_backup(
/*=========================*/
- /* out: TRUE if success */
- byte* hdr, /* in: buffer containing the log group
+ const byte* hdr, /*!< in: buffer containing the log group
header */
- ib_uint64_t* lsn, /* out: checkpoint lsn */
- ulint* offset, /* out: checkpoint offset in the log group */
- ulint* fsp_limit,/* out: fsp limit of space 0,
+ ib_uint64_t* lsn, /*!< out: checkpoint lsn */
+ ulint* offset, /*!< out: checkpoint offset in the log group */
+ ulint* fsp_limit,/*!< out: fsp limit of space 0,
1000000000 if the database is running
with < version 3.23.50 of InnoDB */
- ib_uint64_t* cp_no, /* out: checkpoint number */
+ ib_uint64_t* cp_no, /*!< out: checkpoint number */
ib_uint64_t* first_header_lsn)
- /* out: lsn of of the start of the
+ /*!< out: lsn of of the start of the
first log file */
{
ulint max_cp = 0;
ib_uint64_t max_cp_no = 0;
- byte* cp_buf;
+ const byte* cp_buf;
cp_buf = hdr + LOG_CHECKPOINT_1;
@@ -661,19 +796,19 @@ recv_read_cp_info_for_backup(
return(TRUE);
}
-#endif /* UNIV_HOTBACKUP */
-
-/**********************************************************
-Checks the 4-byte checksum to the trailer checksum field of a log block.
-We also accept a log block in the old format < InnoDB-3.23.52 where the
-checksum field contains the log block number. */
+#endif /* !UNIV_HOTBACKUP */
+
+/******************************************************//**
+Checks the 4-byte checksum to the trailer checksum field of a log
+block. We also accept a log block in the old format before
+InnoDB-3.23.52 where the checksum field contains the log block number.
+@return TRUE if ok, or if the log block may be in the format of InnoDB
+version predating 3.23.52 */
static
ibool
log_block_checksum_is_ok_or_old_format(
/*===================================*/
- /* out: TRUE if ok, or if the log block may be in the
- format of InnoDB version < 3.23.52 */
- byte* block) /* in: pointer to a log block */
+ const byte* block) /*!< in: pointer to a log block */
{
#ifdef UNIV_LOG_DEBUG
return(TRUE);
@@ -700,22 +835,22 @@ log_block_checksum_is_ok_or_old_format(
}
#ifdef UNIV_HOTBACKUP
-/***********************************************************************
+/*******************************************************************//**
Scans the log segment and n_bytes_scanned is set to the length of valid
log scanned. */
UNIV_INTERN
void
recv_scan_log_seg_for_backup(
/*=========================*/
- byte* buf, /* in: buffer containing log data */
- ulint buf_len, /* in: data length in that buffer */
- ib_uint64_t* scanned_lsn, /* in/out: lsn of buffer start,
+ byte* buf, /*!< in: buffer containing log data */
+ ulint buf_len, /*!< in: data length in that buffer */
+ ib_uint64_t* scanned_lsn, /*!< in/out: lsn of buffer start,
we return scanned lsn */
ulint* scanned_checkpoint_no,
- /* in/out: 4 lowest bytes of the
+ /*!< in/out: 4 lowest bytes of the
highest scanned checkpoint number so
far */
- ulint* n_bytes_scanned)/* out: how much we were able to
+ ulint* n_bytes_scanned)/*!< out: how much we were able to
scan, smaller than buf_len if log
data ended here */
{
@@ -791,44 +926,129 @@ recv_scan_log_seg_for_backup(
}
#endif /* UNIV_HOTBACKUP */
-/***********************************************************************
+/*******************************************************************//**
Tries to parse a single log record body and also applies it to a page if
-specified. File ops are parsed, but not applied in this function. */
+specified. File ops are parsed, but not applied in this function.
+@return log record end, NULL if not a complete record */
static
byte*
recv_parse_or_apply_log_rec_body(
/*=============================*/
- /* out: log record end, NULL if not a
- complete record */
- byte type, /* in: type */
- byte* ptr, /* in: pointer to a buffer */
- byte* end_ptr,/* in: pointer to the buffer end */
- buf_block_t* block, /* in/out: buffer block or NULL; if
+ byte type, /*!< in: type */
+ byte* ptr, /*!< in: pointer to a buffer */
+ byte* end_ptr,/*!< in: pointer to the buffer end */
+ buf_block_t* block, /*!< in/out: buffer block or NULL; if
not NULL, then the log record is
applied to the page, and the log
record should be complete then */
- mtr_t* mtr) /* in: mtr or NULL; should be non-NULL
+ mtr_t* mtr) /*!< in: mtr or NULL; should be non-NULL
if and only if block is non-NULL */
{
dict_index_t* index = NULL;
page_t* page;
page_zip_des_t* page_zip;
+#ifdef UNIV_DEBUG
+ ulint page_type;
+#endif /* UNIV_DEBUG */
ut_ad(!block == !mtr);
if (block) {
page = block->frame;
page_zip = buf_block_get_page_zip(block);
+ ut_d(page_type = fil_page_get_type(page));
} else {
page = NULL;
page_zip = NULL;
+ ut_d(page_type = FIL_PAGE_TYPE_ALLOCATED);
}
switch (type) {
+#ifdef UNIV_LOG_LSN_DEBUG
+ case MLOG_LSN:
+ /* The LSN is checked in recv_parse_log_rec(). */
+ break;
+#endif /* UNIV_LOG_LSN_DEBUG */
case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
+#ifdef UNIV_DEBUG
+ if (page && page_type == FIL_PAGE_TYPE_ALLOCATED
+ && end_ptr >= ptr + 2) {
+ /* It is OK to set FIL_PAGE_TYPE and certain
+ list node fields on an empty page. Any other
+ write is not OK. */
+
+ /* NOTE: There may be bogus assertion failures for
+ dict_hdr_create(), trx_rseg_header_create(),
+ trx_sys_create_doublewrite_buf(), and
+ trx_sysf_create().
+ These are only called during database creation. */
+ ulint offs = mach_read_from_2(ptr);
+
+ switch (type) {
+ default:
+ ut_error;
+ case MLOG_2BYTES:
+ /* Note that this can fail when the
+ redo log been written with something
+ older than InnoDB Plugin 1.0.4. */
+ ut_ad(offs == FIL_PAGE_TYPE
+ || offs == IBUF_TREE_SEG_HEADER
+ + IBUF_HEADER + FSEG_HDR_OFFSET
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER + FIL_ADDR_BYTE
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER + FIL_ADDR_BYTE
+ + FIL_ADDR_SIZE
+ || offs == PAGE_BTR_SEG_LEAF
+ + PAGE_HEADER + FSEG_HDR_OFFSET
+ || offs == PAGE_BTR_SEG_TOP
+ + PAGE_HEADER + FSEG_HDR_OFFSET
+ || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
+ + PAGE_HEADER + FIL_ADDR_BYTE
+ + 0 /*FLST_PREV*/
+ || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
+ + PAGE_HEADER + FIL_ADDR_BYTE
+ + FIL_ADDR_SIZE /*FLST_NEXT*/);
+ break;
+ case MLOG_4BYTES:
+ /* Note that this can fail when the
+ redo log been written with something
+ older than InnoDB Plugin 1.0.4. */
+ ut_ad(0
+ || offs == IBUF_TREE_SEG_HEADER
+ + IBUF_HEADER + FSEG_HDR_SPACE
+ || offs == IBUF_TREE_SEG_HEADER
+ + IBUF_HEADER + FSEG_HDR_PAGE_NO
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER/* flst_init */
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER + FIL_ADDR_PAGE
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER + FIL_ADDR_PAGE
+ + FIL_ADDR_SIZE
+ || offs == PAGE_BTR_SEG_LEAF
+ + PAGE_HEADER + FSEG_HDR_PAGE_NO
+ || offs == PAGE_BTR_SEG_LEAF
+ + PAGE_HEADER + FSEG_HDR_SPACE
+ || offs == PAGE_BTR_SEG_TOP
+ + PAGE_HEADER + FSEG_HDR_PAGE_NO
+ || offs == PAGE_BTR_SEG_TOP
+ + PAGE_HEADER + FSEG_HDR_SPACE
+ || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
+ + PAGE_HEADER + FIL_ADDR_PAGE
+ + 0 /*FLST_PREV*/
+ || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
+ + PAGE_HEADER + FIL_ADDR_PAGE
+ + FIL_ADDR_SIZE /*FLST_NEXT*/);
+ break;
+ }
+ }
+#endif /* UNIV_DEBUG */
ptr = mlog_parse_nbytes(type, ptr, end_ptr, page, page_zip);
break;
case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_REC_INSERT,
@@ -841,6 +1061,8 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_REC_CLUST_DELETE_MARK: case MLOG_COMP_REC_CLUST_DELETE_MARK:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_REC_CLUST_DELETE_MARK,
@@ -853,6 +1075,7 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_COMP_REC_SEC_DELETE_MARK:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
/* This log record type is obsolete, but we process it for
backward compatibility with MySQL 5.0.3 and 5.0.4. */
ut_a(!page || page_is_comp(page));
@@ -863,10 +1086,13 @@ recv_parse_or_apply_log_rec_body(
}
/* Fall through */
case MLOG_REC_SEC_DELETE_MARK:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr,
page, page_zip);
break;
case MLOG_REC_UPDATE_IN_PLACE: case MLOG_COMP_REC_UPDATE_IN_PLACE:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_REC_UPDATE_IN_PLACE,
@@ -880,6 +1106,8 @@ recv_parse_or_apply_log_rec_body(
break;
case MLOG_LIST_END_DELETE: case MLOG_COMP_LIST_END_DELETE:
case MLOG_LIST_START_DELETE: case MLOG_COMP_LIST_START_DELETE:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_LIST_END_DELETE
@@ -893,6 +1121,8 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_LIST_END_COPY_CREATED,
@@ -905,6 +1135,8 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_PAGE_REORGANIZE: case MLOG_COMP_PAGE_REORGANIZE:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_PAGE_REORGANIZE,
@@ -917,29 +1149,36 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_PAGE_CREATE: case MLOG_COMP_PAGE_CREATE:
+ /* Allow anything in page_type when creating a page. */
ut_a(!page_zip);
ptr = page_parse_create(ptr, end_ptr,
type == MLOG_COMP_PAGE_CREATE,
block, mtr);
break;
case MLOG_UNDO_INSERT:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_add_undo_rec(ptr, end_ptr, page);
break;
case MLOG_UNDO_ERASE_END:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_erase_page_end(ptr, end_ptr, page, mtr);
break;
case MLOG_UNDO_INIT:
+ /* Allow anything in page_type when creating a page. */
ptr = trx_undo_parse_page_init(ptr, end_ptr, page, mtr);
break;
case MLOG_UNDO_HDR_DISCARD:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_discard_latest(ptr, end_ptr, page, mtr);
break;
case MLOG_UNDO_HDR_CREATE:
case MLOG_UNDO_HDR_REUSE:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_page_header(type, ptr, end_ptr,
page, mtr);
break;
case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
/* On a compressed page, MLOG_COMP_REC_MIN_MARK
will be followed by MLOG_COMP_REC_DELETE
or MLOG_ZIP_WRITE_HEADER(FIL_PAGE_PREV, FIL_NULL)
@@ -950,6 +1189,8 @@ recv_parse_or_apply_log_rec_body(
page, mtr);
break;
case MLOG_REC_DELETE: case MLOG_COMP_REC_DELETE:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_REC_DELETE,
@@ -962,33 +1203,40 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_IBUF_BITMAP_INIT:
+ /* Allow anything in page_type when creating a page. */
ptr = ibuf_parse_bitmap_init(ptr, end_ptr, block, mtr);
break;
case MLOG_INIT_FILE_PAGE:
+ /* Allow anything in page_type when creating a page. */
ptr = fsp_parse_init_file_page(ptr, end_ptr, block);
break;
case MLOG_WRITE_STRING:
+ ut_ad(!page || page_type != FIL_PAGE_TYPE_ALLOCATED);
ptr = mlog_parse_string(ptr, end_ptr, page, page_zip);
break;
case MLOG_FILE_CREATE:
case MLOG_FILE_RENAME:
case MLOG_FILE_DELETE:
case MLOG_FILE_CREATE2:
- ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0);
+ ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0);
break;
case MLOG_ZIP_WRITE_NODE_PTR:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
ptr = page_zip_parse_write_node_ptr(ptr, end_ptr,
page, page_zip);
break;
case MLOG_ZIP_WRITE_BLOB_PTR:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
ptr = page_zip_parse_write_blob_ptr(ptr, end_ptr,
page, page_zip);
break;
case MLOG_ZIP_WRITE_HEADER:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
ptr = page_zip_parse_write_header(ptr, end_ptr,
page, page_zip);
break;
case MLOG_ZIP_PAGE_COMPRESS:
+ /* Allow anything in page_type when creating a page. */
ptr = page_zip_parse_compress(ptr, end_ptr,
page, page_zip);
break;
@@ -1007,44 +1255,43 @@ recv_parse_or_apply_log_rec_body(
return(ptr);
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
-searching for a log record in the hash table. */
+searching for a log record in the hash table.
+@return folded value */
UNIV_INLINE
ulint
recv_fold(
/*======*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
return(ut_fold_ulint_pair(space, page_no));
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the hash value of a page file address: used in inserting or
-searching for a log record in the hash table. */
+searching for a log record in the hash table.
+@return folded value */
UNIV_INLINE
ulint
recv_hash(
/*======*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
return(hash_calc_hash(recv_fold(space, page_no), recv_sys->addr_hash));
}
-/*************************************************************************
-Gets the hashed file address struct for a page. */
+/*********************************************************************//**
+Gets the hashed file address struct for a page.
+@return file address struct, NULL if not found from the hash table */
static
recv_addr_t*
recv_get_fil_addr_struct(
/*=====================*/
- /* out: file address struct, NULL if not found from
- the hash table */
- ulint space, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
recv_addr_t* recv_addr;
@@ -1063,19 +1310,19 @@ recv_get_fil_addr_struct(
return(recv_addr);
}
-/***********************************************************************
+/*******************************************************************//**
Adds a new log record to the hash table of log records. */
static
void
recv_add_to_hash_table(
/*===================*/
- byte type, /* in: log record type */
- ulint space, /* in: space id */
- ulint page_no, /* in: page number */
- byte* body, /* in: log record body */
- byte* rec_end, /* in: log record end */
- ib_uint64_t start_lsn, /* in: start lsn of the mtr */
- ib_uint64_t end_lsn) /* in: end lsn of the mtr */
+ byte type, /*!< in: log record type */
+ ulint space, /*!< in: space id */
+ ulint page_no, /*!< in: page number */
+ byte* body, /*!< in: log record body */
+ byte* rec_end, /*!< in: log record end */
+ ib_uint64_t start_lsn, /*!< in: start lsn of the mtr */
+ ib_uint64_t end_lsn) /*!< in: end lsn of the mtr */
{
recv_t* recv;
ulint len;
@@ -1092,6 +1339,11 @@ recv_add_to_hash_table(
len = rec_end - body;
+ if (srv_recovery_stats) {
+ recv_sys->stats_log_recs++;
+ recv_sys->stats_log_len_sum += len;
+ }
+
recv = mem_heap_alloc(recv_sys->heap, sizeof(recv_t));
recv->type = type;
recv->len = rec_end - body;
@@ -1138,7 +1390,7 @@ recv_add_to_hash_table(
sizeof(recv_data_t) + len);
*prev_field = recv_data;
- ut_memcpy(((byte*)recv_data) + sizeof(recv_data_t), body, len);
+ memcpy(recv_data + 1, body, len);
prev_field = &(recv_data->next);
@@ -1148,14 +1400,14 @@ recv_add_to_hash_table(
*prev_field = NULL;
}
-/*************************************************************************
+/*********************************************************************//**
Copies the log record body from recv to buf. */
static
void
recv_data_copy_to_buf(
/*==================*/
- byte* buf, /* in: buffer of length at least recv->len */
- recv_t* recv) /* in: log record */
+ byte* buf, /*!< in: buffer of length at least recv->len */
+ recv_t* recv) /*!< in: log record */
{
recv_data_t* recv_data;
ulint part_len;
@@ -1180,34 +1432,35 @@ recv_data_copy_to_buf(
}
}
-/****************************************************************************
+/************************************************************************//**
Applies the hashed log records to the page, if the page lsn is less than the
lsn of a log record. This can be called when a buffer page has just been
read in, or also for a page already in the buffer pool. */
UNIV_INTERN
void
-recv_recover_page(
-/*==============*/
- ibool recover_backup,
- /* in: TRUE if we are recovering a backup
- page: then we do not acquire any latches
- since the page was read in outside the
- buffer pool */
+recv_recover_page_func(
+/*===================*/
+#ifndef UNIV_HOTBACKUP
ibool just_read_in,
- /* in: TRUE if the i/o-handler calls this for
- a freshly read page */
- buf_block_t* block) /* in: buffer block */
+ /*!< in: TRUE if the i/o handler calls
+ this for a freshly read page */
+#endif /* !UNIV_HOTBACKUP */
+ buf_block_t* block) /*!< in/out: buffer block */
{
page_t* page;
+ page_zip_des_t* page_zip;
recv_addr_t* recv_addr;
recv_t* recv;
byte* buf;
ib_uint64_t start_lsn;
ib_uint64_t end_lsn;
ib_uint64_t page_lsn;
+ ib_uint64_t page_lsn_orig;
ib_uint64_t page_newest_lsn;
ibool modification_to_page;
+#ifndef UNIV_HOTBACKUP
ibool success;
+#endif /* !UNIV_HOTBACKUP */
mtr_t mtr;
mutex_enter(&(recv_sys->mutex));
@@ -1242,57 +1495,78 @@ recv_recover_page(
recv_addr->state = RECV_BEING_PROCESSED;
+ if (srv_recovery_stats) {
+ if (just_read_in) {
+ recv_sys->stats_recover_pages_with_read++;
+ } else {
+ recv_sys->stats_recover_pages_without_read++;
+ }
+ }
+
mutex_exit(&(recv_sys->mutex));
mtr_start(&mtr);
mtr_set_log_mode(&mtr, MTR_LOG_NONE);
page = block->frame;
+ page_zip = buf_block_get_page_zip(block);
- if (!recover_backup) {
- if (just_read_in) {
- /* Move the ownership of the x-latch on the
- page to this OS thread, so that we can acquire
- a second x-latch on it. This is needed for the
- operations to the page to pass the debug
- checks. */
+#ifndef UNIV_HOTBACKUP
+ if (just_read_in) {
+ /* Move the ownership of the x-latch on the page to
+ this OS thread, so that we can acquire a second
+ x-latch on it. This is needed for the operations to
+ the page to pass the debug checks. */
- rw_lock_x_lock_move_ownership(&(block->lock));
- }
+ rw_lock_x_lock_move_ownership(&block->lock);
+ }
- success = buf_page_get_known_nowait(RW_X_LATCH, block,
- BUF_KEEP_OLD,
- __FILE__, __LINE__,
- &mtr);
- ut_a(success);
+ success = buf_page_get_known_nowait(RW_X_LATCH, block,
+ BUF_KEEP_OLD,
+ __FILE__, __LINE__,
+ &mtr);
+ ut_a(success);
- buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
- }
+ buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
+#endif /* !UNIV_HOTBACKUP */
/* Read the newest modification lsn from the page */
page_lsn = mach_read_ull(page + FIL_PAGE_LSN);
+ page_lsn_orig = page_lsn;
- if (!recover_backup) {
- /* It may be that the page has been modified in the buffer
- pool: read the newest modification lsn there */
-
- page_newest_lsn
- = buf_page_get_newest_modification(&block->page);
+#ifndef UNIV_HOTBACKUP
+ /* It may be that the page has been modified in the buffer
+ pool: read the newest modification lsn there */
- if (page_newest_lsn) {
+ page_newest_lsn = buf_page_get_newest_modification(&block->page);
- page_lsn = page_newest_lsn;
- }
- } else {
- /* In recovery from a backup we do not really use the buffer
- pool */
+ if (page_newest_lsn) {
- page_newest_lsn = 0;
+ page_lsn = page_newest_lsn;
}
+#else /* !UNIV_HOTBACKUP */
+ /* In recovery from a backup we do not really use the buffer pool */
+ page_newest_lsn = 0;
+#endif /* !UNIV_HOTBACKUP */
modification_to_page = FALSE;
start_lsn = end_lsn = 0;
+ if (srv_recovery_stats) {
+ mutex_enter(&(recv_sys->mutex));
+ if (page_lsn_orig && recv_sys->stats_oldest_modified_lsn > page_lsn_orig) {
+ recv_sys->stats_oldest_modified_lsn = page_lsn_orig;
+ }
+ if (page_lsn_orig && recv_sys->stats_newest_modified_lsn < page_lsn_orig) {
+ recv_sys->stats_newest_modified_lsn = page_lsn_orig;
+ }
+ if (UT_LIST_GET_LAST(recv_addr->rec_list)->start_lsn
+ < page_lsn_orig) {
+ recv_sys->stats_pages_already_new++;
+ }
+ mutex_exit(&(recv_sys->mutex));
+ }
+
recv = UT_LIST_GET_FIRST(recv_addr->rec_list);
while (recv) {
@@ -1312,13 +1586,19 @@ recv_recover_page(
if (recv->type == MLOG_INIT_FILE_PAGE) {
page_lsn = page_newest_lsn;
- mach_write_ull(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM, 0);
- mach_write_ull(page + FIL_PAGE_LSN, 0);
+ memset(FIL_PAGE_LSN + page, 0, 8);
+ memset(UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM
+ + page, 0, 8);
+
+ if (page_zip) {
+ memset(FIL_PAGE_LSN + page_zip->data, 0, 8);
+ }
}
if (recv->start_lsn >= page_lsn) {
+ ib_uint64_t end_lsn;
+
if (!modification_to_page) {
modification_to_page = TRUE;
@@ -1340,11 +1620,24 @@ recv_recover_page(
recv_parse_or_apply_log_rec_body(recv->type, buf,
buf + recv->len,
block, &mtr);
- mach_write_ull(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM,
- recv->start_lsn + recv->len);
- mach_write_ull(page + FIL_PAGE_LSN,
- recv->start_lsn + recv->len);
+
+ if (srv_recovery_stats) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_applied_log_recs++;
+ recv_sys->stats_applied_log_len_sum += recv->len;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
+ end_lsn = recv->start_lsn + recv->len;
+ mach_write_ull(FIL_PAGE_LSN + page, end_lsn);
+ mach_write_ull(UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM
+ + page, end_lsn);
+
+ if (page_zip) {
+ mach_write_ull(FIL_PAGE_LSN
+ + page_zip->data, end_lsn);
+ }
}
if (recv->len > RECV_DATA_BLOCK_SIZE) {
@@ -1377,11 +1670,13 @@ recv_recover_page(
mutex_exit(&(recv_sys->mutex));
- if (!recover_backup && modification_to_page) {
+#ifndef UNIV_HOTBACKUP
+ if (modification_to_page) {
ut_a(block);
buf_flush_recv_note_modification(block, start_lsn, end_lsn);
}
+#endif /* !UNIV_HOTBACKUP */
/* Make sure that committing mtr does not change the modification
lsn values of page */
@@ -1391,17 +1686,18 @@ recv_recover_page(
mtr_commit(&mtr);
}
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Reads in pages which have hashed log records, from an area around a given
-page number. */
+page number.
+@return number of pages found */
static
ulint
recv_read_in_area(
/*==============*/
- /* out: number of pages found */
- ulint space, /* in: space */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no)/*!< in: page number */
{
recv_addr_t* recv_addr;
ulint page_nos[RECV_READ_AHEAD_AREA];
@@ -1432,6 +1728,13 @@ recv_read_in_area(
}
}
+ if (srv_recovery_stats && n) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_read_requested_pages += n;
+ recv_sys->stats_read_in_area[n - 1]++;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
buf_read_recv_pages(FALSE, space, zip_size, page_nos, n);
/*
fprintf(stderr, "Recv pages at %lu n %lu\n", page_nos[0], n);
@@ -1439,14 +1742,14 @@ recv_read_in_area(
return(n);
}
-/***********************************************************************
+/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
UNIV_INTERN
void
recv_apply_hashed_log_recs(
/*=======================*/
- ibool allow_ibuf) /* in: if TRUE, also ibuf operations are
+ ibool allow_ibuf) /*!< in: if TRUE, also ibuf operations are
allowed during the application; if FALSE,
no ibuf operations are allowed, and after
the application all file pages are flushed to
@@ -1515,7 +1818,7 @@ loop:
buf_block_dbg_add_level(
block, SYNC_NO_ORDER_CHECK);
- recv_recover_page(FALSE, FALSE, block);
+ recv_recover_page(FALSE, block);
mtr_commit(&mtr);
} else {
recv_read_in_area(space, zip_size,
@@ -1559,6 +1862,7 @@ loop:
/* Flush all the file pages to disk and invalidate them in
the buffer pool */
+ ut_d(recv_no_log_write = TRUE);
mutex_exit(&(recv_sys->mutex));
mutex_exit(&(log_sys->mutex));
@@ -1572,6 +1876,7 @@ loop:
mutex_enter(&(log_sys->mutex));
mutex_enter(&(recv_sys->mutex));
+ ut_d(recv_no_log_write = FALSE);
recv_no_ibuf_operations = FALSE;
}
@@ -1583,13 +1888,16 @@ loop:
if (has_printed) {
fprintf(stderr, "InnoDB: Apply batch completed\n");
+
+ if (srv_recovery_stats) {
+ recv_sys->stats_recv_turns++;
+ }
}
mutex_exit(&(recv_sys->mutex));
}
-
-#ifdef UNIV_HOTBACKUP
-/***********************************************************************
+#else /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
Applies log records in the hash table to a backup. */
UNIV_INTERN
void
@@ -1607,7 +1915,7 @@ recv_apply_log_recs_for_backup(void)
recv_sys->apply_log_recs = TRUE;
recv_sys->apply_batch_on = TRUE;
- block = buf_LRU_get_free_block(UNIV_PAGE_SIZE);
+ block = back_block1;
fputs("InnoDB: Starting an apply batch of log records"
" to the database...\n"
@@ -1675,6 +1983,10 @@ recv_apply_log_recs_for_backup(void)
recv_addr->space, zip_size,
recv_addr->page_no, 0, zip_size,
block->page.zip.data, NULL);
+ if (error == DB_SUCCESS
+ && !buf_zip_decompress(block, TRUE)) {
+ exit(1);
+ }
} else {
error = fil_io(OS_FILE_READ, TRUE,
recv_addr->space, 0,
@@ -1695,7 +2007,7 @@ recv_apply_log_recs_for_backup(void)
}
/* Apply the log records to this page */
- recv_recover_page(TRUE, FALSE, block);
+ recv_recover_page(FALSE, block);
/* Write the page back to the tablespace file using the
fil0fil.c routines */
@@ -1729,25 +2041,23 @@ skip_this_recv_addr:
}
}
- buf_block_free(block);
recv_sys_empty_hash();
}
-#endif /* UNIV_HOTBACKUP */
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
-Tries to parse a single log record and returns its length. */
+/*******************************************************************//**
+Tries to parse a single log record and returns its length.
+@return length of the record, or 0 if the record was not complete */
static
ulint
recv_parse_log_rec(
/*===============*/
- /* out: length of the record, or 0 if the record was
- not complete */
- byte* ptr, /* in: pointer to a buffer */
- byte* end_ptr,/* in: pointer to the buffer end */
- byte* type, /* out: type */
- ulint* space, /* out: space id */
- ulint* page_no,/* out: page number */
- byte** body) /* out: log record body start */
+ byte* ptr, /*!< in: pointer to a buffer */
+ byte* end_ptr,/*!< in: pointer to the buffer end */
+ byte* type, /*!< out: type */
+ ulint* space, /*!< out: space id */
+ ulint* page_no,/*!< out: page number */
+ byte** body) /*!< out: log record body start */
{
byte* new_ptr;
@@ -1782,6 +2092,17 @@ recv_parse_log_rec(
return(0);
}
+#ifdef UNIV_LOG_LSN_DEBUG
+ if (*type == MLOG_LSN) {
+ ib_uint64_t lsn = (ib_uint64_t) *space << 32 | *page_no;
+# ifdef UNIV_LOG_DEBUG
+ ut_a(lsn == log_sys->old_lsn);
+# else /* UNIV_LOG_DEBUG */
+ ut_a(lsn == recv_sys->recovered_lsn);
+# endif /* UNIV_LOG_DEBUG */
+ }
+#endif /* UNIV_LOG_LSN_DEBUG */
+
/* Check that page_no is sensible */
if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {
@@ -1805,14 +2126,14 @@ recv_parse_log_rec(
return(new_ptr - ptr);
}
-/***********************************************************
+/*******************************************************//**
Calculates the new value for lsn when more data is added to the log. */
static
ib_uint64_t
recv_calc_lsn_on_data_add(
/*======================*/
- ib_uint64_t lsn, /* in: old lsn */
- ib_uint64_t len) /* in: this many bytes of data is
+ ib_uint64_t lsn, /*!< in: old lsn */
+ ib_uint64_t len) /*!< in: this many bytes of data is
added, log block headers not included */
{
ulint frag_len;
@@ -1832,15 +2153,15 @@ recv_calc_lsn_on_data_add(
}
#ifdef UNIV_LOG_DEBUG
-/***********************************************************
+/*******************************************************//**
Checks that the parser recognizes incomplete initial segments of a log
record as incomplete. */
static
void
recv_check_incomplete_log_recs(
/*===========================*/
- byte* ptr, /* in: pointer to a complete log record */
- ulint len) /* in: length of the log record */
+ byte* ptr, /*!< in: pointer to a complete log record */
+ ulint len) /*!< in: length of the log record */
{
ulint i;
byte type;
@@ -1855,16 +2176,16 @@ recv_check_incomplete_log_recs(
}
#endif /* UNIV_LOG_DEBUG */
-/***********************************************************
+/*******************************************************//**
Prints diagnostic info of corrupt log. */
static
void
recv_report_corrupt_log(
/*====================*/
- byte* ptr, /* in: pointer to corrupt log record */
- byte type, /* in: type of the record */
- ulint space, /* in: space id, this may also be garbage */
- ulint page_no)/* in: page number, this may also be garbage */
+ byte* ptr, /*!< in: pointer to corrupt log record */
+ byte type, /*!< in: type of the record */
+ ulint space, /*!< in: space id, this may also be garbage */
+ ulint page_no)/*!< in: page number, this may also be garbage */
{
fprintf(stderr,
"InnoDB: ############### CORRUPT LOG RECORD FOUND\n"
@@ -1904,22 +2225,21 @@ recv_report_corrupt_log(
"InnoDB: far enough in recovery! Please run CHECK TABLE\n"
"InnoDB: on your InnoDB tables to check that they are ok!\n"
"InnoDB: If mysqld crashes after this recovery, look at\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
fflush(stderr);
}
-/***********************************************************
+/*******************************************************//**
Parses log records from a buffer and stores them to a hash table to wait
-merging to file pages. */
+merging to file pages.
+@return currently always returns FALSE */
static
ibool
recv_parse_log_recs(
/*================*/
- /* out: currently always returns FALSE */
- ibool store_to_hash) /* in: TRUE if the records should be stored
+ ibool store_to_hash) /*!< in: TRUE if the records should be stored
to the hash table; this is set to FALSE if just
debug checking is needed */
{
@@ -2023,7 +2343,8 @@ loop:
point to the datadir we should use there */
if (NULL == fil_op_log_parse_or_replay(
- body, end_ptr, type, space)) {
+ body, end_ptr, type,
+ space, page_no)) {
fprintf(stderr,
"InnoDB: Error: file op"
" log record of type %lu"
@@ -2039,6 +2360,12 @@ loop:
#endif
/* In normal mysqld crash recovery we do not try to
replay file operations */
+#ifdef UNIV_LOG_LSN_DEBUG
+ } else if (type == MLOG_LSN) {
+ /* Do not add these records to the hash table.
+ The page number and space id fields are misused
+ for something else. */
+#endif /* UNIV_LOG_LSN_DEBUG */
} else {
recv_add_to_hash_table(type, space, page_no, body,
ptr + len, old_lsn,
@@ -2070,11 +2397,11 @@ loop:
= recv_sys->recovered_offset + total_len;
recv_previous_parsed_rec_is_multi = 1;
- if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
#ifdef UNIV_LOG_DEBUG
+ if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
recv_check_incomplete_log_recs(ptr, len);
-#endif /* UNIV_LOG_DEBUG */
}
+#endif /* UNIV_LOG_DEBUG */
#ifdef UNIV_DEBUG
if (log_debug_writes) {
@@ -2138,7 +2465,11 @@ loop:
break;
}
- if (store_to_hash) {
+ if (store_to_hash
+#ifdef UNIV_LOG_LSN_DEBUG
+ && type != MLOG_LSN
+#endif /* UNIV_LOG_LSN_DEBUG */
+ ) {
recv_add_to_hash_table(type, space, page_no,
body, ptr + len,
old_lsn,
@@ -2152,16 +2483,16 @@ loop:
goto loop;
}
-/***********************************************************
+/*******************************************************//**
Adds data from a new log block to the parsing buffer of recv_sys if
-recv_sys->parse_start_lsn is non-zero. */
+recv_sys->parse_start_lsn is non-zero.
+@return TRUE if more data added */
static
ibool
recv_sys_add_to_parsing_buf(
/*========================*/
- /* out: TRUE if more data added */
- byte* log_block, /* in: log block */
- ib_uint64_t scanned_lsn) /* in: lsn of how far we were able
+ const byte* log_block, /*!< in: log block */
+ ib_uint64_t scanned_lsn) /*!< in: lsn of how far we were able
to find data in this log block */
{
ulint more_len;
@@ -2227,7 +2558,7 @@ recv_sys_add_to_parsing_buf(
return(TRUE);
}
-/***********************************************************
+/*******************************************************//**
Moves the parsing buffer data left to the buffer start. */
static
void
@@ -2242,39 +2573,34 @@ recv_sys_justify_left_parsing_buf(void)
recv_sys->recovered_offset = 0;
}
-/***********************************************************
-Scans log from a buffer and stores new log data to the parsing buffer. Parses
-and hashes the log records if new data found. */
+/*******************************************************//**
+Scans log from a buffer and stores new log data to the parsing buffer.
+Parses and hashes the log records if new data found. Unless
+UNIV_HOTBACKUP is defined, this function will apply log records
+automatically when the hash table becomes full.
+@return TRUE if limit_lsn has been reached, or not able to scan any
+more in this log group */
UNIV_INTERN
ibool
recv_scan_log_recs(
/*===============*/
- /* out: TRUE if limit_lsn has been
- reached, or not able to scan any more
- in this log group */
- ibool apply_automatically,/* in: TRUE if we want this
- function to apply log records
- automatically when the hash table
- becomes full; in the hot backup tool
- the tool does the applying, not this
- function */
- ulint available_memory,/* in: we let the hash table of recs
+ ulint available_memory,/*!< in: we let the hash table of recs
to grow to this size, at the maximum */
- ibool store_to_hash, /* in: TRUE if the records should be
+ ibool store_to_hash, /*!< in: TRUE if the records should be
stored to the hash table; this is set
to FALSE if just debug checking is
needed */
- byte* buf, /* in: buffer containing a log segment
- or garbage */
- ulint len, /* in: buffer length */
- ib_uint64_t start_lsn, /* in: buffer start lsn */
- ib_uint64_t* contiguous_lsn, /* in/out: it is known that all log
+ const byte* buf, /*!< in: buffer containing a log
+ segment or garbage */
+ ulint len, /*!< in: buffer length */
+ ib_uint64_t start_lsn, /*!< in: buffer start lsn */
+ ib_uint64_t* contiguous_lsn, /*!< in/out: it is known that all log
groups contain contiguous log data up
to this lsn */
- ib_uint64_t* group_scanned_lsn)/* out: scanning succeeded up to
+ ib_uint64_t* group_scanned_lsn)/*!< out: scanning succeeded up to
this lsn */
{
- byte* log_block;
+ const byte* log_block;
ulint no;
ib_uint64_t scanned_lsn;
ibool finished;
@@ -2284,7 +2610,6 @@ recv_scan_log_recs(
ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_ad(len > 0);
- ut_a(apply_automatically <= TRUE);
ut_a(store_to_hash <= TRUE);
finished = FALSE;
@@ -2293,8 +2618,7 @@ recv_scan_log_recs(
scanned_lsn = start_lsn;
more_data = FALSE;
- while (log_block < buf + len && !finished) {
-
+ do {
no = log_block_get_hdr_no(log_block);
/*
fprintf(stderr, "Log block header no %lu\n", no);
@@ -2385,6 +2709,7 @@ recv_scan_log_recs(
of startup type, we must initiate crash recovery
environment before parsing these log records. */
+#ifndef UNIV_HOTBACKUP
if (recv_log_scan_is_startup_type
&& !recv_needed_recovery) {
@@ -2394,6 +2719,7 @@ recv_scan_log_recs(
recv_sys->scanned_lsn);
recv_init_crash_recovery();
}
+#endif /* !UNIV_HOTBACKUP */
/* We were able to find more log data: add it to the
parsing buffer if parse_start_lsn is already
@@ -2422,10 +2748,11 @@ recv_scan_log_recs(
/* Log data for this group ends here */
finished = TRUE;
+ break;
} else {
log_block += OS_FILE_LOG_BLOCK_SIZE;
}
- }
+ } while (log_block < buf + len && !finished);
*group_scanned_lsn = scanned_lsn;
@@ -2447,9 +2774,9 @@ recv_scan_log_recs(
recv_parse_log_recs(store_to_hash);
+#ifndef UNIV_HOTBACKUP
if (store_to_hash && mem_heap_get_size(recv_sys->heap)
- > available_memory
- && apply_automatically) {
+ > available_memory) {
/* Hash table of log records has grown too big:
empty it; FALSE means no ibuf operations
@@ -2459,6 +2786,7 @@ recv_scan_log_recs(
recv_apply_hashed_log_recs(FALSE);
}
+#endif /* !UNIV_HOTBACKUP */
if (recv_sys->recovered_offset > RECV_PARSING_BUF_SIZE / 4) {
/* Move parsing buffer data to the buffer start */
@@ -2470,18 +2798,19 @@ recv_scan_log_recs(
return(finished);
}
-/***********************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************//**
Scans log from a buffer and stores new log data to the parsing buffer. Parses
and hashes the log records if new data found. */
static
void
recv_group_scan_log_recs(
/*=====================*/
- log_group_t* group, /* in: log group */
- ib_uint64_t* contiguous_lsn, /* in/out: it is known that all log
+ log_group_t* group, /*!< in: log group */
+ ib_uint64_t* contiguous_lsn, /*!< in/out: it is known that all log
groups contain contiguous log data up
to this lsn */
- ib_uint64_t* group_scanned_lsn)/* out: scanning succeeded up to
+ ib_uint64_t* group_scanned_lsn)/*!< out: scanning succeeded up to
this lsn */
{
ibool finished;
@@ -2499,7 +2828,7 @@ recv_group_scan_log_recs(
group, start_lsn, end_lsn);
finished = recv_scan_log_recs(
- TRUE, (buf_pool->curr_size - recv_n_pool_free_frames)
+ (buf_pool->curr_size - recv_n_pool_free_frames)
* UNIV_PAGE_SIZE, TRUE, log_sys->buf, RECV_SCAN_SIZE,
start_lsn, contiguous_lsn, group_scanned_lsn);
start_lsn = end_lsn;
@@ -2516,7 +2845,7 @@ recv_group_scan_log_recs(
#endif /* UNIV_DEBUG */
}
-/***********************************************************
+/*******************************************************//**
Initialize crash recovery environment. Can be called iff
recv_needed_recovery == FALSE. */
static
@@ -2557,24 +2886,25 @@ recv_init_crash_recovery(void)
}
}
-/************************************************************
+/********************************************************//**
Recovers from a checkpoint. When this function returns, the database is able
to start processing of new user transactions, but the function
recv_recovery_from_checkpoint_finish should be called later to complete
-the recovery and free the resources used in it. */
+the recovery and free the resources used in it.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
recv_recovery_from_checkpoint_start_func(
/*=====================================*/
- /* out: error code or DB_SUCCESS */
#ifdef UNIV_LOG_ARCHIVE
- ulint type, /* in: LOG_CHECKPOINT or LOG_ARCHIVE */
- ib_uint64_t limit_lsn, /* in: recover up to this lsn
+ ulint type, /*!< in: LOG_CHECKPOINT or
+ LOG_ARCHIVE */
+ ib_uint64_t limit_lsn, /*!< in: recover up to this lsn
if possible */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t min_flushed_lsn,/* in: min flushed lsn from
+ ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn from
data files */
- ib_uint64_t max_flushed_lsn)/* in: max flushed lsn from
+ ib_uint64_t max_flushed_lsn)/*!< in: max flushed lsn from
data files */
{
log_group_t* group;
@@ -2593,16 +2923,20 @@ recv_recovery_from_checkpoint_start_func(
#ifdef UNIV_LOG_ARCHIVE
ut_ad(type != LOG_CHECKPOINT || limit_lsn == IB_ULONGLONG_MAX);
+/** TRUE when recovering from a checkpoint */
# define TYPE_CHECKPOINT (type == LOG_CHECKPOINT)
+/** Recover up to this log sequence number */
# define LIMIT_LSN limit_lsn
#else /* UNIV_LOG_ARCHIVE */
+/** TRUE when recovering from a checkpoint */
# define TYPE_CHECKPOINT 1
+/** Recover up to this log sequence number */
# define LIMIT_LSN IB_ULONGLONG_MAX
#endif /* UNIV_LOG_ARCHIVE */
if (TYPE_CHECKPOINT) {
recv_sys_create();
- recv_sys_init(FALSE, buf_pool_get_curr_size());
+ recv_sys_init(buf_pool_get_curr_size());
}
if (srv_force_recovery >= SRV_FORCE_NO_LOG_REDO) {
@@ -2922,7 +3256,7 @@ recv_recovery_from_checkpoint_start_func(
#undef LIMIT_LSN
}
-/************************************************************
+/********************************************************//**
Completes recovery from a checkpoint. */
UNIV_INTERN
void
@@ -2945,6 +3279,84 @@ recv_recovery_from_checkpoint_finish(void)
}
#endif /* UNIV_DEBUG */
+ if (recv_needed_recovery && srv_recovery_stats) {
+ FILE* file = stderr;
+ ulint i;
+
+ fprintf(stderr,
+ "InnoDB: Applying log records was done. Its statistics are followings.\n");
+
+ fprintf(stderr,
+ "============================================================\n"
+ "-------------------\n"
+ "RECOVERY STATISTICS\n"
+ "-------------------\n");
+ fprintf(stderr,
+ "Recovery time: %g sec. (%lu turns)\n",
+ difftime(time(NULL), recv_sys->stats_recv_start_time),
+ recv_sys->stats_recv_turns);
+
+ fprintf(stderr,
+ "\n"
+ "Data page IO statistics\n"
+ " Requested pages: %lu\n"
+ " Read pages: %lu\n"
+ " Written pages: %lu\n"
+ " (Dirty blocks): %lu\n",
+ recv_sys->stats_read_requested_pages,
+ recv_sys->stats_read_io_pages,
+ recv_sys->stats_write_io_pages,
+ UT_LIST_GET_LEN(buf_pool->flush_list));
+
+ fprintf(stderr,
+ " Grouping IO [times]:\n"
+ "\tnumber of pages,\n"
+ "\t\tread request neighbors (in %d pages chunk),\n"
+ "\t\t\tcombined read IO,\n"
+ "\t\t\t\tcombined write IO\n",
+ RECV_READ_AHEAD_AREA);
+ for (i = 0; i < ut_max(RECV_READ_AHEAD_AREA,
+ OS_AIO_MERGE_N_CONSECUTIVE); i++) {
+ fprintf(stderr,
+ "\t%3lu,\t%lu,\t%lu,\t%lu\n", i + 1,
+ (i < RECV_READ_AHEAD_AREA) ?
+ recv_sys->stats_read_in_area[i] : 0,
+ (i < OS_AIO_MERGE_N_CONSECUTIVE) ?
+ recv_sys->stats_read_io_consecutive[i] : 0,
+ (i < OS_AIO_MERGE_N_CONSECUTIVE) ?
+ recv_sys->stats_write_io_consecutive[i] : 0);
+ }
+
+ fprintf(stderr,
+ "\n"
+ "Recovery process statistics\n"
+ " Checked pages by doublewrite buffer: %lu\n"
+ " Overwritten pages from doublewrite: %lu\n"
+ " Recovered pages by io_thread: %lu\n"
+ " Recovered pages by main thread: %lu\n"
+ " Parsed log records to apply: %lu\n"
+ " Sum of the length: %lu\n"
+ " Applied log records: %lu\n"
+ " Sum of the length: %lu\n"
+ " Pages which are already new enough: %lu (It may not be accurate, if turns > 1)\n"
+ " Oldest page's LSN: %llu\n"
+ " Newest page's LSN: %llu\n",
+ recv_sys->stats_doublewrite_check_pages,
+ recv_sys->stats_doublewrite_overwrite_pages,
+ recv_sys->stats_recover_pages_with_read,
+ recv_sys->stats_recover_pages_without_read,
+ recv_sys->stats_log_recs,
+ recv_sys->stats_log_len_sum,
+ recv_sys->stats_applied_log_recs,
+ recv_sys->stats_applied_log_len_sum,
+ recv_sys->stats_pages_already_new,
+ recv_sys->stats_oldest_modified_lsn,
+ recv_sys->stats_newest_modified_lsn);
+
+ fprintf(stderr,
+ "============================================================\n");
+ }
+
if (recv_needed_recovery) {
trx_sys_print_mysql_master_log_pos();
trx_sys_print_mysql_binlog_offset();
@@ -2971,8 +3383,13 @@ recv_recovery_from_checkpoint_finish(void)
recv_recovery_on = FALSE;
#ifndef UNIV_LOG_DEBUG
- recv_sys_free();
+ recv_sys_debug_free();
#endif
+ /* Roll back any recovered data dictionary transactions, so
+ that the data dictionary tables will be free of any locks.
+ The data dictionary latch should guarantee that there is at
+ most one data dictionary transaction active at a time. */
+ trx_rollback_or_clean_recovered(FALSE);
/* Drop partially created indexes. */
row_merge_drop_temp_indexes();
@@ -2994,21 +3411,21 @@ recv_recovery_from_checkpoint_finish(void)
}
}
-/**********************************************************
+/******************************************************//**
Resets the logs. The contents of log files will be lost! */
UNIV_INTERN
void
recv_reset_logs(
/*============*/
- ib_uint64_t lsn, /* in: reset to this lsn
+ ib_uint64_t lsn, /*!< in: reset to this lsn
rounded up to be divisible by
OS_FILE_LOG_BLOCK_SIZE, after
which we add
LOG_BLOCK_HDR_SIZE */
#ifdef UNIV_LOG_ARCHIVE
- ulint arch_log_no, /* in: next archived log file number */
+ ulint arch_log_no, /*!< in: next archived log file number */
#endif /* UNIV_LOG_ARCHIVE */
- ibool new_logs_created)/* in: TRUE if resetting logs
+ ibool new_logs_created)/*!< in: TRUE if resetting logs
is done at the log creation;
FALSE if it is done after
archive recovery */
@@ -3063,18 +3480,19 @@ recv_reset_logs(
mutex_enter(&(log_sys->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_HOTBACKUP
-/**********************************************************
+/******************************************************//**
Creates new log files after a backup has been restored. */
UNIV_INTERN
void
recv_reset_log_files_for_backup(
/*============================*/
- const char* log_dir, /* in: log file directory path */
- ulint n_log_files, /* in: number of log files */
- ulint log_file_size, /* in: log file size */
- ib_uint64_t lsn) /* in: new start lsn, must be
+ const char* log_dir, /*!< in: log file directory path */
+ ulint n_log_files, /*!< in: number of log files */
+ ulint log_file_size, /*!< in: log file size */
+ ib_uint64_t lsn) /*!< in: new start lsn, must be
divisible by OS_FILE_LOG_BLOCK_SIZE */
{
os_file_t log_file;
@@ -3157,15 +3575,14 @@ recv_reset_log_files_for_backup(
#endif /* UNIV_HOTBACKUP */
#ifdef UNIV_LOG_ARCHIVE
-/**********************************************************
-Reads from the archive of a log group and performs recovery. */
+/******************************************************//**
+Reads from the archive of a log group and performs recovery.
+@return TRUE if no more complete consistent archive files */
static
ibool
log_group_recover_from_archive_file(
/*================================*/
- /* out: TRUE if no more complete
- consistent archive files */
- log_group_t* group) /* in: log group */
+ log_group_t* group) /*!< in: log group */
{
os_file_t file_handle;
ib_uint64_t start_lsn;
@@ -3322,7 +3739,7 @@ ask_again:
read_offset % UNIV_PAGE_SIZE, len, buf, NULL);
ret = recv_scan_log_recs(
- TRUE, (buf_pool->n_frames - recv_n_pool_free_frames)
+ (buf_pool->n_frames - recv_n_pool_free_frames)
* UNIV_PAGE_SIZE, TRUE, buf, len, start_lsn,
&dummy_lsn, &scanned_lsn);
@@ -3348,18 +3765,18 @@ ask_again:
return(FALSE);
}
-/************************************************************
-Recovers from archived log files, and also from log files, if they exist. */
+/********************************************************//**
+Recovers from archived log files, and also from log files, if they exist.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
recv_recovery_from_archive_start(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- ib_uint64_t min_flushed_lsn,/* in: min flushed lsn field from the
+ ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn field from the
data files */
- ib_uint64_t limit_lsn, /* in: recover up to this lsn if
+ ib_uint64_t limit_lsn, /*!< in: recover up to this lsn if
possible */
- ulint first_log_no) /* in: number of the first archived
+ ulint first_log_no) /*!< in: number of the first archived
log file to use in the recovery; the
file will be searched from
INNOBASE_LOG_ARCH_DIR specified in
@@ -3374,7 +3791,7 @@ recv_recovery_from_archive_start(
ut_a(0);
recv_sys_create();
- recv_sys_init(FALSE, buf_pool_get_curr_size());
+ recv_sys_init(buf_pool_get_curr_size());
recv_recovery_on = TRUE;
recv_recovery_from_backup_on = TRUE;
@@ -3464,7 +3881,7 @@ recv_recovery_from_archive_start(
return(DB_SUCCESS);
}
-/************************************************************
+/********************************************************//**
Completes recovery from archive. */
UNIV_INTERN
void
diff --git a/storage/xtradb/mach/mach0data.c b/storage/xtradb/mach/mach0data.c
index 5deb475318d..e030ce9aadf 100644
--- a/storage/xtradb/mach/mach0data.c
+++ b/storage/xtradb/mach/mach0data.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file mach/mach0data.c
Utilities for converting data from the database file
to the machine format.
@@ -29,17 +30,16 @@ Created 11/28/1995 Heikki Tuuri
#include "mach0data.ic"
#endif
-/*************************************************************
-Reads a ulint in a compressed form if the log record fully contains it. */
+/*********************************************************//**
+Reads a ulint in a compressed form if the log record fully contains it.
+@return pointer to end of the stored field, NULL if not complete */
UNIV_INTERN
byte*
mach_parse_compressed(
/*==================*/
- /* out: pointer to end of the stored field, NULL if
- not complete */
- byte* ptr, /* in: pointer to buffer from where to read */
- byte* end_ptr,/* in: pointer to end of the buffer */
- ulint* val) /* out: read value (< 2^32) */
+ byte* ptr, /*!< in: pointer to buffer from where to read */
+ byte* end_ptr,/*!< in: pointer to end of the buffer */
+ ulint* val) /*!< out: read value (< 2^32) */
{
ulint flag;
@@ -93,17 +93,16 @@ mach_parse_compressed(
}
}
-/*************************************************************
-Reads a dulint in a compressed form if the log record fully contains it. */
+/*********************************************************//**
+Reads a dulint in a compressed form if the log record fully contains it.
+@return pointer to end of the stored field, NULL if not complete */
UNIV_INTERN
byte*
mach_dulint_parse_compressed(
/*=========================*/
- /* out: pointer to end of the stored field, NULL if
- not complete */
- byte* ptr, /* in: pointer to buffer from where to read */
- byte* end_ptr,/* in: pointer to end of the buffer */
- dulint* val) /* out: read value */
+ byte* ptr, /*!< in: pointer to buffer from where to read */
+ byte* end_ptr,/*!< in: pointer to end of the buffer */
+ dulint* val) /*!< out: read value */
{
ulint high;
ulint low;
diff --git a/storage/xtradb/mem/mem0dbg.c b/storage/xtradb/mem/mem0dbg.c
index a1647462922..01eda20ec45 100644
--- a/storage/xtradb/mem/mem0dbg.c
+++ b/storage/xtradb/mem/mem0dbg.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file mem/mem0dbg.c
The memory management: the debug code. This is not a compilation module,
but is included in mem0mem.* !
@@ -24,10 +25,12 @@ Created 6/9/1994 Heikki Tuuri
*************************************************************************/
#ifdef UNIV_MEM_DEBUG
+# ifndef UNIV_HOTBACKUP
/* The mutex which protects in the debug version the hash table
containing the list of live memory heaps, and also the global
variables below. */
UNIV_INTERN mutex_t mem_hash_mutex;
+# endif /* !UNIV_HOTBACKUP */
/* The following variables contain information about the
extent of memory allocations. Only used in the debug version.
@@ -38,7 +41,10 @@ static ulint mem_n_allocations = 0;
static ulint mem_total_allocated_memory = 0;
UNIV_INTERN ulint mem_current_allocated_memory = 0;
static ulint mem_max_allocated_memory = 0;
+# ifndef UNIV_HOTBACKUP
static ulint mem_last_print_info = 0;
+static ibool mem_hash_initialized = FALSE;
+# endif /* !UNIV_HOTBACKUP */
/* Size of the hash table for memory management tracking */
#define MEM_HASH_SIZE 997
@@ -48,10 +54,10 @@ static ulint mem_last_print_info = 0;
typedef struct mem_hash_node_struct mem_hash_node_t;
struct mem_hash_node_struct {
UT_LIST_NODE_T(mem_hash_node_t)
- list; /* hash list node */
- mem_heap_t* heap; /* memory heap */
+ list; /*!< hash list node */
+ mem_heap_t* heap; /*!< memory heap */
const char* file_name;/* file where heap was created*/
- ulint line; /* file line of creation */
+ ulint line; /*!< file line of creation */
ulint nth_heap;/* this is the nth heap created */
UT_LIST_NODE_T(mem_hash_node_t)
all_list;/* list of all created heaps */
@@ -65,7 +71,6 @@ static mem_hash_cell_t mem_hash_table[MEM_HASH_SIZE];
/* The base node of the list of all allocated heaps */
static mem_hash_cell_t mem_all_list_base;
-static ibool mem_hash_initialized = FALSE;
UNIV_INLINE
@@ -128,13 +133,14 @@ mem_field_trailer_get_check(byte* field)
}
#endif /* UNIV_MEM_DEBUG */
-/**********************************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
Initializes the memory system. */
UNIV_INTERN
void
mem_init(
/*=====*/
- ulint size) /* in: common pool size in bytes */
+ ulint size) /*!< in: common pool size in bytes */
{
#ifdef UNIV_MEM_DEBUG
@@ -165,15 +171,27 @@ mem_init(
mem_comm_pool = mem_pool_create(size);
}
+/******************************************************************//**
+Closes the memory system. */
+UNIV_INTERN
+void
+mem_close(void)
+/*===========*/
+{
+ mem_pool_free(mem_comm_pool);
+ mem_comm_pool = NULL;
+}
+#endif /* !UNIV_HOTBACKUP */
+
#ifdef UNIV_MEM_DEBUG
-/**********************************************************************
+/******************************************************************//**
Initializes an allocated memory field in the debug version. */
UNIV_INTERN
void
mem_field_init(
/*===========*/
- byte* buf, /* in: memory field */
- ulint n) /* in: how many bytes the user requested */
+ byte* buf, /*!< in: memory field */
+ ulint n) /*!< in: how many bytes the user requested */
{
ulint rnd;
byte* usr_buf;
@@ -213,15 +231,15 @@ mem_field_init(
mem_init_buf(usr_buf, n);
}
-/**********************************************************************
+/******************************************************************//**
Erases an allocated memory field in the debug version. */
UNIV_INTERN
void
mem_field_erase(
/*============*/
- byte* buf, /* in: memory field */
+ byte* buf, /*!< in: memory field */
ulint n __attribute__((unused)))
- /* in: how many bytes the user requested */
+ /*!< in: how many bytes the user requested */
{
byte* usr_buf;
@@ -240,15 +258,15 @@ mem_field_erase(
mem_erase_buf(buf, MEM_SPACE_NEEDED(n));
}
-/*******************************************************************
+/***************************************************************//**
Initializes a buffer to a random combination of hex BA and BE.
Used to initialize allocated memory. */
UNIV_INTERN
void
mem_init_buf(
/*=========*/
- byte* buf, /* in: pointer to buffer */
- ulint n) /* in: length of buffer */
+ byte* buf, /*!< in: pointer to buffer */
+ ulint n) /*!< in: length of buffer */
{
byte* ptr;
@@ -266,15 +284,15 @@ mem_init_buf(
UNIV_MEM_INVALID(buf, n);
}
-/*******************************************************************
+/***************************************************************//**
Initializes a buffer to a random combination of hex DE and AD.
-Used to erase freed memory.*/
+Used to erase freed memory. */
UNIV_INTERN
void
mem_erase_buf(
/*==========*/
- byte* buf, /* in: pointer to buffer */
- ulint n) /* in: length of buffer */
+ byte* buf, /*!< in: pointer to buffer */
+ ulint n) /*!< in: length of buffer */
{
byte* ptr;
@@ -291,16 +309,16 @@ mem_erase_buf(
UNIV_MEM_FREE(buf, n);
}
-/*******************************************************************
+/***************************************************************//**
Inserts a created memory heap to the hash table of current allocated
memory heaps. */
UNIV_INTERN
void
mem_hash_insert(
/*============*/
- mem_heap_t* heap, /* in: the created heap */
- const char* file_name, /* in: file name of creation */
- ulint line) /* in: line where created */
+ mem_heap_t* heap, /*!< in: the created heap */
+ const char* file_name, /*!< in: file name of creation */
+ ulint line) /*!< in: line where created */
{
mem_hash_node_t* new_node;
ulint cell_no ;
@@ -329,7 +347,7 @@ mem_hash_insert(
mutex_exit(&mem_hash_mutex);
}
-/*******************************************************************
+/***************************************************************//**
Removes a memory heap (which is going to be freed by the caller)
from the list of live memory heaps. Returns the size of the heap
in terms of how much memory in bytes was allocated for the user of
@@ -341,9 +359,9 @@ UNIV_INTERN
void
mem_hash_remove(
/*============*/
- mem_heap_t* heap, /* in: the heap to be freed */
- const char* file_name, /* in: file name of freeing */
- ulint line) /* in: line where freed */
+ mem_heap_t* heap, /*!< in: the heap to be freed */
+ const char* file_name, /*!< in: file name of freeing */
+ ulint line) /*!< in: line where freed */
{
mem_hash_node_t* node;
ulint cell_no;
@@ -410,7 +428,7 @@ mem_hash_remove(
#endif /* UNIV_MEM_DEBUG */
#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
-/*******************************************************************
+/***************************************************************//**
Checks a memory heap for consistency and prints the contents if requested.
Outputs the sum of sizes of buffers given to the user (only in
the debug version), the physical size of the heap and the number of
@@ -420,24 +438,24 @@ UNIV_INTERN
void
mem_heap_validate_or_print(
/*=======================*/
- mem_heap_t* heap, /* in: memory heap */
+ mem_heap_t* heap, /*!< in: memory heap */
byte* top __attribute__((unused)),
- /* in: calculate and validate only until
+ /*!< in: calculate and validate only until
this top pointer in the heap is reached,
if this pointer is NULL, ignored */
- ibool print, /* in: if TRUE, prints the contents
+ ibool print, /*!< in: if TRUE, prints the contents
of the heap; works only in
the debug version */
- ibool* error, /* out: TRUE if error */
- ulint* us_size,/* out: allocated memory
+ ibool* error, /*!< out: TRUE if error */
+ ulint* us_size,/*!< out: allocated memory
(for the user) in the heap,
if a NULL pointer is passed as this
argument, it is ignored; in the
non-debug version this is always -1 */
- ulint* ph_size,/* out: physical size of the heap,
+ ulint* ph_size,/*!< out: physical size of the heap,
if a NULL pointer is passed as this
argument, it is ignored */
- ulint* n_blocks) /* out: number of blocks in the heap,
+ ulint* n_blocks) /*!< out: number of blocks in the heap,
if a NULL pointer is passed as this
argument, it is ignored */
{
@@ -585,13 +603,13 @@ completed:
*error = FALSE;
}
-/******************************************************************
+/**************************************************************//**
Prints the contents of a memory heap. */
static
void
mem_heap_print(
/*===========*/
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ibool error;
ulint us_size;
@@ -610,14 +628,14 @@ mem_heap_print(
ut_a(!error);
}
-/******************************************************************
-Validates the contents of a memory heap. */
+/**************************************************************//**
+Validates the contents of a memory heap.
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_heap_validate(
/*==============*/
- /* out: TRUE if ok */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ibool error;
ulint us_size;
@@ -639,14 +657,14 @@ mem_heap_validate(
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG
-/******************************************************************
-Checks that an object is a memory heap (or a block of it). */
+/**************************************************************//**
+Checks that an object is a memory heap (or a block of it).
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_heap_check(
/*===========*/
- /* out: TRUE if ok */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
@@ -655,13 +673,13 @@ mem_heap_check(
#endif /* UNIV_DEBUG */
#ifdef UNIV_MEM_DEBUG
-/*********************************************************************
-TRUE if no memory is currently allocated. */
+/*****************************************************************//**
+TRUE if no memory is currently allocated.
+@return TRUE if no heaps exist */
UNIV_INTERN
ibool
mem_all_freed(void)
/*===============*/
- /* out: TRUE if no heaps exist */
{
mem_hash_node_t* node;
ulint heap_count = 0;
@@ -683,8 +701,9 @@ mem_all_freed(void)
mutex_exit(&mem_hash_mutex);
if (heap_count == 0) {
-
+# ifndef UNIV_HOTBACKUP
ut_a(mem_pool_get_reserved(mem_comm_pool) == 0);
+# endif /* !UNIV_HOTBACKUP */
return(TRUE);
} else {
@@ -692,13 +711,13 @@ mem_all_freed(void)
}
}
-/*********************************************************************
-Validates the dynamic memory allocation system. */
+/*****************************************************************//**
+Validates the dynamic memory allocation system.
+@return TRUE if error */
UNIV_INTERN
ibool
mem_validate_no_assert(void)
/*========================*/
- /* out: TRUE if error */
{
mem_hash_node_t* node;
ulint n_heaps = 0;
@@ -709,7 +728,9 @@ mem_validate_no_assert(void)
ulint n_blocks;
ulint i;
+# ifndef UNIV_HOTBACKUP
mem_pool_validate(mem_comm_pool);
+# endif /* !UNIV_HOTBACKUP */
mutex_enter(&mem_hash_mutex);
@@ -765,13 +786,13 @@ mem_validate_no_assert(void)
return(error);
}
-/****************************************************************
-Validates the dynamic memory */
+/************************************************************//**
+Validates the dynamic memory
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_validate(void)
/*==============*/
- /* out: TRUE if ok */
{
ut_a(!mem_validate_no_assert());
@@ -779,14 +800,14 @@ mem_validate(void)
}
#endif /* UNIV_MEM_DEBUG */
-/****************************************************************
+/************************************************************//**
Tries to find neigboring memory allocation blocks and dumps to stderr
the neighborhood of a given pointer. */
UNIV_INTERN
void
mem_analyze_corruption(
/*===================*/
- void* ptr) /* in: pointer to place of possible corruption */
+ void* ptr) /*!< in: pointer to place of possible corruption */
{
byte* p;
ulint i;
@@ -887,14 +908,15 @@ mem_analyze_corruption(
}
}
-/*********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated
memory heaps or buffers. Can only be used in the debug version. */
static
void
mem_print_info_low(
/*===============*/
- ibool print_all) /* in: if TRUE, all heaps are printed,
+ ibool print_all) /*!< in: if TRUE, all heaps are printed,
else only the heaps allocated after the
previous call of this function */
{
@@ -991,7 +1013,7 @@ next_heap:
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated memory
heaps or buffers. Can only be used in the debug version. */
UNIV_INTERN
@@ -1002,7 +1024,7 @@ mem_print_info(void)
mem_print_info_low(TRUE);
}
-/*********************************************************************
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated memory
heaps or buffers since the last ..._print_info or..._print_new_info. */
UNIV_INTERN
@@ -1012,3 +1034,4 @@ mem_print_new_info(void)
{
mem_print_info_low(FALSE);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/mem/mem0mem.c b/storage/xtradb/mem/mem0mem.c
index b7345f5846b..ccb2fd8a7b4 100644
--- a/storage/xtradb/mem/mem0mem.c
+++ b/storage/xtradb/mem/mem0mem.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file mem/mem0mem.c
The memory management
Created 6/9/1994 Heikki Tuuri
@@ -97,64 +98,43 @@ UT_LIST_BASE_NODE_T(mem_block_t) mem_block_list;
#endif
-/**************************************************************************
-Duplicates a NUL-terminated string, allocated from a memory heap. */
+/**********************************************************************//**
+Duplicates a NUL-terminated string, allocated from a memory heap.
+@return own: a copy of the string */
UNIV_INTERN
char*
mem_heap_strdup(
/*============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str) /* in: string to be copied */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* str) /*!< in: string to be copied */
{
return(mem_heap_dup(heap, str, strlen(str) + 1));
}
-/**************************************************************************
-Duplicate a block of data, allocated from a memory heap. */
+/**********************************************************************//**
+Duplicate a block of data, allocated from a memory heap.
+@return own: a copy of the data */
UNIV_INTERN
void*
mem_heap_dup(
/*=========*/
- /* out, own: a copy of the data */
- mem_heap_t* heap, /* in: memory heap where copy is allocated */
- const void* data, /* in: data to be copied */
- ulint len) /* in: length of data, in bytes */
+ mem_heap_t* heap, /*!< in: memory heap where copy is allocated */
+ const void* data, /*!< in: data to be copied */
+ ulint len) /*!< in: length of data, in bytes */
{
return(memcpy(mem_heap_alloc(heap, len), data, len));
}
-/**************************************************************************
-Concatenate two memory blocks and return the result, using a memory heap. */
-UNIV_INTERN
-void*
-mem_heap_cat(
-/*=========*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where result is allocated */
- const void* b1, /* in: block 1 */
- ulint len1, /* in: length of b1, in bytes */
- const void* b2, /* in: block 2 */
- ulint len2) /* in: length of b2, in bytes */
-{
- void* res = mem_heap_alloc(heap, len1 + len2);
-
- memcpy(res, b1, len1);
- memcpy((char*)res + len1, b2, len2);
-
- return(res);
-}
-
-/**************************************************************************
-Concatenate two strings and return the result, using a memory heap. */
+/**********************************************************************//**
+Concatenate two strings and return the result, using a memory heap.
+@return own: the result */
UNIV_INTERN
char*
mem_heap_strcat(
/*============*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* s1, /* in: string 1 */
- const char* s2) /* in: string 2 */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* s1, /*!< in: string 1 */
+ const char* s2) /*!< in: string 2 */
{
char* s;
ulint s1_len = strlen(s1);
@@ -171,18 +151,17 @@ mem_heap_strcat(
}
-/********************************************************************
-Helper function for mem_heap_printf. */
+/****************************************************************//**
+Helper function for mem_heap_printf.
+@return length of formatted string, including terminating NUL */
static
ulint
mem_heap_printf_low(
/*================*/
- /* out: length of formatted string,
- including terminating NUL */
- char* buf, /* in/out: buffer to store formatted string
+ char* buf, /*!< in/out: buffer to store formatted string
in, or NULL to just calculate length */
- const char* format, /* in: format string */
- va_list ap) /* in: arguments */
+ const char* format, /*!< in: format string */
+ va_list ap) /*!< in: arguments */
{
ulint len = 0;
@@ -281,18 +260,18 @@ mem_heap_printf_low(
return(len);
}
-/********************************************************************
+/****************************************************************//**
A simple (s)printf replacement that dynamically allocates the space for the
formatted string from the given heap. This supports a very limited set of
the printf syntax: types 's' and 'u' and length modifier 'l' (which is
-required for the 'u' type). */
+required for the 'u' type).
+@return heap-allocated formatted string */
UNIV_INTERN
char*
mem_heap_printf(
/*============*/
- /* out: heap-allocated formatted string */
- mem_heap_t* heap, /* in: memory heap */
- const char* format, /* in: format string */
+ mem_heap_t* heap, /*!< in: memory heap */
+ const char* format, /*!< in: format string */
...)
{
va_list ap;
@@ -314,24 +293,25 @@ mem_heap_printf(
return(str);
}
-/*******************************************************************
-Creates a memory heap block where data can be allocated. */
+/***************************************************************//**
+Creates a memory heap block where data can be allocated.
+@return own: memory heap block, NULL if did not succeed (only possible
+for MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INTERN
mem_block_t*
mem_heap_create_block(
/*==================*/
- /* out, own: memory heap block, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap or NULL if first block
+ mem_heap_t* heap, /*!< in: memory heap or NULL if first block
should be created */
- ulint n, /* in: number of bytes needed for user data */
- ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC or
+ ulint n, /*!< in: number of bytes needed for user data */
+ ulint type, /*!< in: type of heap: MEM_HEAP_DYNAMIC or
MEM_HEAP_BUFFER */
- const char* file_name,/* in: file name where created */
- ulint line) /* in: line where created */
+ const char* file_name,/*!< in: file name where created */
+ ulint line) /*!< in: line where created */
{
+#ifndef UNIV_HOTBACKUP
buf_block_t* buf_block = NULL;
+#endif /* !UNIV_HOTBACKUP */
mem_block_t* block;
ulint len;
@@ -345,6 +325,7 @@ mem_heap_create_block(
/* In dynamic allocation, calculate the size: block header + data. */
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
+#ifndef UNIV_HOTBACKUP
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
ut_ad(type == MEM_HEAP_DYNAMIC || n <= MEM_MAX_ALLOC_IN_BUF);
@@ -374,6 +355,13 @@ mem_heap_create_block(
ut_ad(block);
block->buf_block = buf_block;
+ block->free_block = NULL;
+#else /* !UNIV_HOTBACKUP */
+ len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
+ block = ut_malloc(len);
+ ut_ad(block);
+#endif /* !UNIV_HOTBACKUP */
+
block->magic_n = MEM_BLOCK_MAGIC_N;
ut_strlcpy_rev(block->file_name, file_name, sizeof(block->file_name));
block->line = line;
@@ -395,24 +383,21 @@ mem_heap_create_block(
mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE);
mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE);
- block->free_block = NULL;
-
ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);
return(block);
}
-/*******************************************************************
-Adds a new block to a memory heap. */
+/***************************************************************//**
+Adds a new block to a memory heap.
+@return created block, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INTERN
mem_block_t*
mem_heap_add_block(
/*===============*/
- /* out: created block, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: number of bytes user needs */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: number of bytes user needs */
{
mem_block_t* block;
mem_block_t* new_block;
@@ -458,18 +443,20 @@ mem_heap_add_block(
return(new_block);
}
-/**********************************************************************
+/******************************************************************//**
Frees a block from a memory heap. */
UNIV_INTERN
void
mem_heap_block_free(
/*================*/
- mem_heap_t* heap, /* in: heap */
- mem_block_t* block) /* in: block to free */
+ mem_heap_t* heap, /*!< in: heap */
+ mem_block_t* block) /*!< in: block to free */
{
ulint type;
ulint len;
- buf_block_t* buf_block;
+#ifndef UNIV_HOTBACKUP
+ buf_block_t* buf_block = block->buf_block;
+#endif /* !UNIV_HOTBACKUP */
if (block->magic_n != MEM_BLOCK_MAGIC_N) {
mem_analyze_corruption(block);
@@ -486,18 +473,20 @@ mem_heap_block_free(
#endif
type = heap->type;
len = block->len;
- buf_block = block->buf_block;
block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
+#ifndef UNIV_HOTBACKUP
+ if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG
- /* In the debug version we set the memory to a random combination
- of hex 0xDE and 0xAD. */
+ /* In the debug version we set the memory to a random
+ combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*)block, len);
+ mem_erase_buf((byte*)block, len);
#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */
+ }
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
ut_ad(!buf_block);
@@ -507,15 +496,27 @@ mem_heap_block_free(
buf_block_free(buf_block);
}
+#else /* !UNIV_HOTBACKUP */
+#ifdef UNIV_MEM_DEBUG
+ /* In the debug version we set the memory to a random
+ combination of hex 0xDE and 0xAD. */
+
+ mem_erase_buf((byte*)block, len);
+#else /* UNIV_MEM_DEBUG */
+ UNIV_MEM_ASSERT_AND_FREE(block, len);
+#endif /* UNIV_MEM_DEBUG */
+ ut_free(block);
+#endif /* !UNIV_HOTBACKUP */
}
-/**********************************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
Frees the free_block field from a memory heap. */
UNIV_INTERN
void
mem_heap_free_block_free(
/*=====================*/
- mem_heap_t* heap) /* in: heap */
+ mem_heap_t* heap) /*!< in: heap */
{
if (UNIV_LIKELY_NULL(heap->free_block)) {
@@ -524,9 +525,10 @@ mem_heap_free_block_free(
heap->free_block = NULL;
}
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef MEM_PERIODIC_CHECK
-/**********************************************************************
+/******************************************************************//**
Goes through the list of all allocated mem blocks, checks their magic
numbers, and reports possible corruption. */
UNIV_INTERN
diff --git a/storage/xtradb/mem/mem0pool.c b/storage/xtradb/mem/mem0pool.c
index 34de6b2a706..c4f8af607e0 100644
--- a/storage/xtradb/mem/mem0pool.c
+++ b/storage/xtradb/mem/mem0pool.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file mem/mem0pool.c
The lowest-level memory management
Created 5/12/1997 Heikki Tuuri
@@ -89,28 +90,28 @@ and for the adaptive index. Thus, for each individual transaction, its locks
can occupy at most about the size of the buffer frame of memory in the common
pool, and after that its locks will grow into the buffer pool. */
-/* Mask used to extract the free bit from area->size */
+/** Mask used to extract the free bit from area->size */
#define MEM_AREA_FREE 1
-/* The smallest memory area total size */
+/** The smallest memory area total size */
#define MEM_AREA_MIN_SIZE (2 * MEM_AREA_EXTRA_SIZE)
-/* Data structure for a memory pool. The space is allocated using the buddy
+/** Data structure for a memory pool. The space is allocated using the buddy
algorithm, where free list i contains areas of size 2 to power i. */
struct mem_pool_struct{
- byte* buf; /* memory pool */
- ulint size; /* memory common pool size */
- ulint reserved; /* amount of currently allocated
+ byte* buf; /*!< memory pool */
+ ulint size; /*!< memory common pool size */
+ ulint reserved; /*!< amount of currently allocated
memory */
- mutex_t mutex; /* mutex protecting this struct */
+ mutex_t mutex; /*!< mutex protecting this struct */
UT_LIST_BASE_NODE_T(mem_area_t)
- free_list[64]; /* lists of free memory areas: an
+ free_list[64]; /*!< lists of free memory areas: an
area is put to the list whose number
is the 2-logarithm of the area size */
};
-/* The common memory pool */
+/** The common memory pool */
UNIV_INTERN mem_pool_t* mem_comm_pool = NULL;
/* We use this counter to check that the mem pool mutex does not leak;
@@ -119,7 +120,7 @@ mysql@lists.mysql.com */
UNIV_INTERN ulint mem_n_threads_inside = 0;
-/************************************************************************
+/********************************************************************//**
Reserves the mem pool mutex. */
UNIV_INTERN
void
@@ -129,7 +130,7 @@ mem_pool_mutex_enter(void)
mutex_enter(&(mem_comm_pool->mutex));
}
-/************************************************************************
+/********************************************************************//**
Releases the mem pool mutex. */
UNIV_INTERN
void
@@ -139,39 +140,39 @@ mem_pool_mutex_exit(void)
mutex_exit(&(mem_comm_pool->mutex));
}
-/************************************************************************
-Returns memory area size. */
+/********************************************************************//**
+Returns memory area size.
+@return size */
UNIV_INLINE
ulint
mem_area_get_size(
/*==============*/
- /* out: size */
- mem_area_t* area) /* in: area */
+ mem_area_t* area) /*!< in: area */
{
return(area->size_and_free & ~MEM_AREA_FREE);
}
-/************************************************************************
+/********************************************************************//**
Sets memory area size. */
UNIV_INLINE
void
mem_area_set_size(
/*==============*/
- mem_area_t* area, /* in: area */
- ulint size) /* in: size */
+ mem_area_t* area, /*!< in: area */
+ ulint size) /*!< in: size */
{
area->size_and_free = (area->size_and_free & MEM_AREA_FREE)
| size;
}
-/************************************************************************
-Returns memory area free bit. */
+/********************************************************************//**
+Returns memory area free bit.
+@return TRUE if free */
UNIV_INLINE
ibool
mem_area_get_free(
/*==============*/
- /* out: TRUE if free */
- mem_area_t* area) /* in: area */
+ mem_area_t* area) /*!< in: area */
{
#if TRUE != MEM_AREA_FREE
# error "TRUE != MEM_AREA_FREE"
@@ -179,14 +180,14 @@ mem_area_get_free(
return(area->size_and_free & MEM_AREA_FREE);
}
-/************************************************************************
+/********************************************************************//**
Sets memory area free bit. */
UNIV_INLINE
void
mem_area_set_free(
/*==============*/
- mem_area_t* area, /* in: area */
- ibool free) /* in: free bit value */
+ mem_area_t* area, /*!< in: area */
+ ibool free) /*!< in: free bit value */
{
#if TRUE != MEM_AREA_FREE
# error "TRUE != MEM_AREA_FREE"
@@ -195,14 +196,14 @@ mem_area_set_free(
| free;
}
-/************************************************************************
-Creates a memory pool. */
+/********************************************************************//**
+Creates a memory pool.
+@return memory pool */
UNIV_INTERN
mem_pool_t*
mem_pool_create(
/*============*/
- /* out: memory pool */
- ulint size) /* in: pool size in bytes */
+ ulint size) /*!< in: pool size in bytes */
{
mem_pool_t* pool;
mem_area_t* area;
@@ -259,16 +260,27 @@ mem_pool_create(
return(pool);
}
-/************************************************************************
-Fills the specified free list. */
+/********************************************************************//**
+Frees a memory pool. */
+UNIV_INTERN
+void
+mem_pool_free(
+/*==========*/
+ mem_pool_t* pool) /*!< in, own: memory pool */
+{
+ ut_free(pool->buf);
+ ut_free(pool);
+}
+
+/********************************************************************//**
+Fills the specified free list.
+@return TRUE if we were able to insert a block to the free list */
static
ibool
mem_pool_fill_free_list(
/*====================*/
- /* out: TRUE if we were able to insert a
- block to the free list */
- ulint i, /* in: free list index */
- mem_pool_t* pool) /* in: memory pool */
+ ulint i, /*!< in: free list index */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* area;
mem_area_t* area2;
@@ -331,20 +343,20 @@ mem_pool_fill_free_list(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Allocates memory from a pool. NOTE: This low-level function should only be
-used in mem0mem.*! */
+used in mem0mem.*!
+@return own: allocated memory buffer */
UNIV_INTERN
void*
mem_area_alloc(
/*===========*/
- /* out, own: allocated memory buffer */
- ulint* psize, /* in: requested size in bytes; for optimum
+ ulint* psize, /*!< in: requested size in bytes; for optimum
space usage, the size should be a power of 2
minus MEM_AREA_EXTRA_SIZE;
out: allocated size in bytes (greater than
or equal to the requested size) */
- mem_pool_t* pool) /* in: memory pool */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* area;
ulint size;
@@ -435,16 +447,16 @@ mem_area_alloc(
return((void*)(MEM_AREA_EXTRA_SIZE + ((byte*)area)));
}
-/************************************************************************
-Gets the buddy of an area, if it exists in pool. */
+/********************************************************************//**
+Gets the buddy of an area, if it exists in pool.
+@return the buddy, NULL if no buddy in pool */
UNIV_INLINE
mem_area_t*
mem_area_get_buddy(
/*===============*/
- /* out: the buddy, NULL if no buddy in pool */
- mem_area_t* area, /* in: memory area */
- ulint size, /* in: memory area size */
- mem_pool_t* pool) /* in: memory pool */
+ mem_area_t* area, /*!< in: memory area */
+ ulint size, /*!< in: memory area size */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* buddy;
@@ -475,15 +487,15 @@ mem_area_get_buddy(
return(buddy);
}
-/************************************************************************
+/********************************************************************//**
Frees memory to a pool. */
UNIV_INTERN
void
mem_area_free(
/*==========*/
- void* ptr, /* in, own: pointer to allocated memory
+ void* ptr, /*!< in, own: pointer to allocated memory
buffer */
- mem_pool_t* pool) /* in: memory pool */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* area;
mem_area_t* buddy;
@@ -604,14 +616,14 @@ mem_area_free(
ut_ad(mem_pool_validate(pool));
}
-/************************************************************************
-Validates a memory pool. */
+/********************************************************************//**
+Validates a memory pool.
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_pool_validate(
/*==============*/
- /* out: TRUE if ok */
- mem_pool_t* pool) /* in: memory pool */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* area;
mem_area_t* buddy;
@@ -624,7 +636,8 @@ mem_pool_validate(
for (i = 0; i < 64; i++) {
- UT_LIST_VALIDATE(free_list, mem_area_t, pool->free_list[i]);
+ UT_LIST_VALIDATE(free_list, mem_area_t, pool->free_list[i],
+ (void) 0);
area = UT_LIST_GET_FIRST(pool->free_list[i]);
@@ -650,14 +663,14 @@ mem_pool_validate(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Prints info of a memory pool. */
UNIV_INTERN
void
mem_pool_print_info(
/*================*/
- FILE* outfile,/* in: output file to write to */
- mem_pool_t* pool) /* in: memory pool */
+ FILE* outfile,/*!< in: output file to write to */
+ mem_pool_t* pool) /*!< in: memory pool */
{
ulint i;
@@ -683,14 +696,14 @@ mem_pool_print_info(
mutex_exit(&(pool->mutex));
}
-/************************************************************************
-Returns the amount of reserved memory. */
+/********************************************************************//**
+Returns the amount of reserved memory.
+@return reserved memory in bytes */
UNIV_INTERN
ulint
mem_pool_get_reserved(
/*==================*/
- /* out: reserved memory in bytes */
- mem_pool_t* pool) /* in: memory pool */
+ mem_pool_t* pool) /*!< in: memory pool */
{
ulint reserved;
diff --git a/storage/xtradb/mtr/mtr0log.c b/storage/xtradb/mtr/mtr0log.c
index 0fe66d08c05..3f3dab36b76 100644
--- a/storage/xtradb/mtr/mtr0log.c
+++ b/storage/xtradb/mtr/mtr0log.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file mtr/mtr0log.c
Mini-transaction log routines
Created 12/7/1995 Heikki Tuuri
@@ -29,19 +30,22 @@ Created 12/7/1995 Heikki Tuuri
#endif
#include "buf0buf.h"
-#include "dict0boot.h"
+#include "dict0dict.h"
#include "log0recv.h"
#include "page0page.h"
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+# include "dict0boot.h"
+
+/********************************************************//**
Catenates n bytes to the mtr log. */
UNIV_INTERN
void
mlog_catenate_string(
/*=================*/
- mtr_t* mtr, /* in: mtr */
- const byte* str, /* in: string to write */
- ulint len) /* in: string length */
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* str, /*!< in: string to write */
+ ulint len) /*!< in: string length */
{
dyn_array_t* mlog;
@@ -55,7 +59,7 @@ mlog_catenate_string(
dyn_push_string(mlog, str, len);
}
-/************************************************************
+/********************************************************//**
Writes the initial part of a log record consisting of one-byte item
type and four-byte space and page numbers. Also pushes info
to the mtr memo that a buffer page has been modified. */
@@ -63,11 +67,11 @@ UNIV_INTERN
void
mlog_write_initial_log_record(
/*==========================*/
- const byte* ptr, /* in: pointer to (inside) a buffer
+ const byte* ptr, /*!< in: pointer to (inside) a buffer
frame holding the file page where
modification is made */
- byte type, /* in: log item type: MLOG_1BYTE, ... */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte type, /*!< in: log item type: MLOG_1BYTE, ... */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -86,20 +90,20 @@ mlog_write_initial_log_record(
mlog_close(mtr, log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Parses an initial log record written by mlog_write_initial_log_record. */
+/********************************************************//**
+Parses an initial log record written by mlog_write_initial_log_record.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_initial_log_record(
/*==========================*/
- /* out: parsed record end, NULL if not a complete
- record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* type, /* out: log record type: MLOG_1BYTE, ... */
- ulint* space, /* out: space id */
- ulint* page_no)/* out: page number */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* type, /*!< out: log record type: MLOG_1BYTE, ... */
+ ulint* space, /*!< out: space id */
+ ulint* page_no)/*!< out: page number */
{
if (end_ptr < ptr + 1) {
@@ -128,19 +132,18 @@ mlog_parse_initial_log_record(
return(ptr);
}
-/************************************************************
-Parses a log record written by mlog_write_ulint or mlog_write_dulint. */
+/********************************************************//**
+Parses a log record written by mlog_write_ulint or mlog_write_dulint.
+@return parsed record end, NULL if not a complete record or a corrupt record */
UNIV_INTERN
byte*
mlog_parse_nbytes(
/*==============*/
- /* out: parsed record end, NULL if not a complete
- record or a corrupt record */
- ulint type, /* in: log record type: MLOG_1BYTE, ... */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* page, /* in: page where to apply the log record, or NULL */
- void* page_zip)/* in/out: compressed page, or NULL */
+ ulint type, /*!< in: log record type: MLOG_1BYTE, ... */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* page, /*!< in: page where to apply the log record, or NULL */
+ void* page_zip)/*!< in/out: compressed page, or NULL */
{
ulint offset;
ulint val;
@@ -236,17 +239,17 @@ mlog_parse_nbytes(
return(ptr);
}
-/************************************************************
+/********************************************************//**
Writes 1 - 4 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_ulint(
/*=============*/
- byte* ptr, /* in: pointer where to write */
- ulint val, /* in: value to write */
- byte type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte* ptr, /*!< in: pointer where to write */
+ ulint val, /*!< in: value to write */
+ byte type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -282,16 +285,16 @@ mlog_write_ulint(
mlog_close(mtr, log_ptr);
}
-/************************************************************
+/********************************************************//**
Writes 8 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_dulint(
/*==============*/
- byte* ptr, /* in: pointer where to write */
- dulint val, /* in: value to write */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte* ptr, /*!< in: pointer where to write */
+ dulint val, /*!< in: value to write */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -318,17 +321,18 @@ mlog_write_dulint(
mlog_close(mtr, log_ptr);
}
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Writes a string to a file page buffered in the buffer pool. Writes the
corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_string(
/*==============*/
- byte* ptr, /* in: pointer where to write */
- const byte* str, /* in: string to write */
- ulint len, /* in: string length */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte* ptr, /*!< in: pointer where to write */
+ const byte* str, /*!< in: string to write */
+ ulint len, /*!< in: string length */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(ptr && mtr);
ut_a(len < UNIV_PAGE_SIZE);
@@ -338,16 +342,16 @@ mlog_write_string(
mlog_log_string(ptr, len, mtr);
}
-/************************************************************
+/********************************************************//**
Logs a write of a string to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_log_string(
/*============*/
- byte* ptr, /* in: pointer written to */
- ulint len, /* in: string length */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte* ptr, /*!< in: pointer written to */
+ ulint len, /*!< in: string length */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -374,19 +378,19 @@ mlog_log_string(
mlog_catenate_string(mtr, ptr, len);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Parses a log record written by mlog_write_string. */
+/********************************************************//**
+Parses a log record written by mlog_write_string.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_string(
/*==============*/
- /* out: parsed record end, NULL if not a complete
- record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* page, /* in: page where to apply the log record, or NULL */
- void* page_zip)/* in/out: compressed page, or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* page, /*!< in: page where to apply the log record, or NULL */
+ void* page_zip)/*!< in/out: compressed page, or NULL */
{
ulint offset;
ulint len;
@@ -426,20 +430,20 @@ mlog_parse_string(
return(ptr + len);
}
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Opens a buffer for mlog, writes the initial log record and,
-if needed, the field lengths of an index. */
+if needed, the field lengths of an index.
+@return buffer, NULL if log mode MTR_LOG_NONE */
UNIV_INTERN
byte*
mlog_open_and_write_index(
/*======================*/
- /* out: buffer, NULL if log mode
- MTR_LOG_NONE */
- mtr_t* mtr, /* in: mtr */
- byte* rec, /* in: index record or page */
- dict_index_t* index, /* in: record descriptor */
- byte type, /* in: log item type */
- ulint size) /* in: requested buffer size in bytes
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* rec, /*!< in: index record or page */
+ dict_index_t* index, /*!< in: record descriptor */
+ byte type, /*!< in: log item type */
+ ulint size) /*!< in: requested buffer size in bytes
(if 0, calls mlog_close() and returns NULL) */
{
byte* log_ptr;
@@ -523,20 +527,19 @@ mlog_open_and_write_index(
}
return(log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Parses a log record written by mlog_open_and_write_index. */
+/********************************************************//**
+Parses a log record written by mlog_open_and_write_index.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_index(
/*=============*/
- /* out: parsed record end,
- NULL if not a complete record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- /* out: new value of log_ptr */
- ibool comp, /* in: TRUE=compact record format */
- dict_index_t** index) /* out, own: dummy index */
+ byte* ptr, /*!< in: buffer */
+ const byte* end_ptr,/*!< in: buffer end */
+ ibool comp, /*!< in: TRUE=compact record format */
+ dict_index_t** index) /*!< out, own: dummy index */
{
ulint i, n, n_uniq;
dict_table_t* table;
diff --git a/storage/xtradb/mtr/mtr0mtr.c b/storage/xtradb/mtr/mtr0mtr.c
index 1f811a6eea3..34e6d3ffc92 100644
--- a/storage/xtradb/mtr/mtr0mtr.c
+++ b/storage/xtradb/mtr/mtr0mtr.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file mtr/mtr0mtr.c
Mini-transaction buffer
Created 11/26/1995 Heikki Tuuri
@@ -34,14 +35,16 @@ Created 11/26/1995 Heikki Tuuri
#include "log0log.h"
#include "buf0flu.h"
-/*********************************************************************
+#ifndef UNIV_HOTBACKUP
+# include "log0recv.h"
+/*****************************************************************//**
Releases the item in the slot given. */
UNIV_INLINE
void
mtr_memo_slot_release(
/*==================*/
- mtr_t* mtr, /* in: mtr */
- mtr_memo_slot_t* slot) /* in: memo slot */
+ mtr_t* mtr, /*!< in: mtr */
+ mtr_memo_slot_t* slot) /*!< in: memo slot */
{
void* object;
ulint type;
@@ -70,7 +73,7 @@ mtr_memo_slot_release(
slot->object = NULL;
}
-/**************************************************************
+/**********************************************************//**
Releases the mlocks and other objects stored in an mtr memo. They are released
in the order opposite to which they were pushed to the memo. NOTE! It is
essential that the x-rw-lock on a modified buffer page is not released before
@@ -81,7 +84,7 @@ UNIV_INLINE
void
mtr_memo_pop_all(
/*=============*/
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -135,18 +138,17 @@ mtr_memo_note_modification_all(
}
}
-/****************************************************************
+/************************************************************//**
Writes the contents of a mini-transaction log, if any, to the database log. */
static
void
mtr_log_reserve_and_write(
/*======================*/
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dyn_array_t* mlog;
dyn_block_t* block;
ulint data_size;
- ibool success;
byte* first_data;
ut_ad(mtr);
@@ -165,8 +167,8 @@ mtr_log_reserve_and_write(
if (mlog->heap == NULL) {
mtr->end_lsn = log_reserve_and_write_fast(
first_data, dyn_block_get_used(mlog),
- &(mtr->start_lsn), &success);
- if (success) {
+ &mtr->start_lsn);
+ if (mtr->end_lsn) {
return;
}
@@ -193,22 +195,28 @@ mtr_log_reserve_and_write(
mtr->end_lsn = log_close();
}
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
void
mtr_commit(
/*=======*/
- mtr_t* mtr) /* in: mini-transaction */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
+#ifndef UNIV_HOTBACKUP
ibool write_log;
+#endif /* !UNIV_HOTBACKUP */
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
ut_d(mtr->state = MTR_COMMITTING);
+#ifndef UNIV_HOTBACKUP
+ /* This is a dirty read, for debugging. */
+ ut_ad(!recv_no_log_write);
write_log = mtr->modifications && mtr->n_log_recs;
if (write_log) {
@@ -232,12 +240,15 @@ mtr_commit(
/* All unlocking has been moved here, after log_sys mutex release. */
mtr_memo_pop_all(mtr);
+#endif /* !UNIV_HOTBACKUP */
+
ut_d(mtr->state = MTR_COMMITTED);
dyn_array_free(&(mtr->memo));
dyn_array_free(&(mtr->log));
}
-/**************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Releases the latches stored in an mtr memo down to a savepoint.
NOTE! The mtr must not have made changes to buffer pages after the
savepoint, as these can be handled only by mtr_commit. */
@@ -245,8 +256,8 @@ UNIV_INTERN
void
mtr_rollback_to_savepoint(
/*======================*/
- mtr_t* mtr, /* in: mtr */
- ulint savepoint) /* in: savepoint */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint savepoint) /*!< in: savepoint */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -271,15 +282,15 @@ mtr_rollback_to_savepoint(
}
}
-/*******************************************************
+/***************************************************//**
Releases an object in the memo stack. */
UNIV_INTERN
void
mtr_memo_release(
/*=============*/
- mtr_t* mtr, /* in: mtr */
- void* object, /* in: object */
- ulint type) /* in: object type: MTR_MEMO_S_LOCK, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ void* object, /*!< in: object */
+ ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -312,18 +323,19 @@ mtr_memo_release(
}
}
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
+/********************************************************//**
+Reads 1 - 4 bytes from a file page buffered in the buffer pool.
+@return value read */
UNIV_INTERN
ulint
mtr_read_ulint(
/*===========*/
- /* out: value read */
- const byte* ptr, /* in: pointer from where to read */
- ulint type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ const byte* ptr, /*!< in: pointer from where to read */
+ ulint type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
@@ -338,16 +350,16 @@ mtr_read_ulint(
}
}
-/************************************************************
-Reads 8 bytes from a file page buffered in the buffer pool. */
+/********************************************************//**
+Reads 8 bytes from a file page buffered in the buffer pool.
+@return value read */
UNIV_INTERN
dulint
mtr_read_dulint(
/*============*/
- /* out: value read */
- const byte* ptr, /* in: pointer from where to read */
+ const byte* ptr, /*!< in: pointer from where to read */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
@@ -356,27 +368,28 @@ mtr_read_dulint(
}
#ifdef UNIV_DEBUG
-/**************************************************************
-Checks if memo contains the given page. */
+# ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Checks if memo contains the given page.
+@return TRUE if contains */
UNIV_INTERN
ibool
mtr_memo_contains_page(
/*===================*/
- /* out: TRUE if contains */
- mtr_t* mtr, /* in: mtr */
- const byte* ptr, /* in: pointer to buffer frame */
- ulint type) /* in: type of object */
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* ptr, /*!< in: pointer to buffer frame */
+ ulint type) /*!< in: type of object */
{
return(mtr_memo_contains(mtr, buf_block_align(ptr), type));
}
-/*************************************************************
+/*********************************************************//**
Prints info of an mtr handle. */
UNIV_INTERN
void
mtr_print(
/*======*/
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
fprintf(stderr,
"Mini-transaction handle: memo size %lu bytes"
@@ -384,4 +397,5 @@ mtr_print(
(ulong) dyn_array_get_data_size(&(mtr->memo)),
(ulong) dyn_array_get_data_size(&(mtr->log)));
}
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index efef608b88f..d3b3edea29f 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -15,37 +15,71 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free 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
+
+***********************************************************************/
+
+/**************************************************//**
+@file os/os0file.c
The interface to the operating system file i/o primitives
Created 10/21/1995 Heikki Tuuri
*******************************************************/
#include "os0file.h"
-#include "os0sync.h"
-#include "os0thread.h"
#include "ut0mem.h"
#include "srv0srv.h"
#include "srv0start.h"
#include "fil0fil.h"
#include "buf0buf.h"
-
-#if defined(UNIV_HOTBACKUP) && defined(__WIN__)
+#include "trx0sys.h"
+#include "trx0trx.h"
+#include "log0recv.h"
+#ifndef UNIV_HOTBACKUP
+# include "os0sync.h"
+# include "os0thread.h"
+#else /* !UNIV_HOTBACKUP */
+# ifdef __WIN__
/* Add includes for the _stat() call to compile on Windows */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#endif /* UNIV_HOTBACKUP */
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <errno.h>
+# endif /* __WIN__ */
+#endif /* !UNIV_HOTBACKUP */
/* This specifies the file permissions InnoDB uses when it creates files in
Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to
my_umask */
#ifndef __WIN__
+/** Umask for creating files */
UNIV_INTERN ulint os_innodb_umask
= S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
#else
+/** Umask for creating files */
UNIV_INTERN ulint os_innodb_umask = 0;
#endif
@@ -57,6 +91,9 @@ UNIV_INTERN ibool os_do_not_call_flush_at_each_write = FALSE;
/* We do not call os_file_flush in every os_file_write. */
#endif /* UNIV_DO_FLUSH */
+#ifdef UNIV_HOTBACKUP
+# define os_aio_use_native_aio FALSE
+#else /* UNIV_HOTBACKUP */
/* We use these mutexes to protect lseek + file i/o operation, if the
OS does not provide an atomic pread or pwrite, or similar */
#define OS_FILE_N_SEEK_MUTEXES 16
@@ -65,12 +102,13 @@ UNIV_INTERN os_mutex_t os_file_seek_mutexes[OS_FILE_N_SEEK_MUTEXES];
/* In simulated aio, merge at most this many consecutive i/os */
#define OS_AIO_MERGE_N_CONSECUTIVE 64
-/* If this flag is TRUE, then we will use the native aio of the
+/** If this flag is TRUE, then we will use the native aio of the
OS (provided we compiled Innobase with it in), otherwise we will
use simulated aio we build below with threads */
UNIV_INTERN ibool os_aio_use_native_aio = FALSE;
+/** Flag: enable debug printout for asynchronous i/o */
UNIV_INTERN ibool os_aio_print_debug = FALSE;
/* State for the state of an IO request in simulated AIO.
@@ -95,74 +133,83 @@ typedef enum {
OS_AIO_CLAIMED /* Result being returned to client. */
} os_aio_status;
-/* The aio array slot structure */
+/** The asynchronous i/o array slot structure */
typedef struct os_aio_slot_struct os_aio_slot_t;
+/** The asynchronous i/o array slot structure */
struct os_aio_slot_struct{
- ibool is_read; /* TRUE if a read operation */
- ulint pos; /* index of the slot in the aio
+ ibool is_read; /*!< TRUE if a read operation */
+ ulint pos; /*!< index of the slot in the aio
array */
- ibool reserved; /* TRUE if this slot is reserved */
+ ibool reserved; /*!< TRUE if this slot is reserved */
os_aio_status status; /* Status for current request. Valid when reserved
is TRUE. Used only in simulated aio. */
- time_t reservation_time;/* time when reserved */
- ulint len; /* length of the block to read or
+ time_t reservation_time;/*!< time when reserved */
+ ulint len; /*!< length of the block to read or
write */
- byte* buf; /* buffer used in i/o */
- ulint type; /* OS_FILE_READ or OS_FILE_WRITE */
- ulint offset; /* 32 low bits of file offset in
+ byte* buf; /*!< buffer used in i/o */
+ ulint type; /*!< OS_FILE_READ or OS_FILE_WRITE */
+ ulint offset; /*!< 32 low bits of file offset in
bytes */
- ulint offset_high; /* 32 high bits of file offset */
- os_file_t file; /* file where to read or write */
- const char* name; /* file name or path */
-// ibool io_already_done;/* used only in simulated aio:
+ ulint offset_high; /*!< 32 high bits of file offset */
+ os_file_t file; /*!< file where to read or write */
+ const char* name; /*!< file name or path */
+// ibool io_already_done;/*!< used only in simulated aio:
// TRUE if the physical i/o already
// made and only the slot message
// needs to be passed to the caller
// of os_aio_simulated_handle */
- fil_node_t* message1; /* message which is given by the */
- void* message2; /* the requester of an aio operation
+ fil_node_t* message1; /*!< message which is given by the */
+ void* message2; /*!< the requester of an aio operation
and which can be used to identify
which pending aio operation was
completed */
#ifdef WIN_ASYNC_IO
- os_event_t event; /* event object we need in the
+ os_event_t event; /*!< event object we need in the
OVERLAPPED struct */
- OVERLAPPED control; /* Windows control block for the
+ OVERLAPPED control; /*!< Windows control block for the
aio request */
#endif
};
-/* The aio array structure */
+/** The asynchronous i/o array structure */
typedef struct os_aio_array_struct os_aio_array_t;
+/** The asynchronous i/o array structure */
struct os_aio_array_struct{
- os_mutex_t mutex; /* the mutex protecting the aio array */
- os_event_t not_full; /* The event which is set to the signaled
- state when there is space in the aio
- outside the ibuf segment */
- os_event_t is_empty; /* The event which is set to the signaled
- state when there are no pending i/os
- in this array */
- ulint n_slots; /* Total number of slots in the aio array.
- This must be divisible by n_threads. */
- ulint n_segments;/* Number of segments in the aio array of
- pending aio requests. A thread can wait
- separately for any one of the segments. */
- ulint n_reserved;/* Number of reserved slots in the
- aio array outside the ibuf segment */
- os_aio_slot_t* slots; /* Pointer to the slots in the array */
+ os_mutex_t mutex; /*!< the mutex protecting the aio array */
+ os_event_t not_full;
+ /*!< The event which is set to the
+ signaled state when there is space in
+ the aio outside the ibuf segment */
+ os_event_t is_empty;
+ /*!< The event which is set to the
+ signaled state when there are no
+ pending i/os in this array */
+ ulint n_slots;/*!< Total number of slots in the aio
+ array. This must be divisible by
+ n_threads. */
+ ulint n_segments;
+ /*!< Number of segments in the aio
+ array of pending aio requests. A
+ thread can wait separately for any one
+ of the segments. */
+ ulint n_reserved;
+ /*!< Number of reserved slots in the
+ aio array outside the ibuf segment */
+ os_aio_slot_t* slots; /*!< Pointer to the slots in the array */
#ifdef __WIN__
os_native_event_t* native_events;
- /* Pointer to an array of OS native event
- handles where we copied the handles from
- slots, in the same order. This can be used
- in WaitForMultipleObjects; used only in
- Windows */
+ /*!< Pointer to an array of OS native
+ event handles where we copied the
+ handles from slots, in the same
+ order. This can be used in
+ WaitForMultipleObjects; used only in
+ Windows */
#endif
};
-/* Array of events used in simulated aio */
+/** Array of events used in simulated aio */
static os_event_t* os_aio_segment_wait_events = NULL;
/* Number for the first global segment for reading. */
@@ -172,13 +219,14 @@ const ulint os_aio_first_read_segment = 2;
2 + os_aio_read_write_threads. */
ulint os_aio_first_write_segment = 0;
-/* The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
-are NULL when the module has not yet been initialized. */
-static os_aio_array_t* os_aio_read_array = NULL;
-static os_aio_array_t* os_aio_write_array = NULL;
-static os_aio_array_t* os_aio_ibuf_array = NULL;
-static os_aio_array_t* os_aio_log_array = NULL;
-static os_aio_array_t* os_aio_sync_array = NULL;
+/** The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
+are NULL when the module has not yet been initialized. @{ */
+static os_aio_array_t* os_aio_read_array = NULL; /*!< Reads */
+static os_aio_array_t* os_aio_write_array = NULL; /*!< Writes */
+static os_aio_array_t* os_aio_ibuf_array = NULL; /*!< Insert buffer */
+static os_aio_array_t* os_aio_log_array = NULL; /*!< Redo log */
+static os_aio_array_t* os_aio_sync_array = NULL; /*!< Synchronous I/O */
+/* @} */
/* Per thread buffer used for merged IO requests. Used by
os_aio_simulated_handle so that a buffer doesn't have to be allocated
@@ -186,11 +234,13 @@ for each request. */
static char* os_aio_thread_buffer[SRV_MAX_N_IO_THREADS];
static ulint os_aio_thread_buffer_size[SRV_MAX_N_IO_THREADS];
+/** Number of asynchronous I/O segments. Set by os_aio_init(). */
static ulint os_aio_n_segments = ULINT_UNDEFINED;
-/* If the following is TRUE, read i/o handler threads try to
+/** If the following is TRUE, read i/o handler threads try to
wait until a batch of new read requests have been posted */
static volatile ibool os_aio_recommend_sleep_for_read_threads = FALSE;
+#endif /* UNIV_HOTBACKUP */
UNIV_INTERN ulint os_n_file_reads = 0;
UNIV_INTERN ulint os_bytes_read_since_printout = 0;
@@ -203,20 +253,26 @@ UNIV_INTERN time_t os_last_printout;
UNIV_INTERN ibool os_has_said_disk_full = FALSE;
-/* The mutex protecting the following counts of pending I/O operations */
+#ifndef UNIV_HOTBACKUP
+/** The mutex protecting the following counts of pending I/O operations */
static os_mutex_t os_file_count_mutex;
+#endif /* !UNIV_HOTBACKUP */
+/** Number of pending os_file_pread() operations */
UNIV_INTERN ulint os_file_n_pending_preads = 0;
+/** Number of pending os_file_pwrite() operations */
UNIV_INTERN ulint os_file_n_pending_pwrites = 0;
+/** Number of pending write operations */
UNIV_INTERN ulint os_n_pending_writes = 0;
+/** Number of pending read operations */
UNIV_INTERN ulint os_n_pending_reads = 0;
-/***************************************************************************
-Gets the operating system version. Currently works only on Windows. */
+/***********************************************************************//**
+Gets the operating system version. Currently works only on Windows.
+@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
UNIV_INTERN
ulint
os_get_os_version(void)
/*===================*/
- /* out: OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
{
#ifdef __WIN__
OSVERSIONINFO os_info;
@@ -246,18 +302,17 @@ os_get_os_version(void)
#endif
}
-/***************************************************************************
+/***********************************************************************//**
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 + 100 is returned.
+@return error number, or OS error number + 100 */
UNIV_INTERN
ulint
os_file_get_last_error(
/*===================*/
- /* out: error number, or OS error
- number + 100 */
- ibool report_all_errors) /* in: TRUE if we want an error message
+ ibool report_all_errors) /*!< in: TRUE if we want an error message
printed of all errors */
{
ulint err;
@@ -302,12 +357,25 @@ os_file_get_last_error(
" software or another instance\n"
"InnoDB: of MySQL."
" Please close it to get rid of this error.\n");
+ } else if (err == ERROR_WORKING_SET_QUOTA
+ || err == ERROR_NO_SYSTEM_RESOURCES) {
+ fprintf(stderr,
+ "InnoDB: The error means that there are no"
+ " sufficient system resources or quota to"
+ " complete the operation.\n");
+ } else if (err == ERROR_OPERATION_ABORTED) {
+ fprintf(stderr,
+ "InnoDB: The error means that the I/O"
+ " operation has been aborted\n"
+ "InnoDB: because of either a thread exit"
+ " or an application request.\n"
+ "InnoDB: Retry attempt is made.\n");
} else {
fprintf(stderr,
"InnoDB: Some operating system error numbers"
" are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
+ REFMAN
"operating-system-error-codes.html\n");
}
}
@@ -323,6 +391,11 @@ os_file_get_last_error(
} else if (err == ERROR_SHARING_VIOLATION
|| err == ERROR_LOCK_VIOLATION) {
return(OS_FILE_SHARING_VIOLATION);
+ } else if (err == ERROR_WORKING_SET_QUOTA
+ || err == ERROR_NO_SYSTEM_RESOURCES) {
+ return(OS_FILE_INSUFFICIENT_RESOURCE);
+ } else if (err == ERROR_OPERATION_ABORTED) {
+ return(OS_FILE_OPERATION_ABORTED);
} else {
return(100 + err);
}
@@ -366,7 +439,7 @@ os_file_get_last_error(
"InnoDB: Some operating system"
" error numbers are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
+ REFMAN
"operating-system-error-codes.html\n");
}
}
@@ -387,19 +460,18 @@ os_file_get_last_error(
#endif
}
-/********************************************************************
+/****************************************************************//**
Does error handling when a file operation fails.
Conditionally exits (calling exit(3)) based on should_exit value and the
-error type */
+error type
+@return TRUE if we should retry the operation */
static
ibool
os_file_handle_error_cond_exit(
/*===========================*/
- /* out: TRUE if we should retry the
- operation */
- const char* name, /* in: name of a file or NULL */
- const char* operation, /* in: operation */
- ibool should_exit) /* in: call exit(3) if unknown error
+ const char* name, /*!< in: name of a file or NULL */
+ const char* operation, /*!< in: operation */
+ ibool should_exit) /*!< in: call exit(3) if unknown error
and this parameter is TRUE */
{
ulint err;
@@ -442,6 +514,14 @@ os_file_handle_error_cond_exit(
os_thread_sleep(10000000); /* 10 sec */
return(TRUE);
+ } else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
+
+ os_thread_sleep(100000); /* 100 ms */
+ return(TRUE);
+ } else if (err == OS_FILE_OPERATION_ABORTED) {
+
+ os_thread_sleep(100000); /* 100 ms */
+ return(TRUE);
} else {
if (name) {
fprintf(stderr, "InnoDB: File name %s\n", name);
@@ -462,31 +542,29 @@ os_file_handle_error_cond_exit(
return(FALSE);
}
-/********************************************************************
-Does error handling when a file operation fails. */
+/****************************************************************//**
+Does error handling when a file operation fails.
+@return TRUE if we should retry the operation */
static
ibool
os_file_handle_error(
/*=================*/
- /* out: TRUE if we should retry the
- operation */
- const char* name, /* in: name of a file or NULL */
- const char* operation)/* in: operation */
+ const char* name, /*!< in: name of a file or NULL */
+ const char* operation)/*!< in: operation */
{
/* exit in case of unknown error */
return(os_file_handle_error_cond_exit(name, operation, TRUE));
}
-/********************************************************************
-Does error handling when a file operation fails. */
+/****************************************************************//**
+Does error handling when a file operation fails.
+@return TRUE if we should retry the operation */
static
ibool
os_file_handle_error_no_exit(
/*=========================*/
- /* out: TRUE if we should retry the
- operation */
- const char* name, /* in: name of a file or NULL */
- const char* operation)/* in: operation */
+ const char* name, /*!< in: name of a file or NULL */
+ const char* operation)/*!< in: operation */
{
/* don't exit in case of unknown error */
return(os_file_handle_error_cond_exit(name, operation, FALSE));
@@ -501,15 +579,15 @@ os_file_handle_error_no_exit(
# undef USE_FILE_LOCK
#endif
#ifdef USE_FILE_LOCK
-/********************************************************************
-Obtain an exclusive lock on a file. */
+/****************************************************************//**
+Obtain an exclusive lock on a file.
+@return 0 on success */
static
int
os_file_lock(
/*=========*/
- /* out: 0 on success */
- int fd, /* in: file descriptor */
- const char* name) /* in: file name */
+ int fd, /*!< in: file descriptor */
+ const char* name) /*!< in: file name */
{
struct flock lk;
lk.l_type = F_WRLCK;
@@ -534,7 +612,8 @@ os_file_lock(
}
#endif /* USE_FILE_LOCK */
-/********************************************************************
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Creates the seek mutexes used in positioned reads and writes. */
UNIV_INTERN
void
@@ -550,63 +629,57 @@ os_io_init_simple(void)
}
}
-/***************************************************************************
+/***********************************************************************//**
Creates a temporary file. This function is like tmpfile(3), but
the temporary file is created in the MySQL temporary directory.
On Netware, this function is like tmpfile(3), because the C run-time
-library of Netware does not expose the delete-on-close flag. */
+library of Netware does not expose the delete-on-close flag.
+@return temporary file handle, or NULL on error */
UNIV_INTERN
FILE*
os_file_create_tmpfile(void)
/*========================*/
- /* out: temporary file handle, or NULL on error */
{
-#ifdef UNIV_HOTBACKUP
- ut_error;
-
- return(NULL);
-#else
-# ifdef __NETWARE__
+#ifdef __NETWARE__
FILE* file = tmpfile();
-# else /* __NETWARE__ */
+#else /* __NETWARE__ */
FILE* file = NULL;
int fd = innobase_mysql_tmpfile();
if (fd >= 0) {
file = fdopen(fd, "w+b");
}
-# endif /* __NETWARE__ */
+#endif /* __NETWARE__ */
if (!file) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: unable to create temporary file;"
" errno: %d\n", errno);
-# ifndef __NETWARE__
+#ifndef __NETWARE__
if (fd >= 0) {
close(fd);
}
-# endif /* !__NETWARE__ */
+#endif /* !__NETWARE__ */
}
return(file);
-#endif /* UNIV_HOTBACKUP */
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
+/***********************************************************************//**
The os_file_opendir() function opens a directory stream corresponding to the
directory named by the dirname argument. The directory stream is positioned
at the first entry. In both Unix and Windows we automatically skip the '.'
-and '..' items at the start of the directory listing. */
+and '..' items at the start of the directory listing.
+@return directory stream, NULL if error */
UNIV_INTERN
os_file_dir_t
os_file_opendir(
/*============*/
- /* out: directory stream, NULL if
- error */
- const char* dirname, /* in: directory name; it must not
+ const char* dirname, /*!< in: directory name; it must not
contain a trailing '\' or '/' */
- ibool error_is_fatal) /* in: TRUE if we should treat an
+ ibool error_is_fatal) /*!< in: TRUE if we should treat an
error as a fatal error; if we try to
open symlinks then we do not wish a
fatal error if it happens not to be
@@ -653,14 +726,14 @@ os_file_opendir(
#endif
}
-/***************************************************************************
-Closes a directory stream. */
+/***********************************************************************//**
+Closes a directory stream.
+@return 0 if success, -1 if failure */
UNIV_INTERN
int
os_file_closedir(
/*=============*/
- /* out: 0 if success, -1 if failure */
- os_file_dir_t dir) /* in: directory stream */
+ os_file_dir_t dir) /*!< in: directory stream */
{
#ifdef __WIN__
BOOL ret;
@@ -687,18 +760,17 @@ os_file_closedir(
#endif
}
-/***************************************************************************
+/***********************************************************************//**
This function returns information of the next file in the directory. We jump
-over the '.' and '..' entries in the directory. */
+over the '.' and '..' entries in the directory.
+@return 0 if ok, -1 if error, 1 if at the end of the directory */
UNIV_INTERN
int
os_file_readdir_next_file(
/*======================*/
- /* out: 0 if ok, -1 if error, 1 if at the end
- of the directory */
- const char* dirname,/* in: directory name or path */
- os_file_dir_t dir, /* in: directory stream */
- os_file_stat_t* info) /* in/out: buffer where the info is returned */
+ const char* dirname,/*!< in: directory name or path */
+ os_file_dir_t dir, /*!< in: directory stream */
+ os_file_stat_t* info) /*!< in/out: buffer where the info is returned */
{
#ifdef __WIN__
LPWIN32_FIND_DATA lpFindFileData;
@@ -730,8 +802,7 @@ next_file:
/* TODO: MySQL has apparently its own symlink
implementation in Windows, dbname.sym can
redirect a database directory:
- http://dev.mysql.com/doc/refman/5.1/en/
- windows-symbolic-links.html */
+ REFMAN "windows-symbolic-links.html" */
info->type = OS_FILE_TYPE_LINK;
} else if (lpFindFileData->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY) {
@@ -814,6 +885,23 @@ next_file:
ret = stat(full_path, &statinfo);
if (ret) {
+
+ if (errno == ENOENT) {
+ /* readdir() returned a file that does not exist,
+ it must have been deleted in the meantime. Do what
+ would have happened if the file was deleted before
+ readdir() - ignore and go to the next entry.
+ If this is the last entry then info->name will still
+ contain the name of the deleted file when this
+ function returns, but this is not an issue since the
+ caller shouldn't be looking at info when end of
+ directory is returned. */
+
+ ut_free(full_path);
+
+ goto next_file;
+ }
+
os_file_handle_error_no_exit(full_path, "stat");
ut_free(full_path);
@@ -839,20 +927,19 @@ next_file:
#endif
}
-/*********************************************************************
+/*****************************************************************//**
This function attempts to create a directory named pathname. The new directory
gets default permissions. On Unix the permissions are (0770 & ~umask). If the
directory exists already, nothing is done and the call succeeds, unless the
-fail_if_exists arguments is true. */
+fail_if_exists arguments is true.
+@return TRUE if call succeeds, FALSE on error */
UNIV_INTERN
ibool
os_file_create_directory(
/*=====================*/
- /* out: TRUE if call succeeds,
- FALSE on error */
- const char* pathname, /* in: directory name as
+ const char* pathname, /*!< in: directory name as
null-terminated string */
- ibool fail_if_exists) /* in: if TRUE, pre-existing directory
+ ibool fail_if_exists) /*!< in: if TRUE, pre-existing directory
is treated as an error. */
{
#ifdef __WIN__
@@ -885,27 +972,26 @@ os_file_create_directory(
#endif
}
-/********************************************************************
-A simple function to open or create a file. */
+/****************************************************************//**
+A simple function to open or create a file.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create_simple(
/*==================*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file is
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file is
opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error), or
OS_FILE_CREATE_PATH if new file
(if exists, error) and subdirectories along
its path are created (if needed)*/
- ulint access_type,/* in: OS_FILE_READ_ONLY or
+ ulint access_type,/*!< in: OS_FILE_READ_ONLY or
OS_FILE_READ_WRITE */
- ibool* success)/* out: TRUE if succeed, FALSE if error */
+ ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
#ifdef __WIN__
os_file_t file;
@@ -951,7 +1037,7 @@ try_again:
NULL, /* default security attributes */
create_flag,
attributes,
- NULL); /* no template file */
+ NULL); /*!< no template file */
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
@@ -1027,26 +1113,25 @@ try_again:
#endif /* __WIN__ */
}
-/********************************************************************
-A simple function to open or create a file. */
+/****************************************************************//**
+A simple function to open or create a file.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create_simple_no_error_handling(
/*====================================*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file
is opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error) */
- ulint access_type,/* in: OS_FILE_READ_ONLY,
+ ulint access_type,/*!< in: OS_FILE_READ_ONLY,
OS_FILE_READ_WRITE, or
OS_FILE_READ_ALLOW_DELETE; the last option is
used by a backup program reading the file */
- ibool* success)/* out: TRUE if succeed, FALSE if error */
+ ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
#ifdef __WIN__
os_file_t file;
@@ -1073,7 +1158,7 @@ os_file_create_simple_no_error_handling(
} else if (access_type == OS_FILE_READ_ALLOW_DELETE) {
access = GENERIC_READ;
share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ
- | FILE_SHARE_WRITE; /* A backup program has to give
+ | FILE_SHARE_WRITE; /*!< A backup program has to give
mysqld the maximum freedom to
do what it likes with the
file */
@@ -1088,7 +1173,7 @@ os_file_create_simple_no_error_handling(
NULL, /* default security attributes */
create_flag,
attributes,
- NULL); /* no template file */
+ NULL); /*!< no template file */
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
@@ -1140,16 +1225,16 @@ os_file_create_simple_no_error_handling(
#endif /* __WIN__ */
}
-/********************************************************************
+/****************************************************************//**
Tries to disable OS caching on an opened file descriptor. */
UNIV_INTERN
void
os_file_set_nocache(
/*================*/
- int fd, /* in: file descriptor to alter */
- const char* file_name, /* in: file name, used in the
+ int fd, /*!< in: file descriptor to alter */
+ const char* file_name, /*!< in: file name, used in the
diagnostic message */
- const char* operation_name) /* in: "open" or "create"; used in the
+ const char* operation_name) /*!< in: "open" or "create"; used in the
diagnostic message */
{
/* some versions of Solaris may not have DIRECTIO_ON */
@@ -1183,18 +1268,17 @@ os_file_set_nocache(
#endif
}
-/********************************************************************
-Opens an existing file or creates a new. */
+/****************************************************************//**
+Opens an existing file or creates a new.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create(
/*===========*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file
is opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error),
@@ -1202,15 +1286,15 @@ os_file_create(
or an old overwritten;
OS_FILE_OPEN_RAW, if a raw device or disk
partition should be opened */
- ulint purpose,/* in: OS_FILE_AIO, if asynchronous,
+ ulint purpose,/*!< in: OS_FILE_AIO, if asynchronous,
non-buffered i/o is desired,
OS_FILE_NORMAL, if any normal file;
NOTE that it also depends on type, os_aio_..
and srv_.. variables whether we really use
async i/o or unbuffered i/o: look in the
function source code for the exact rules */
- ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */
- ibool* success)/* out: TRUE if succeed, FALSE if error */
+ ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */
+ ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
#ifdef __WIN__
os_file_t file;
@@ -1246,6 +1330,7 @@ try_again:
}
#endif
#ifdef UNIV_NON_BUFFERED_IO
+# ifndef UNIV_HOTBACKUP
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
/* Do not use unbuffered i/o to log files because
value 2 denotes that we do not flush the log at every
@@ -1254,10 +1339,14 @@ try_again:
== SRV_WIN_IO_UNBUFFERED) {
attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
-#endif
+# else /* !UNIV_HOTBACKUP */
+ attributes = attributes | FILE_FLAG_NO_BUFFERING;
+# endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_NON_BUFFERED_IO */
} else if (purpose == OS_FILE_NORMAL) {
attributes = 0;
#ifdef UNIV_NON_BUFFERED_IO
+# ifndef UNIV_HOTBACKUP
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
/* Do not use unbuffered i/o to log files because
value 2 denotes that we do not flush the log at every
@@ -1266,7 +1355,10 @@ try_again:
== SRV_WIN_IO_UNBUFFERED) {
attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
-#endif
+# else /* !UNIV_HOTBACKUP */
+ attributes = attributes | FILE_FLAG_NO_BUFFERING;
+# endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_NON_BUFFERED_IO */
} else {
attributes = 0;
ut_error;
@@ -1289,7 +1381,7 @@ try_again:
NULL, /* default security attributes */
create_flag,
attributes,
- NULL); /* no template file */
+ NULL); /*!< no template file */
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
@@ -1442,14 +1534,14 @@ try_again:
#endif /* __WIN__ */
}
-/***************************************************************************
-Deletes a file if it exists. The file has to be closed before calling this. */
+/***********************************************************************//**
+Deletes a file if it exists. The file has to be closed before calling this.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_delete_if_exists(
/*=====================*/
- /* out: TRUE if success */
- const char* name) /* in: file path as a null-terminated string */
+ const char* name) /*!< in: file path as a null-terminated string */
{
#ifdef __WIN__
BOOL ret;
@@ -1504,14 +1596,14 @@ loop:
#endif
}
-/***************************************************************************
-Deletes a file. The file has to be closed before calling this. */
+/***********************************************************************//**
+Deletes a file. The file has to be closed before calling this.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_delete(
/*===========*/
- /* out: TRUE if success */
- const char* name) /* in: file path as a null-terminated string */
+ const char* name) /*!< in: file path as a null-terminated string */
{
#ifdef __WIN__
BOOL ret;
@@ -1567,17 +1659,17 @@ loop:
#endif
}
-/***************************************************************************
+/***********************************************************************//**
Renames a file (can also move it to another directory). It is safest that the
-file is closed before calling this function. */
+file is closed before calling this function.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_rename(
/*===========*/
- /* out: TRUE if success */
- const char* oldpath,/* in: old file path as a null-terminated
+ const char* oldpath,/*!< in: old file path as a null-terminated
string */
- const char* newpath)/* in: new file path */
+ const char* newpath)/*!< in: new file path */
{
#ifdef __WIN__
BOOL ret;
@@ -1606,15 +1698,15 @@ os_file_rename(
#endif
}
-/***************************************************************************
+/***********************************************************************//**
Closes a file handle. In case of error, error number can be retrieved with
-os_file_get_last_error. */
+os_file_get_last_error.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_close(
/*==========*/
- /* out: TRUE if success */
- os_file_t file) /* in, own: handle to a file */
+ os_file_t file) /*!< in, own: handle to a file */
{
#ifdef __WIN__
BOOL ret;
@@ -1645,14 +1737,15 @@ os_file_close(
#endif
}
-/***************************************************************************
-Closes a file handle. */
+#ifdef UNIV_HOTBACKUP
+/***********************************************************************//**
+Closes a file handle.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_close_no_error_handling(
/*============================*/
- /* out: TRUE if success */
- os_file_t file) /* in, own: handle to a file */
+ os_file_t file) /*!< in, own: handle to a file */
{
#ifdef __WIN__
BOOL ret;
@@ -1679,18 +1772,19 @@ os_file_close_no_error_handling(
return(TRUE);
#endif
}
+#endif /* UNIV_HOTBACKUP */
-/***************************************************************************
-Gets a file size. */
+/***********************************************************************//**
+Gets a file size.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_get_size(
/*=============*/
- /* out: TRUE if success */
- os_file_t file, /* in: handle to a file */
- ulint* size, /* out: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ ulint* size, /*!< out: least significant 32 bits of file
size */
- ulint* size_high)/* out: most significant 32 bits of size */
+ ulint* size_high)/*!< out: most significant 32 bits of size */
{
#ifdef __WIN__
DWORD high;
@@ -1728,14 +1822,14 @@ os_file_get_size(
#endif
}
-/***************************************************************************
-Gets file size as a 64-bit integer ib_int64_t. */
+/***********************************************************************//**
+Gets file size as a 64-bit integer ib_int64_t.
+@return size in bytes, -1 if error */
UNIV_INTERN
ib_int64_t
os_file_get_size_as_iblonglong(
/*===========================*/
- /* out: size in bytes, -1 if error */
- os_file_t file) /* in: handle to a file */
+ os_file_t file) /*!< in: handle to a file */
{
ulint size;
ulint size_high;
@@ -1751,19 +1845,19 @@ os_file_get_size_as_iblonglong(
return((((ib_int64_t)size_high) << 32) + (ib_int64_t)size);
}
-/***************************************************************************
-Write the specified number of zeros to a newly created file. */
+/***********************************************************************//**
+Write the specified number of zeros to a newly created file.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_set_size(
/*=============*/
- /* out: TRUE if success */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- ulint size, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ ulint size, /*!< in: least significant 32 bits of file
size */
- ulint size_high)/* in: most significant 32 bits of size */
+ ulint size_high)/*!< in: most significant 32 bits of size */
{
ib_int64_t current_size;
ib_int64_t desired_size;
@@ -1840,14 +1934,14 @@ error_handling:
return(FALSE);
}
-/***************************************************************************
-Truncates a file at its current position. */
+/***********************************************************************//**
+Truncates a file at its current position.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_set_eof(
/*============*/
- /* out: TRUE if success */
- FILE* file) /* in: file to be truncated */
+ FILE* file) /*!< in: file to be truncated */
{
#ifdef __WIN__
HANDLE h = (HANDLE) _get_osfhandle(fileno(file));
@@ -1858,17 +1952,17 @@ os_file_set_eof(
}
#ifndef __WIN__
-/***************************************************************************
+/***********************************************************************//**
Wrapper to fsync(2) that retries the call on some errors.
Returns the value 0 if successful; otherwise the value -1 is returned and
-the global variable errno is set to indicate the error. */
+the global variable errno is set to indicate the error.
+@return 0 if success, -1 otherwise */
static
int
os_file_fsync(
/*==========*/
- /* out: 0 if success, -1 otherwise */
- os_file_t file) /* in: handle to a file */
+ os_file_t file) /*!< in: handle to a file */
{
int ret;
int failures;
@@ -1906,14 +2000,14 @@ os_file_fsync(
}
#endif /* !__WIN__ */
-/***************************************************************************
-Flushes the write buffers of a given file to the disk. */
+/***********************************************************************//**
+Flushes the write buffers of a given file to the disk.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_flush(
/*==========*/
- /* out: TRUE if success */
- os_file_t file) /* in, own: handle to a file */
+ os_file_t file) /*!< in, own: handle to a file */
{
#ifdef __WIN__
BOOL ret;
@@ -2005,23 +2099,33 @@ os_file_flush(
}
#ifndef __WIN__
-/***********************************************************************
-Does a synchronous read operation in Posix. */
+/*******************************************************************//**
+Does a synchronous read operation in Posix.
+@return number of bytes read, -1 if error */
+#define os_file_pread(file, buf, n, offset, offset_high) \
+ _os_file_pread(file, buf, n, offset, offset_high, NULL);
+
static
ssize_t
-os_file_pread(
+_os_file_pread(
/*==========*/
- /* out: number of bytes read, -1 if error */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint n, /* in: number of bytes to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint n, /*!< in: number of bytes to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset from where to read */
- ulint offset_high) /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
+ trx_t* trx)
{
off_t offs;
+#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
ssize_t n_bytes;
+#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
+ ulint sec;
+ ulint ms;
+ ib_uint64_t start_time;
+ ib_uint64_t finish_time;
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2042,6 +2146,15 @@ os_file_pread(
os_n_file_reads++;
+ if (innobase_get_slow_log() && trx && trx->take_stats)
+ {
+ trx->io_reads++;
+ trx->io_read += n;
+ ut_usectime(&sec, &ms);
+ start_time = (ib_uint64_t)sec * 1000000 + ms;
+ } else {
+ start_time = 0;
+ }
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads++;
@@ -2055,21 +2168,32 @@ os_file_pread(
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
+ if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
+ }
+
return(n_bytes);
#else
{
off_t ret_offset;
ssize_t ret;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret_offset = lseek(file, offs, SEEK_SET);
@@ -2079,30 +2203,39 @@ os_file_pread(
ret = read(file, buf, (ssize_t)n);
}
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
+ if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
+ }
+
return(ret);
}
#endif
}
-/***********************************************************************
-Does a synchronous write operation in Posix. */
+/*******************************************************************//**
+Does a synchronous write operation in Posix.
+@return number of bytes written, -1 if error */
static
ssize_t
os_file_pwrite(
/*===========*/
- /* out: number of bytes written, -1 if error */
- os_file_t file, /* in: handle to a file */
- const void* buf, /* in: buffer from where to write */
- ulint n, /* in: number of bytes to write */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ const void* buf, /*!< in: buffer from where to write */
+ ulint n, /*!< in: number of bytes to write */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to write */
- ulint offset_high) /* in: most significant 32 bits of
+ ulint offset_high) /*!< in: most significant 32 bits of
offset */
{
ssize_t ret;
@@ -2157,16 +2290,20 @@ os_file_pwrite(
#else
{
off_t ret_offset;
+# ifndef UNIV_HOTBACKUP
ulint i;
+# endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
+# ifndef UNIV_HOTBACKUP
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+# endif /* UNIV_HOTBACKUP */
ret_offset = lseek(file, offs, SEEK_SET);
@@ -2192,7 +2329,9 @@ os_file_pwrite(
# endif /* UNIV_DO_FLUSH */
func_exit:
+# ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+# endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -2204,21 +2343,21 @@ func_exit:
}
#endif
-/***********************************************************************
-Requests a synchronous positioned read operation. */
+/*******************************************************************//**
+Requests a synchronous positioned read operation.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
-os_file_read(
+_os_file_read(
/*=========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to read */
+ ulint n, /*!< in: number of bytes to read */
+ trx_t* trx)
{
#ifdef __WIN__
BOOL ret;
@@ -2227,7 +2366,9 @@ os_file_read(
DWORD low;
DWORD high;
ibool retry;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2246,16 +2387,20 @@ try_again:
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2266,7 +2411,9 @@ try_again:
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2275,14 +2422,14 @@ try_again:
if (ret && len == n) {
return(TRUE);
}
-#else
+#else /* __WIN__ */
ibool retry;
ssize_t ret;
os_bytes_read_since_printout += n;
try_again:
- ret = os_file_pread(file, buf, n, offset, offset_high);
+ ret = _os_file_pread(file, buf, n, offset, offset_high, trx);
if ((ulint)ret == n) {
@@ -2294,7 +2441,7 @@ try_again:
"InnoDB: Was only able to read %ld.\n",
(ulong)n, (ulong)offset_high,
(ulong)offset, (long)ret);
-#endif
+#endif /* __WIN__ */
#ifdef __WIN__
error_handling:
#endif
@@ -2320,22 +2467,21 @@ error_handling:
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Requests a synchronous positioned read operation. This function does not do
-any error handling. In case of error it returns FALSE. */
+any error handling. In case of error it returns FALSE.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_read_no_error_handling(
/*===========================*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to read */
+ ulint n) /*!< in: number of bytes to read */
{
#ifdef __WIN__
BOOL ret;
@@ -2344,7 +2490,9 @@ os_file_read_no_error_handling(
DWORD low;
DWORD high;
ibool retry;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2363,16 +2511,20 @@ try_again:
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2383,7 +2535,9 @@ try_again:
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2392,7 +2546,7 @@ try_again:
if (ret && len == n) {
return(TRUE);
}
-#else
+#else /* __WIN__ */
ibool retry;
ssize_t ret;
@@ -2405,7 +2559,7 @@ try_again:
return(TRUE);
}
-#endif
+#endif /* __WIN__ */
#ifdef __WIN__
error_handling:
#endif
@@ -2418,7 +2572,7 @@ error_handling:
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Rewind file to its start, read at most size - 1 bytes from it to str, and
NUL-terminate str. All errors are silently ignored. This function is
mostly meant to be used with temporary files. */
@@ -2426,9 +2580,9 @@ UNIV_INTERN
void
os_file_read_string(
/*================*/
- FILE* file, /* in: file to read from */
- char* str, /* in: buffer where to read */
- ulint size) /* in: size of buffer */
+ FILE* file, /*!< in: file to read from */
+ char* str, /*!< in: buffer where to read */
+ ulint size) /*!< in: size of buffer */
{
size_t flen;
@@ -2441,23 +2595,22 @@ os_file_read_string(
str[flen] = '\0';
}
-/***********************************************************************
-Requests a synchronous write operation. */
+/*******************************************************************//**
+Requests a synchronous write operation.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_write(
/*==========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- const void* buf, /* in: buffer from which to write */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ const void* buf, /*!< in: buffer from which to write */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to write */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to write */
+ ulint n) /*!< in: number of bytes to write */
{
#ifdef __WIN__
BOOL ret;
@@ -2465,9 +2618,11 @@ os_file_write(
DWORD ret2;
DWORD low;
DWORD high;
- ulint i;
ulint n_retries = 0;
ulint err;
+#ifndef UNIV_HOTBACKUP
+ ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFF) == offset);
@@ -2484,16 +2639,20 @@ retry:
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -2509,8 +2668,7 @@ retry:
"InnoDB: Some operating system error numbers"
" are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "operating-system-error-codes.html\n",
+ REFMAN "operating-system-error-codes.html\n",
name, (ulong) offset_high, (ulong) offset,
(ulong) GetLastError());
@@ -2528,7 +2686,9 @@ retry:
}
# endif /* UNIV_DO_FLUSH */
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -2581,8 +2741,7 @@ retry:
"InnoDB: Some operating system error numbers"
" are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "operating-system-error-codes.html\n");
+ REFMAN "operating-system-error-codes.html\n");
os_has_said_disk_full = TRUE;
}
@@ -2624,8 +2783,7 @@ retry:
"InnoDB: Some operating system error numbers"
" are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "operating-system-error-codes.html\n");
+ REFMAN "operating-system-error-codes.html\n");
os_has_said_disk_full = TRUE;
}
@@ -2634,16 +2792,16 @@ retry:
#endif
}
-/***********************************************************************
-Check the existence and type of the given file. */
+/*******************************************************************//**
+Check the existence and type of the given file.
+@return TRUE if call succeeded */
UNIV_INTERN
ibool
os_file_status(
/*===========*/
- /* out: TRUE if call succeeded */
- const char* path, /* in: pathname of the file */
- ibool* exists, /* out: TRUE if file exists */
- os_file_type_t* type) /* out: type of the file (if it exists) */
+ const char* path, /*!< in: pathname of the file */
+ ibool* exists, /*!< out: TRUE if file exists */
+ os_file_type_t* type) /*!< out: type of the file (if it exists) */
{
#ifdef __WIN__
int ret;
@@ -2706,16 +2864,15 @@ os_file_status(
#endif
}
-/***********************************************************************
-This function returns information about the specified file */
+/*******************************************************************//**
+This function returns information about the specified file
+@return TRUE if stat information found */
UNIV_INTERN
ibool
os_file_get_status(
/*===============*/
- /* out: TRUE if stat
- information found */
- const char* path, /* in: pathname of the file */
- os_file_stat_t* stat_info) /* information of a file in a
+ const char* path, /*!< in: pathname of the file */
+ os_file_stat_t* stat_info) /*!< information of a file in a
directory */
{
#ifdef __WIN__
@@ -2792,7 +2949,7 @@ os_file_get_status(
# define OS_FILE_PATH_SEPARATOR '/'
#endif
-/********************************************************************
+/****************************************************************//**
The function os_file_dirname returns a directory component of a
null-terminated pathname string. In the usual case, dirname returns
the string up to, but not including, the final '/', and basename
@@ -2818,14 +2975,13 @@ returned by dirname and basename for different paths:
"/" "/" "/"
"." "." "."
".." "." ".."
-*/
+
+@return own: directory component of the pathname */
UNIV_INTERN
char*
os_file_dirname(
/*============*/
- /* out, own: directory component of the
- pathname */
- const char* path) /* in: pathname */
+ const char* path) /*!< in: pathname */
{
/* Find the offset of the last slash */
const char* last_slash = strrchr(path, OS_FILE_PATH_SEPARATOR);
@@ -2848,15 +3004,14 @@ os_file_dirname(
return(mem_strdupl(path, last_slash - path));
}
-/********************************************************************
-Creates all missing subdirectories along the given path. */
+/****************************************************************//**
+Creates all missing subdirectories along the given path.
+@return TRUE if call succeeded FALSE otherwise */
UNIV_INTERN
ibool
os_file_create_subdirs_if_needed(
/*=============================*/
- /* out: TRUE if call succeeded
- FALSE otherwise */
- const char* path) /* in: path name */
+ const char* path) /*!< in: path name */
{
char* subdir;
ibool success, subdir_exists;
@@ -2889,31 +3044,32 @@ os_file_create_subdirs_if_needed(
return(success);
}
-/********************************************************************
-Returns a pointer to the nth slot in the aio array. */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
+Returns a pointer to the nth slot in the aio array.
+@return pointer to slot */
static
os_aio_slot_t*
os_aio_array_get_nth_slot(
/*======================*/
- /* out: pointer to slot */
- os_aio_array_t* array, /* in: aio array */
- ulint index) /* in: index of the slot */
+ os_aio_array_t* array, /*!< in: aio array */
+ ulint index) /*!< in: index of the slot */
{
ut_a(index < array->n_slots);
return((array->slots) + index);
}
-/****************************************************************************
-Creates an aio wait array. */
+/************************************************************************//**
+Creates an aio wait array.
+@return own: aio array */
static
os_aio_array_t*
os_aio_array_create(
/*================*/
- /* out, own: aio array */
- ulint n, /* in: maximum number of pending aio operations
+ ulint n, /*!< in: maximum number of pending aio operations
allowed; n must be divisible by n_segments */
- ulint n_segments) /* in: number of segments in the aio array */
+ ulint n_segments) /*!< in: number of segments in the aio array */
{
os_aio_array_t* array;
ulint i;
@@ -2958,35 +3114,55 @@ os_aio_array_create(
return(array);
}
-/****************************************************************************
-Initializes the asynchronous io system. Calls also os_io_init_simple.
-Creates a separate aio array for
-non-ibuf read and write, a third aio array for the ibuf i/o, with just one
-segment, two aio arrays for log reads and writes with one segment, and a
-synchronous aio array of the specified size. The combined number of segments
-in the three first aio arrays is the parameter n_segments given to the
-function. The caller must create an i/o handler thread for each segment in
-the four first arrays, but not for the sync aio array. */
+/************************************************************************//**
+Frees an aio wait array. */
+static
+void
+os_aio_array_free(
+/*==============*/
+ os_aio_array_t* array) /*!< in, own: array to free */
+{
+#ifdef WIN_ASYNC_IO
+ ulint i;
+
+ for (i = 0; i < array->n_slots; i++) {
+ os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i);
+ os_event_free(slot->event);
+ }
+#endif /* WIN_ASYNC_IO */
+
+#ifdef __WIN__
+ ut_free(array->native_events);
+#endif /* __WIN__ */
+ os_mutex_free(array->mutex);
+ os_event_free(array->not_full);
+ os_event_free(array->is_empty);
+
+ ut_free(array->slots);
+ ut_free(array);
+}
+
+/***********************************************************************
+Initializes the asynchronous io system. Creates one array each for ibuf
+and log i/o. Also creates one array each for read and write where each
+array is divided logically into n_read_segs and n_write_segs
+respectively. The caller must create an i/o handler thread for each
+segment in these arrays. This function also creates the sync array.
+No i/o handler thread needs to be created for that */
UNIV_INTERN
void
os_aio_init(
/*========*/
- ulint n, /* in: maximum number of pending aio operations
- allowed; n must be divisible by n_segments */
-// ulint n_segments, /* in: combined number of segments in the four
-// first aio arrays; must be >= 4 */
- ulint n_read_threads, /* n_segments == 2 + n_read_threads + n_write_threads*/
- ulint n_write_threads, /**/
- ulint n_slots_sync) /* in: number of slots in the sync aio array */
+ ulint n_per_seg, /*<! in: maximum number of pending aio
+ operations allowed per segment */
+ ulint n_read_segs, /*<! in: number of reader threads */
+ ulint n_write_segs, /*<! in: number of writer threads */
+ ulint n_slots_sync) /*<! in: number of slots in the sync aio
+ array */
{
- ulint n_read_segs;
- ulint n_write_segs;
- ulint n_per_seg;
ulint i;
+ ulint n_segments = 2 + n_read_segs + n_write_segs;
- ulint n_segments = 2 + n_read_threads + n_write_threads;
-
- ut_ad(n % n_segments == 0);
ut_ad(n_segments >= 4);
os_io_init_simple();
@@ -2997,13 +3173,10 @@ os_aio_init(
os_aio_thread_buffer_size[i] = 0;
}
- n_per_seg = n / n_segments;
- n_write_segs = n_write_threads;
- n_read_segs = n_read_threads;
/* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */
- os_aio_first_write_segment = os_aio_first_read_segment + n_read_threads;
+ os_aio_first_write_segment = os_aio_first_read_segment + n_read_segs;
os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
srv_io_thread_function[0] = "insert buffer thread";
@@ -3042,15 +3215,44 @@ os_aio_init(
}
+/***********************************************************************
+Frees the asynchronous io system. */
+UNIV_INTERN
+void
+os_aio_free(void)
+/*=============*/
+{
+ ulint i;
+
+ os_aio_array_free(os_aio_ibuf_array);
+ os_aio_ibuf_array = NULL;
+ os_aio_array_free(os_aio_log_array);
+ os_aio_log_array = NULL;
+ os_aio_array_free(os_aio_read_array);
+ os_aio_read_array = NULL;
+ os_aio_array_free(os_aio_write_array);
+ os_aio_write_array = NULL;
+ os_aio_array_free(os_aio_sync_array);
+ os_aio_sync_array = NULL;
+
+ for (i = 0; i < os_aio_n_segments; i++) {
+ os_event_free(os_aio_segment_wait_events[i]);
+ }
+
+ ut_free(os_aio_segment_wait_events);
+ os_aio_segment_wait_events = 0;
+ os_aio_n_segments = 0;
+}
+
#ifdef WIN_ASYNC_IO
-/****************************************************************************
+/************************************************************************//**
Wakes up all async i/o threads in the array in Windows async i/o at
shutdown. */
static
void
os_aio_array_wake_win_aio_at_shutdown(
/*==================================*/
- os_aio_array_t* array) /* in: aio array */
+ os_aio_array_t* array) /*!< in: aio array */
{
ulint i;
@@ -3061,7 +3263,7 @@ os_aio_array_wake_win_aio_at_shutdown(
}
#endif
-/****************************************************************************
+/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
UNIV_INTERN
@@ -3086,7 +3288,7 @@ os_aio_wake_all_threads_at_shutdown(void)
}
}
-/****************************************************************************
+/************************************************************************//**
Waits until there are no pending writes in os_aio_write_array. There can
be other, synchronous, pending writes. */
UNIV_INTERN
@@ -3097,16 +3299,16 @@ os_aio_wait_until_no_pending_writes(void)
os_event_wait(os_aio_write_array->is_empty);
}
-/**************************************************************************
-Calculates segment number for a slot. */
+/**********************************************************************//**
+Calculates segment number for a slot.
+@return segment number (which is the number used by, for example,
+i/o-handler threads) */
static
ulint
os_aio_get_segment_no_from_slot(
/*============================*/
- /* out: segment number (which is the number
- used by, for example, i/o-handler threads) */
- os_aio_array_t* array, /* in: aio wait array */
- os_aio_slot_t* slot) /* in: slot in this array */
+ os_aio_array_t* array, /*!< in: aio wait array */
+ os_aio_slot_t* slot) /*!< in: slot in this array */
{
ulint segment;
ulint seg_len;
@@ -3134,16 +3336,15 @@ os_aio_get_segment_no_from_slot(
return(segment);
}
-/**************************************************************************
-Calculates local segment number and aio array from global segment number. */
+/**********************************************************************//**
+Calculates local segment number and aio array from global segment number.
+@return local segment number within the aio array */
static
ulint
os_aio_get_array_and_local_segment(
/*===============================*/
- /* out: local segment number within
- the aio array */
- os_aio_array_t** array, /* out: aio wait array */
- ulint global_segment)/* in: global segment number */
+ os_aio_array_t** array, /*!< out: aio wait array */
+ ulint global_segment)/*!< in: global segment number */
{
ulint segment;
@@ -3170,42 +3371,48 @@ os_aio_get_array_and_local_segment(
return(segment);
}
-/***********************************************************************
+/*******************************************************************//**
Requests for a slot in the aio array. If no slot is available, waits until
-not_full-event becomes signaled. */
+not_full-event becomes signaled.
+@return pointer to slot */
static
os_aio_slot_t*
os_aio_array_reserve_slot(
/*======================*/
- /* out: pointer to slot */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE */
- os_aio_array_t* array, /* in: aio array */
- fil_node_t* message1,/* in: message to be passed along with
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE */
+ os_aio_array_t* array, /*!< in: aio array */
+ fil_node_t* message1,/*!< in: message to be passed along with
the aio operation */
- void* message2,/* in: message to be passed along with
+ void* message2,/*!< in: message to be passed along with
the aio operation */
- os_file_t file, /* in: file handle */
- const char* name, /* in: name of the file or path as a
+ os_file_t file, /*!< in: file handle */
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- void* buf, /* in: buffer where to read or from which
+ void* buf, /*!< in: buffer where to read or from which
to write */
- ulint offset, /* in: least significant 32 bits of file
+ ulint offset, /*!< in: least significant 32 bits of file
offset */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint len) /* in: length of the block to read or write */
+ ulint len, /*!< in: length of the block to read or write */
+ trx_t* trx)
{
os_aio_slot_t* slot;
#ifdef WIN_ASYNC_IO
OVERLAPPED* control;
#endif
ulint i;
- ulint prim_segment;
- ulint n;
+ ulint slots_per_seg;
+ ulint local_seg;
- n = array->n_slots / array->n_segments;
- /* 64 blocks' striping ( aligning max(BUF_READ_AHEAD_AREA) ) */
- prim_segment = ( offset >> (UNIV_PAGE_SIZE_SHIFT + 6) ) % (array->n_segments);
+ /* No need of a mutex. Only reading constant fields */
+ slots_per_seg = array->n_slots / array->n_segments;
+
+ /* We attempt to keep adjacent blocks in the same local
+ segment. This can help in merging IO requests when we are
+ doing simulated AIO */
+ local_seg = (offset >> (UNIV_PAGE_SIZE_SHIFT + 6))
+ % array->n_segments;
loop:
os_mutex_enter(array->mutex);
@@ -3225,25 +3432,26 @@ loop:
goto loop;
}
- for (i = prim_segment * n; i < array->n_slots; i++) {
+ /* First try to find a slot in the preferred local segment */
+ for (i = local_seg * slots_per_seg; i < array->n_slots; i++) {
slot = os_aio_array_get_nth_slot(array, i);
if (slot->reserved == FALSE) {
- break;
+ goto found;
}
}
- if (slot->reserved == TRUE){
- /* Not found after the intended segment. So we should search before. */
+ /* Fall back to a full scan. We are guaranteed to find a slot */
for (i = 0;; i++) {
slot = os_aio_array_get_nth_slot(array, i);
if (slot->reserved == FALSE) {
- break;
+ goto found;
}
}
- }
+found:
+ ut_a(slot->reserved == FALSE);
array->n_reserved++;
if (array->n_reserved == 1) {
@@ -3280,14 +3488,14 @@ loop:
return(slot);
}
-/***********************************************************************
+/*******************************************************************//**
Frees a slot in the aio array. */
static
void
os_aio_array_free_slot(
/*===================*/
- os_aio_array_t* array, /* in: aio array */
- os_aio_slot_t* slot) /* in: pointer to slot */
+ os_aio_array_t* array, /*!< in: aio array */
+ os_aio_slot_t* slot) /*!< in: pointer to slot */
{
ut_ad(array);
ut_ad(slot);
@@ -3315,13 +3523,13 @@ os_aio_array_free_slot(
os_mutex_exit(array->mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Wakes up a simulated aio i/o-handler thread if it has something to do. */
static
void
os_aio_simulated_wake_handler_thread(
/*=================================*/
- ulint global_segment) /* in: the number of the segment in the aio
+ ulint global_segment) /*!< in: the number of the segment in the aio
arrays */
{
os_aio_array_t* array;
@@ -3377,7 +3585,7 @@ os_aio_simulated_wake_handler_thread(
}
}
-/**************************************************************************
+/**********************************************************************//**
Wakes up simulated aio i/o-handler threads if they have something to do. */
UNIV_INTERN
void
@@ -3398,7 +3606,7 @@ os_aio_simulated_wake_handler_threads(void)
os_aio_simulated_wake_handler_thread(os_aio_first_write_segment);
}
-/**************************************************************************
+/**********************************************************************//**
This function can be called if one wants to post a batch of reads and
prefers an i/o-handler thread to handle them all at once later. You must
call os_aio_simulated_wake_handler_threads later to ensure the threads
@@ -3408,9 +3616,21 @@ void
os_aio_simulated_put_read_threads_to_sleep(void)
/*============================================*/
{
+
+/* The idea of putting background IO threads to sleep is only for
+Windows when using simulated AIO. Windows XP seems to schedule
+background threads too eagerly to allow for coalescing during
+readahead requests. */
+#ifdef __WIN__
os_aio_array_t* array;
ulint g;
+ if (os_aio_use_native_aio) {
+ /* We do not use simulated aio: do nothing */
+
+ return;
+ }
+
os_aio_recommend_sleep_for_read_threads = TRUE;
for (g = 0; g < os_aio_n_segments; g++) {
@@ -3421,18 +3641,18 @@ os_aio_simulated_put_read_threads_to_sleep(void)
os_event_reset(os_aio_segment_wait_events[g]);
}
}
+#endif /* __WIN__ */
}
-/***********************************************************************
-Requests an asynchronous i/o operation. */
+/*******************************************************************//**
+Requests an asynchronous i/o operation.
+@return TRUE if request was queued successfully, FALSE if fail */
UNIV_INTERN
ibool
os_aio(
/*===*/
- /* out: TRUE if request was queued
- successfully, FALSE if fail */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE */
- ulint mode, /* in: OS_AIO_NORMAL, ..., possibly ORed
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE */
+ ulint mode, /*!< in: OS_AIO_NORMAL, ..., possibly ORed
to OS_AIO_SIMULATED_WAKE_LATER: the
last flag advises this function not to wake
i/o-handler threads, but the caller will
@@ -3445,21 +3665,25 @@ os_aio(
because i/os are not actually handled until
all have been posted: use with great
caution! */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read or from which
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read or from which
to write */
- ulint offset, /* in: least significant 32 bits of file
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read or write */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n, /* in: number of bytes to read or write */
- fil_node_t* message1,/* in: messages for the aio handler (these
- can be used to identify a completed aio
- operation); if mode is OS_AIO_SYNC, these
- are ignored */
- void* message2)
+ ulint n, /*!< in: number of bytes to read or write */
+ fil_node_t* message1,/*!< in: message for the aio handler
+ (can be used to identify a completed
+ aio operation); ignored if mode is
+ OS_AIO_SYNC */
+ void* message2,/*!< in: message for the aio handler
+ (can be used to identify a completed
+ aio operation); ignored if mode is
+ OS_AIO_SYNC */
+ trx_t* trx)
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -3498,8 +3722,8 @@ os_aio(
wait in the Windows case. */
if (type == OS_FILE_READ) {
- return(os_file_read(file, buf, offset,
- offset_high, n));
+ return(_os_file_read(file, buf, offset,
+ offset_high, n, trx));
}
ut_a(type == OS_FILE_WRITE);
@@ -3532,8 +3756,13 @@ try_again:
ut_error;
}
+ if (trx && type == OS_FILE_READ)
+ {
+ trx->io_reads++;
+ trx->io_read += n;
+ }
slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
- name, buf, offset, offset_high, n);
+ name, buf, offset, offset_high, n, trx);
if (type == OS_FILE_READ) {
if (os_aio_use_native_aio) {
#ifdef WIN_ASYNC_IO
@@ -3615,19 +3844,19 @@ try_again:
}
#ifdef WIN_ASYNC_IO
-/**************************************************************************
+/**********************************************************************//**
This function is only used in Windows asynchronous i/o.
Waits for an aio operation to complete. This function is used to wait the
for completed requests. The aio array of pending requests is divided
into segments. The thread specifies which segment or slot it wants to wait
for. NOTE: this function will also take care of freeing the aio slot,
-therefore no other thread is allowed to do the freeing! */
+therefore no other thread is allowed to do the freeing!
+@return TRUE if the aio operation succeeded */
UNIV_INTERN
ibool
os_aio_windows_handle(
/*==================*/
- /* out: TRUE if the aio operation succeeded */
- ulint segment, /* in: the number of the segment in the aio
+ ulint segment, /*!< in: the number of the segment in the aio
arrays to wait for; segment 0 is the ibuf
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
@@ -3635,15 +3864,15 @@ os_aio_windows_handle(
this is ULINT_UNDEFINED, then it means that
sync aio is used, and this parameter is
ignored */
- ulint pos, /* this parameter is used only in sync aio:
+ ulint pos, /*!< this parameter is used only in sync aio:
wait for the aio slot at this position */
- fil_node_t**message1, /* out: the messages passed with the aio
+ fil_node_t**message1, /*!< out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
restart the operation, for example */
void** message2,
- ulint* type) /* out: OS_FILE_WRITE or ..._READ */
+ ulint* type) /*!< out: OS_FILE_WRITE or ..._READ */
{
ulint orig_seg = segment;
os_aio_array_t* array;
@@ -3653,6 +3882,7 @@ os_aio_windows_handle(
ibool ret_val;
BOOL ret;
DWORD len;
+ BOOL retry = FALSE;
if (segment == ULINT_UNDEFINED) {
array = os_aio_sync_array;
@@ -3706,40 +3936,78 @@ os_aio_windows_handle(
ut_a(TRUE == os_file_flush(slot->file));
}
#endif /* UNIV_DO_FLUSH */
+ } else if (os_file_handle_error(slot->name, "Windows aio")) {
+
+ retry = TRUE;
} else {
- os_file_handle_error(slot->name, "Windows aio");
ret_val = FALSE;
}
os_mutex_exit(array->mutex);
+ if (retry) {
+ /* retry failed read/write operation synchronously.
+ No need to hold array->mutex. */
+
+ switch (slot->type) {
+ case OS_FILE_WRITE:
+ ret = WriteFile(slot->file, slot->buf,
+ slot->len, &len,
+ &(slot->control));
+
+ break;
+ case OS_FILE_READ:
+ ret = ReadFile(slot->file, slot->buf,
+ slot->len, &len,
+ &(slot->control));
+
+ break;
+ default:
+ ut_error;
+ }
+
+ if (!ret && GetLastError() == ERROR_IO_PENDING) {
+ /* aio was queued successfully!
+ We want a synchronous i/o operation on a
+ file where we also use async i/o: in Windows
+ we must use the same wait mechanism as for
+ async i/o */
+
+ ret = GetOverlappedResult(slot->file,
+ &(slot->control),
+ &len, TRUE);
+ }
+
+ ret_val = ret && len == slot->len;
+ }
+
os_aio_array_free_slot(array, slot);
return(ret_val);
}
#endif
-/**************************************************************************
+/**********************************************************************//**
Does simulated aio. This function should be called by an i/o-handler
-thread. */
+thread.
+@return TRUE if the aio operation succeeded */
UNIV_INTERN
ibool
os_aio_simulated_handle(
/*====================*/
- /* out: TRUE if the aio operation succeeded */
- ulint global_segment, /* in: the number of the segment in the aio
+ ulint global_segment, /*!< in: the number of the segment in the aio
arrays to wait for; segment 0 is the ibuf
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
the last are the non-ibuf write threads */
- fil_node_t**message1, /* out: the messages passed with the aio
+ fil_node_t**message1, /*!< out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
restart the operation, for example */
void** message2,
- ulint* type) /* out: OS_FILE_WRITE or ..._READ */
+ ulint* type) /*!< out: OS_FILE_WRITE or ..._READ */
{
os_aio_array_t* array;
ulint segment;
@@ -3760,7 +4028,7 @@ os_aio_simulated_handle(
ibool ret;
ulint n;
ulint i;
- time_t now;
+ time_t now;
segment = os_aio_get_array_and_local_segment(&array, global_segment);
@@ -3992,6 +4260,18 @@ consecutive_loop:
}
}
+ if (srv_recovery_stats && recv_recovery_is_on() && n_consecutive) {
+ mutex_enter(&(recv_sys->mutex));
+ if (slot->type == OS_FILE_READ) {
+ recv_sys->stats_read_io_pages += n_consecutive;
+ recv_sys->stats_read_io_consecutive[n_consecutive - 1]++;
+ } else if (slot->type == OS_FILE_WRITE) {
+ recv_sys->stats_write_io_pages += n_consecutive;
+ recv_sys->stats_write_io_consecutive[n_consecutive - 1]++;
+ }
+ mutex_exit(&(recv_sys->mutex));
+ }
+
os_mutex_enter(array->mutex);
/* Mark the i/os done in slots */
@@ -4047,14 +4327,14 @@ recommended_sleep:
goto restart;
}
-/**************************************************************************
-Validates the consistency of an aio array. */
+/**********************************************************************//**
+Validates the consistency of an aio array.
+@return TRUE if ok */
static
ibool
os_aio_array_validate(
/*==================*/
- /* out: TRUE if ok */
- os_aio_array_t* array) /* in: aio wait array */
+ os_aio_array_t* array) /*!< in: aio wait array */
{
os_aio_slot_t* slot;
ulint n_reserved = 0;
@@ -4083,13 +4363,13 @@ os_aio_array_validate(
return(TRUE);
}
-/**************************************************************************
-Validates the consistency the aio system. */
+/**********************************************************************//**
+Validates the consistency the aio system.
+@return TRUE if ok */
UNIV_INTERN
ibool
os_aio_validate(void)
/*=================*/
- /* out: TRUE if ok */
{
os_aio_array_validate(os_aio_read_array);
os_aio_array_validate(os_aio_write_array);
@@ -4100,13 +4380,13 @@ os_aio_validate(void)
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of the aio arrays. */
UNIV_INTERN
void
os_aio_print(
/*=========*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -4237,7 +4517,7 @@ loop:
os_last_printout = current_time;
}
-/**************************************************************************
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -4253,14 +4533,14 @@ os_aio_refresh_stats(void)
}
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Checks that all slots in the system have been freed, that is, there are
-no pending io operations. */
+no pending io operations.
+@return TRUE if all free */
UNIV_INTERN
ibool
os_aio_all_slots_free(void)
/*=======================*/
- /* out: TRUE if all free */
{
os_aio_array_t* array;
ulint n_res = 0;
@@ -4313,3 +4593,5 @@ os_aio_all_slots_free(void)
return(FALSE);
}
#endif /* UNIV_DEBUG */
+
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/os/os0proc.c b/storage/xtradb/os/os0proc.c
index 8d4a71f8c4e..48922886f23 100644
--- a/storage/xtradb/os/os0proc.c
+++ b/storage/xtradb/os/os0proc.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file os/os0proc.c
The interface to the operating system
process control primitives
@@ -43,11 +44,12 @@ UNIV_INTERN ibool os_use_large_pages;
/* Large page size. This may be a boot-time option on some platforms */
UNIV_INTERN ulint os_large_page_size;
-/********************************************************************
+/****************************************************************//**
Converts the current process id to a number. It is not guaranteed that the
number is unique. In Linux returns the 'process number' of the current
thread. That number is the same as one sees in 'top', for example. In Linux
-the thread id is not the same as one sees in 'top'. */
+the thread id is not the same as one sees in 'top'.
+@return process id as a number */
UNIV_INTERN
ulint
os_proc_get_number(void)
@@ -60,14 +62,14 @@ os_proc_get_number(void)
#endif
}
-/********************************************************************
-Allocates large pages memory. */
+/****************************************************************//**
+Allocates large pages memory.
+@return allocated memory */
UNIV_INTERN
void*
os_mem_alloc_large(
/*===============*/
- /* out: allocated memory */
- ulint* n) /* in/out: number of bytes */
+ ulint* n) /*!< in/out: number of bytes */
{
void* ptr;
ulint size;
@@ -95,6 +97,7 @@ os_mem_alloc_large(
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
" attach shared memory segment, errno %d\n",
errno);
+ ptr = NULL;
}
/* Remove the shared memory segment so that it will be
@@ -171,15 +174,15 @@ skip:
return(ptr);
}
-/********************************************************************
+/****************************************************************//**
Frees large pages memory. */
UNIV_INTERN
void
os_mem_free_large(
/*==============*/
- void *ptr, /* in: pointer returned by
+ void *ptr, /*!< in: pointer returned by
os_mem_alloc_large() */
- ulint size) /* in: size returned by
+ ulint size) /*!< in: size returned by
os_mem_alloc_large() */
{
os_fast_mutex_lock(&ut_list_mutex);
@@ -226,37 +229,3 @@ os_mem_free_large(
}
#endif
}
-
-/********************************************************************
-Sets the priority boost for threads released from waiting within the current
-process. */
-UNIV_INTERN
-void
-os_process_set_priority_boost(
-/*==========================*/
- ibool do_boost) /* in: TRUE if priority boost should be done,
- FALSE if not */
-{
-#ifdef __WIN__
- ibool no_boost;
-
- if (do_boost) {
- no_boost = FALSE;
- } else {
- no_boost = TRUE;
- }
-
-#if TRUE != 1
-# error "TRUE != 1"
-#endif
-
- /* Does not do anything currently!
- SetProcessPriorityBoost(GetCurrentProcess(), no_boost);
- */
- fputs("Warning: process priority boost setting"
- " currently not functional!\n",
- stderr);
-#else
- UT_NOT_USED(do_boost);
-#endif
-}
diff --git a/storage/xtradb/os/os0sync.c b/storage/xtradb/os/os0sync.c
index 78ff74059f8..60467242e14 100644
--- a/storage/xtradb/os/os0sync.c
+++ b/storage/xtradb/os/os0sync.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file os/os0sync.c
The interface to the operating system
synchronization primitives.
@@ -37,9 +38,9 @@ Created 9/6/1995 Heikki Tuuri
/* Type definition for an operating system mutex struct */
struct os_mutex_struct{
- os_event_t event; /* Used by sync0arr.c for queing threads */
- void* handle; /* OS handle to mutex */
- ulint count; /* we use this counter to check
+ os_event_t event; /*!< Used by sync0arr.c for queing threads */
+ void* handle; /*!< OS handle to mutex */
+ ulint count; /*!< we use this counter to check
that the same thread does not
recursively lock the mutex: we
do not assume that the OS mutex
@@ -49,19 +50,21 @@ struct os_mutex_struct{
/* list of all 'slow' OS mutexes created */
};
-/* Mutex protecting counts and the lists of OS mutexes and events */
+/** Mutex protecting counts and the lists of OS mutexes and events */
UNIV_INTERN os_mutex_t os_sync_mutex;
+/** TRUE if os_sync_mutex has been initialized */
static ibool os_sync_mutex_inited = FALSE;
+/** TRUE when os_sync_free() is being executed */
static ibool os_sync_free_called = FALSE;
-/* This is incremented by 1 in os_thread_create and decremented by 1 in
+/** This is incremented by 1 in os_thread_create and decremented by 1 in
os_thread_exit */
UNIV_INTERN ulint os_thread_count = 0;
-/* The list of all events created */
+/** The list of all events created */
static UT_LIST_BASE_NODE_T(os_event_struct_t) os_event_list;
-/* The list of all OS 'slow' mutexes */
+/** The list of all OS 'slow' mutexes */
static UT_LIST_BASE_NODE_T(os_mutex_str_t) os_mutex_list;
UNIV_INTERN ulint os_event_count = 0;
@@ -73,7 +76,7 @@ event embedded inside a mutex, on free, this generates a recursive call.
This version of the free event function doesn't acquire the global lock */
static void os_event_free_internal(os_event_t event);
-/*************************************************************
+/*********************************************************//**
Initializes global event and OS 'slow' mutex lists. */
UNIV_INTERN
void
@@ -83,12 +86,15 @@ os_sync_init(void)
UT_LIST_INIT(os_event_list);
UT_LIST_INIT(os_mutex_list);
+ os_sync_mutex = NULL;
+ os_sync_mutex_inited = FALSE;
+
os_sync_mutex = os_mutex_create(NULL);
os_sync_mutex_inited = TRUE;
}
-/*************************************************************
+/*********************************************************//**
Frees created events and OS 'slow' mutexes. */
UNIV_INTERN
void
@@ -125,16 +131,16 @@ os_sync_free(void)
os_sync_free_called = FALSE;
}
-/*************************************************************
+/*********************************************************//**
Creates an event semaphore, i.e., a semaphore which may just have two
states: signaled and nonsignaled. The created event is manual reset: it
-must be reset explicitly by calling sync_os_reset_event. */
+must be reset explicitly by calling sync_os_reset_event.
+@return the event handle */
UNIV_INTERN
os_event_t
os_event_create(
/*============*/
- /* out: the event handle */
- const char* name) /* in: the name of the event, if NULL
+ const char* name) /*!< in: the name of the event, if NULL
the event is created without a name */
{
#ifdef __WIN__
@@ -161,12 +167,8 @@ os_event_create(
os_fast_mutex_init(&(event->os_mutex));
-#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
- ut_a(0 == pthread_cond_init(&(event->cond_var),
- pthread_condattr_default));
-#else
ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
-#endif
+
event->is_set = FALSE;
/* We return this value in os_event_reset(), which can then be
@@ -197,55 +199,14 @@ os_event_create(
return(event);
}
-#ifdef __WIN__
-/*************************************************************
-Creates an auto-reset event semaphore, i.e., an event which is automatically
-reset when a single thread is released. Works only in Windows. */
-UNIV_INTERN
-os_event_t
-os_event_create_auto(
-/*=================*/
- /* out: the event handle */
- const char* name) /* in: the name of the event, if NULL
- the event is created without a name */
-{
- os_event_t event;
-
- event = ut_malloc(sizeof(struct os_event_struct));
-
- event->handle = CreateEvent(NULL, /* No security attributes */
- FALSE, /* Auto-reset */
- FALSE, /* Initial state nonsignaled */
- (LPCTSTR) name);
-
- if (!event->handle) {
- fprintf(stderr,
- "InnoDB: Could not create a Windows auto"
- " event semaphore; Windows error %lu\n",
- (ulong) GetLastError());
- }
-
- /* Put to the list of events */
- os_mutex_enter(os_sync_mutex);
-
- UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
-
- os_event_count++;
-
- os_mutex_exit(os_sync_mutex);
-
- return(event);
-}
-#endif
-
-/**************************************************************
+/**********************************************************//**
Sets an event semaphore to the signaled state: lets waiting threads
proceed. */
UNIV_INTERN
void
os_event_set(
/*=========*/
- os_event_t event) /* in: event to set */
+ os_event_t event) /*!< in: event to set */
{
#ifdef __WIN__
ut_a(event);
@@ -267,19 +228,19 @@ os_event_set(
#endif
}
-/**************************************************************
+/**********************************************************//**
Resets an event semaphore to the nonsignaled state. Waiting threads will
stop to wait for the event.
The return value should be passed to os_even_wait_low() if it is desired
that this thread should not wait in case of an intervening call to
os_event_set() between this os_event_reset() and the
-os_event_wait_low() call. See comments for os_event_wait_low(). */
+os_event_wait_low() call. See comments for os_event_wait_low().
+@return current signal_count. */
UNIV_INTERN
ib_int64_t
os_event_reset(
/*===========*/
- /* out: current signal_count. */
- os_event_t event) /* in: event to reset */
+ os_event_t event) /*!< in: event to reset */
{
ib_int64_t ret = 0;
@@ -304,13 +265,13 @@ os_event_reset(
return(ret);
}
-/**************************************************************
+/**********************************************************//**
Frees an event object, without acquiring the global lock. */
static
void
os_event_free_internal(
/*===================*/
- os_event_t event) /* in: event to free */
+ os_event_t event) /*!< in: event to free */
{
#ifdef __WIN__
ut_a(event);
@@ -333,13 +294,13 @@ os_event_free_internal(
ut_free(event);
}
-/**************************************************************
+/**********************************************************//**
Frees an event object. */
UNIV_INTERN
void
os_event_free(
/*==========*/
- os_event_t event) /* in: event to free */
+ os_event_t event) /*!< in: event to free */
{
#ifdef __WIN__
@@ -365,7 +326,7 @@ os_event_free(
ut_free(event);
}
-/**************************************************************
+/**********************************************************//**
Waits for an event object until it is in the signaled state. If
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
waiting thread when the event becomes signaled (or immediately if the
@@ -389,8 +350,8 @@ UNIV_INTERN
void
os_event_wait_low(
/*==============*/
- os_event_t event, /* in: event to wait */
- ib_int64_t reset_sig_count)/* in: zero or the value
+ os_event_t event, /*!< in: event to wait */
+ ib_int64_t reset_sig_count)/*!< in: zero or the value
returned by previous call of
os_event_reset(). */
{
@@ -444,17 +405,16 @@ os_event_wait_low(
#endif
}
-/**************************************************************
+/**********************************************************//**
Waits for an event object until it is in the signaled state or
-a timeout is exceeded. In Unix the timeout is always infinite. */
+a timeout is exceeded. In Unix the timeout is always infinite.
+@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
os_event_wait_time(
/*===============*/
- /* out: 0 if success, OS_SYNC_TIME_EXCEEDED if
- timeout was exceeded */
- os_event_t event, /* in: event to wait */
- ulint time) /* in: timeout in microseconds, or
+ os_event_t event, /*!< in: event to wait */
+ ulint time) /*!< in: timeout in microseconds, or
OS_SYNC_INFINITE_TIME */
{
#ifdef __WIN__
@@ -490,19 +450,18 @@ os_event_wait_time(
}
#ifdef __WIN__
-/**************************************************************
+/**********************************************************//**
Waits for any event in an OS native event array. Returns if even a single
-one is signaled or becomes signaled. */
+one is signaled or becomes signaled.
+@return index of the event which was signaled */
UNIV_INTERN
ulint
os_event_wait_multiple(
/*===================*/
- /* out: index of the event
- which was signaled */
- ulint n, /* in: number of events in the
+ ulint n, /*!< in: number of events in the
array */
os_native_event_t* native_event_array)
- /* in: pointer to an array of event
+ /*!< in: pointer to an array of event
handles */
{
DWORD index;
@@ -514,7 +473,7 @@ os_event_wait_multiple(
FALSE, /* Wait for any 1 event */
INFINITE); /* Infinite wait time
limit */
- ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparision */
+ ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */
ut_a(index < WAIT_OBJECT_0 + n);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
@@ -525,15 +484,15 @@ os_event_wait_multiple(
}
#endif
-/*************************************************************
+/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
-mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
+mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
+@return the mutex handle */
UNIV_INTERN
os_mutex_t
os_mutex_create(
/*============*/
- /* out: the mutex handle */
- const char* name) /* in: the name of the mutex, if NULL
+ const char* name) /*!< in: the name of the mutex, if NULL
the mutex is created without a name */
{
#ifdef __WIN__
@@ -576,13 +535,13 @@ os_mutex_create(
return(mutex_str);
}
-/**************************************************************
+/**********************************************************//**
Acquires ownership of a mutex semaphore. */
UNIV_INTERN
void
os_mutex_enter(
/*===========*/
- os_mutex_t mutex) /* in: mutex to acquire */
+ os_mutex_t mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
DWORD err;
@@ -605,13 +564,13 @@ os_mutex_enter(
#endif
}
-/**************************************************************
+/**********************************************************//**
Releases ownership of a mutex. */
UNIV_INTERN
void
os_mutex_exit(
/*==========*/
- os_mutex_t mutex) /* in: mutex to release */
+ os_mutex_t mutex) /*!< in: mutex to release */
{
ut_a(mutex);
@@ -625,13 +584,13 @@ os_mutex_exit(
#endif
}
-/**************************************************************
+/**********************************************************//**
Frees a mutex object. */
UNIV_INTERN
void
os_mutex_free(
/*==========*/
- os_mutex_t mutex) /* in: mutex to free */
+ os_mutex_t mutex) /*!< in: mutex to free */
{
ut_a(mutex);
@@ -662,25 +621,21 @@ os_mutex_free(
#endif
}
-/*************************************************************
+/*********************************************************//**
Initializes an operating system fast mutex semaphore. */
UNIV_INTERN
void
os_fast_mutex_init(
/*===============*/
- os_fast_mutex_t* fast_mutex) /* in: fast mutex */
+ os_fast_mutex_t* fast_mutex) /*!< in: fast mutex */
{
#ifdef __WIN__
ut_a(fast_mutex);
InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
#else
-#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
- ut_a(0 == pthread_mutex_init(fast_mutex, pthread_mutexattr_default));
-#else
ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST));
#endif
-#endif
if (UNIV_LIKELY(os_sync_mutex_inited)) {
/* When creating os_sync_mutex itself (in Unix) we cannot
reserve it */
@@ -695,13 +650,13 @@ os_fast_mutex_init(
}
}
-/**************************************************************
+/**********************************************************//**
Acquires ownership of a fast mutex. */
UNIV_INTERN
void
os_fast_mutex_lock(
/*===============*/
- os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */
+ os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
EnterCriticalSection((LPCRITICAL_SECTION) fast_mutex);
@@ -710,13 +665,13 @@ os_fast_mutex_lock(
#endif
}
-/**************************************************************
+/**********************************************************//**
Releases ownership of a fast mutex. */
UNIV_INTERN
void
os_fast_mutex_unlock(
/*=================*/
- os_fast_mutex_t* fast_mutex) /* in: mutex to release */
+ os_fast_mutex_t* fast_mutex) /*!< in: mutex to release */
{
#ifdef __WIN__
LeaveCriticalSection(fast_mutex);
@@ -725,13 +680,13 @@ os_fast_mutex_unlock(
#endif
}
-/**************************************************************
+/**********************************************************//**
Frees a mutex object. */
UNIV_INTERN
void
os_fast_mutex_free(
/*===============*/
- os_fast_mutex_t* fast_mutex) /* in: mutex to free */
+ os_fast_mutex_t* fast_mutex) /*!< in: mutex to free */
{
#ifdef __WIN__
ut_a(fast_mutex);
@@ -761,6 +716,7 @@ os_fast_mutex_free(
os_mutex_enter(os_sync_mutex);
}
+ ut_ad(os_fast_mutex_count > 0);
os_fast_mutex_count--;
if (UNIV_LIKELY(os_sync_mutex_inited)) {
diff --git a/storage/xtradb/os/os0thread.c b/storage/xtradb/os/os0thread.c
index 7d0a57ae17c..34818ada804 100644
--- a/storage/xtradb/os/os0thread.c
+++ b/storage/xtradb/os/os0thread.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file os/os0thread.c
The interface to the operating system thread control primitives
Created 9/8/1995 Heikki Tuuri
@@ -31,18 +32,19 @@ Created 9/8/1995 Heikki Tuuri
#include <windows.h>
#endif
+#ifndef UNIV_HOTBACKUP
#include "srv0srv.h"
#include "os0sync.h"
-/*******************************************************************
-Compares two thread ids for equality. */
+/***************************************************************//**
+Compares two thread ids for equality.
+@return TRUE if equal */
UNIV_INTERN
ibool
os_thread_eq(
/*=========*/
- /* out: TRUE if equal */
- os_thread_id_t a, /* in: OS thread or thread id */
- os_thread_id_t b) /* in: OS thread or thread id */
+ os_thread_id_t a, /*!< in: OS thread or thread id */
+ os_thread_id_t b) /*!< in: OS thread or thread id */
{
#ifdef __WIN__
if (a == b) {
@@ -59,14 +61,15 @@ os_thread_eq(
#endif
}
-/********************************************************************
+/****************************************************************//**
Converts an OS thread id to a ulint. It is NOT guaranteed that the ulint is
-unique for the thread though! */
+unique for the thread though!
+@return thread identifier as a number */
UNIV_INTERN
ulint
os_thread_pf(
/*=========*/
- os_thread_id_t a)
+ os_thread_id_t a) /*!< in: OS thread identifier */
{
#ifdef UNIV_HPUX10
/* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2,
@@ -78,10 +81,11 @@ os_thread_pf(
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Returns the thread identifier of current thread. Currently the thread
identifier in Unix is the thread handle itself. Note that in HP-UX
-pthread_t is a struct of 3 fields. */
+pthread_t is a struct of 3 fields.
+@return current thread identifier */
UNIV_INTERN
os_thread_id_t
os_thread_get_curr_id(void)
@@ -94,24 +98,24 @@ os_thread_get_curr_id(void)
#endif
}
-/********************************************************************
+/****************************************************************//**
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
-and returns an ulint. */
+and returns an ulint.
+@return handle to the thread */
UNIV_INTERN
os_thread_t
os_thread_create(
/*=============*/
- /* out: handle to the thread */
#ifndef __WIN__
os_posix_f_t start_f,
#else
- ulint (*start_f)(void*), /* in: pointer to function
+ ulint (*start_f)(void*), /*!< in: pointer to function
from which to start */
#endif
- void* arg, /* in: argument to start
+ void* arg, /*!< in: argument to start
function */
- os_thread_id_t* thread_id) /* out: id of the created
+ os_thread_id_t* thread_id) /*!< out: id of the created
thread, or NULL */
{
#ifdef __WIN__
@@ -148,7 +152,7 @@ os_thread_create(
os_thread_t pthread;
pthread_attr_t attr;
-#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10))
+#ifndef UNIV_HPUX10
pthread_attr_init(&attr);
#endif
@@ -182,7 +186,7 @@ os_thread_create(
os_thread_count++;
os_mutex_exit(os_sync_mutex);
-#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
+#ifdef UNIV_HPUX10
ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
#else
ret = pthread_create(&pthread, &attr, start_f, arg);
@@ -193,7 +197,7 @@ os_thread_create(
exit(1);
}
-#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10))
+#ifndef UNIV_HPUX10
pthread_attr_destroy(&attr);
#endif
if (srv_set_thread_priorities) {
@@ -209,13 +213,13 @@ os_thread_create(
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Exits the current thread. */
UNIV_INTERN
void
os_thread_exit(
/*===========*/
- void* exit_value) /* in: exit value; in Windows this void*
+ void* exit_value) /*!< in: exit value; in Windows this void*
is cast as a DWORD */
{
#ifdef UNIV_DEBUG_THREAD_CREATION
@@ -229,12 +233,14 @@ os_thread_exit(
#ifdef __WIN__
ExitThread((DWORD)exit_value);
#else
+ pthread_detach(pthread_self());
pthread_exit(exit_value);
#endif
}
-/*********************************************************************
-Returns handle to the current thread. */
+/*****************************************************************//**
+Returns handle to the current thread.
+@return current thread handle */
UNIV_INTERN
os_thread_t
os_thread_get_curr(void)
@@ -247,7 +253,7 @@ os_thread_get_curr(void)
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Advises the os to give up remainder of the thread's time slice. */
UNIV_INTERN
void
@@ -266,14 +272,15 @@ os_thread_yield(void)
os_thread_sleep(0);
#endif
}
+#endif /* !UNIV_HOTBACKUP */
-/*********************************************************************
+/*****************************************************************//**
The thread sleeps at least the time given in microseconds. */
UNIV_INTERN
void
os_thread_sleep(
/*============*/
- ulint tm) /* in: time in microseconds */
+ ulint tm) /*!< in: time in microseconds */
{
#ifdef __WIN__
Sleep((DWORD) tm / 1000);
@@ -289,14 +296,15 @@ os_thread_sleep(
#endif
}
-/**********************************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
Sets a thread priority. */
UNIV_INTERN
void
os_thread_set_priority(
/*===================*/
- os_thread_t handle, /* in: OS handle to the thread */
- ulint pri) /* in: priority */
+ os_thread_t handle, /*!< in: OS handle to the thread */
+ ulint pri) /*!< in: priority */
{
#ifdef __WIN__
int os_pri;
@@ -318,15 +326,15 @@ os_thread_set_priority(
#endif
}
-/**********************************************************************
-Gets a thread priority. */
+/******************************************************************//**
+Gets a thread priority.
+@return priority */
UNIV_INTERN
ulint
os_thread_get_priority(
/*===================*/
- /* out: priority */
os_thread_t handle __attribute__((unused)))
- /* in: OS handle to the thread */
+ /*!< in: OS handle to the thread */
{
#ifdef __WIN__
int os_pri;
@@ -350,8 +358,9 @@ os_thread_get_priority(
#endif
}
-/**********************************************************************
-Gets the last operating system error code for the calling thread. */
+/******************************************************************//**
+Gets the last operating system error code for the calling thread.
+@return last error on Windows, 0 otherwise */
UNIV_INTERN
ulint
os_thread_get_last_error(void)
@@ -363,3 +372,4 @@ os_thread_get_last_error(void)
return(0);
#endif
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/page/page0cur.c b/storage/xtradb/page/page0cur.c
index e810756c1e4..f10f16a7dd9 100644
--- a/storage/xtradb/page/page0cur.c
+++ b/storage/xtradb/page/page0cur.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file page/page0cur.c
The page cursor
Created 10/4/1994 Heikki Tuuri
@@ -30,40 +31,74 @@ Created 10/4/1994 Heikki Tuuri
#include "page0zip.h"
#include "mtr0log.h"
#include "log0recv.h"
+#include "ut0ut.h"
+#ifndef UNIV_HOTBACKUP
#include "rem0cmp.h"
-static ulint page_rnd = 976722341;
-
#ifdef PAGE_CUR_ADAPT
# ifdef UNIV_SEARCH_PERF_STAT
static ulint page_cur_short_succ = 0;
# endif /* UNIV_SEARCH_PERF_STAT */
-/********************************************************************
-Tries a search shortcut based on the last insert. */
+/*******************************************************************//**
+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] = ut_time_us(NULL)
+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 ib_uint64_t lcg_current = 0;
+ static ibool initialized = FALSE;
+
+ if (!initialized) {
+ lcg_current = (ib_uint64_t) ut_time_us(NULL);
+ initialized = TRUE;
+ }
+
+ /* 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);
+}
+
+/****************************************************************//**
+Tries a search shortcut based on the last insert.
+@return TRUE on success */
UNIV_INLINE
ibool
page_cur_try_search_shortcut(
/*=========================*/
- /* out: TRUE on success */
- const buf_block_t* block, /* in: index page */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
+ const buf_block_t* block, /*!< in: index page */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
ulint* iup_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in upper limit record */
ulint* iup_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
ulint* ilow_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in lower limit record */
ulint* ilow_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
- page_cur_t* cursor) /* out: page cursor */
+ page_cur_t* cursor) /*!< out: page cursor */
{
const rec_t* rec;
const rec_t* next_rec;
@@ -154,20 +189,19 @@ exit_func:
#endif
#ifdef PAGE_CUR_LE_OR_EXTENDS
-/********************************************************************
+/****************************************************************//**
Checks if the nth field in a record is a character type field which extends
the nth field in tuple, i.e., the field is longer or equal in length and has
-common first characters. */
+common first characters.
+@return TRUE if rec field extends tuple field */
static
ibool
page_cur_rec_field_extends(
/*=======================*/
- /* out: TRUE if rec field
- extends tuple field */
- const dtuple_t* tuple, /* in: data tuple */
- const rec_t* rec, /* in: record */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n) /* in: compare nth field */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: record */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n) /*!< in: compare nth field */
{
const dtype_t* type;
const dfield_t* dfield;
@@ -205,33 +239,33 @@ page_cur_rec_field_extends(
}
#endif /* PAGE_CUR_LE_OR_EXTENDS */
-/********************************************************************
+/****************************************************************//**
Searches the right position for a page cursor. */
UNIV_INTERN
void
page_cur_search_with_match(
/*=======================*/
- const buf_block_t* block, /* in: buffer block */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L,
+ const buf_block_t* block, /*!< in: buffer block */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L,
PAGE_CUR_LE, PAGE_CUR_G, or
PAGE_CUR_GE */
ulint* iup_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in upper limit record */
ulint* iup_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
ulint* ilow_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in lower limit record */
ulint* ilow_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
- page_cur_t* cursor) /* out: page cursor */
+ page_cur_t* cursor) /*!< out: page cursor */
{
ulint up;
ulint low;
@@ -503,15 +537,15 @@ up_rec_match:
}
}
-/***************************************************************
+/***********************************************************//**
Positions a page cursor on a randomly chosen user record on a page. If there
are no user records, sets the cursor on the infimum record. */
UNIV_INTERN
void
page_cur_open_on_rnd_user_rec(
/*==========================*/
- buf_block_t* block, /* in: page */
- page_cur_t* cursor) /* out: page cursor */
+ 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));
@@ -523,27 +557,25 @@ page_cur_open_on_rnd_user_rec(
return;
}
- page_rnd += 87584577;
-
- rnd = page_rnd % n_recs;
+ rnd = (ulint) (page_cur_lcg_prng() % n_recs);
do {
page_cur_move_to_next(cursor);
} while (rnd--);
}
-/***************************************************************
+/***********************************************************//**
Writes the log record of a record insert on a page. */
static
void
page_cur_insert_rec_write_log(
/*==========================*/
- rec_t* insert_rec, /* in: inserted physical record */
- ulint rec_size, /* in: insert_rec size */
- rec_t* cursor_rec, /* in: record the
+ rec_t* insert_rec, /*!< in: inserted physical record */
+ ulint rec_size, /*!< in: insert_rec size */
+ rec_t* cursor_rec, /*!< in: record the
cursor is pointing to */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mini-transaction handle */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint cur_rec_size;
ulint extra_size;
@@ -713,20 +745,23 @@ need_extra_info:
mlog_catenate_string(mtr, ins_ptr, rec_size);
}
}
+#else /* !UNIV_HOTBACKUP */
+# define page_cur_insert_rec_write_log(ins_rec,size,cur,index,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a log record of a record insert on a page. */
+/***********************************************************//**
+Parses a log record of a record insert on a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_cur_parse_insert_rec(
/*======================*/
- /* out: end of log record or NULL */
- ibool is_short,/* in: TRUE if short inserts */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr or NULL */
+ ibool is_short,/*!< in: TRUE if short inserts */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ulint origin_offset;
ulint end_seg_len;
@@ -905,32 +940,31 @@ page_cur_parse_insert_rec(
return(ptr + end_seg_len);
}
-/***************************************************************
+/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
-space available, NULL otherwise. The cursor stays at the same position. */
+space available, NULL otherwise. The cursor stays at the same position.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INTERN
rec_t*
page_cur_insert_rec_low(
/*====================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- rec_t* current_rec,/* in: pointer to current record after
+ rec_t* current_rec,/*!< in: pointer to current record after
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) */
- mtr_t* mtr) /* in: mini-transaction handle, or NULL */
+ 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) */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
byte* insert_buf;
ulint rec_size;
- page_t* page; /* the relevant page */
- rec_t* last_insert; /* cursor position at previous
+ page_t* page; /*!< the relevant page */
+ rec_t* last_insert; /*!< cursor position at previous
insert */
- rec_t* free_rec; /* a free record that was reused,
+ rec_t* free_rec; /*!< a free record that was reused,
or NULL */
- rec_t* insert_rec; /* inserted record */
- ulint heap_no; /* heap number of the inserted
+ rec_t* insert_rec; /*!< inserted record */
+ ulint heap_no; /*!< heap number of the inserted
record */
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1118,21 +1152,21 @@ use_heap:
return(insert_rec);
}
-/***************************************************************
-Compresses or reorganizes a page after an optimistic insert. */
+/***********************************************************//**
+Compresses or reorganizes a page after an optimistic insert.
+@return rec if succeed, NULL otherwise */
static
rec_t*
page_cur_insert_rec_zip_reorg(
/*==========================*/
- /* out: rec if succeed, NULL otherwise */
- rec_t** current_rec,/* in/out: pointer to current record after
+ rec_t** current_rec,/*!< in/out: pointer to current record after
which the new record is inserted */
- buf_block_t* block, /* in: buffer block */
- dict_index_t* index, /* in: record descriptor */
- rec_t* rec, /* in: inserted record */
- page_t* page, /* in: uncompressed page */
- page_zip_des_t* page_zip,/* in: compressed page */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ buf_block_t* block, /*!< in: buffer block */
+ dict_index_t* index, /*!< in: record descriptor */
+ rec_t* rec, /*!< in: inserted record */
+ page_t* page, /*!< in: uncompressed page */
+ page_zip_des_t* page_zip,/*!< in: compressed page */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
{
ulint pos;
@@ -1161,41 +1195,40 @@ page_cur_insert_rec_zip_reorg(
}
/* Out of space: restore the page */
- if (!page_zip_decompress(page_zip, page)) {
+ if (!page_zip_decompress(page_zip, page, FALSE)) {
ut_error; /* Memory corrupted? */
}
ut_ad(page_validate(page, index));
return(NULL);
}
-/***************************************************************
+/***********************************************************//**
Inserts a record next to page cursor on a compressed and uncompressed
page. Returns pointer to inserted record if succeed, i.e.,
enough space available, NULL otherwise.
-The cursor stays at the same position. */
+The cursor stays at the same position.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INTERN
rec_t*
page_cur_insert_rec_zip(
/*====================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- rec_t** current_rec,/* in/out: pointer to current record after
+ rec_t** current_rec,/*!< in/out: pointer to current record after
which the new record is inserted */
- buf_block_t* block, /* in: buffer block of *current_rec */
- 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) */
- mtr_t* mtr) /* in: mini-transaction handle, or NULL */
+ buf_block_t* block, /*!< in: buffer block of *current_rec */
+ 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) */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
byte* insert_buf;
ulint rec_size;
- page_t* page; /* the relevant page */
- rec_t* last_insert; /* cursor position at previous
+ page_t* page; /*!< the relevant page */
+ rec_t* last_insert; /*!< cursor position at previous
insert */
- rec_t* free_rec; /* a free record that was reused,
+ rec_t* free_rec; /*!< a free record that was reused,
or NULL */
- rec_t* insert_rec; /* inserted record */
- ulint heap_no; /* heap number of the inserted
+ rec_t* insert_rec; /*!< inserted record */
+ ulint heap_no; /*!< heap number of the inserted
record */
page_zip_des_t* page_zip;
@@ -1466,18 +1499,18 @@ use_heap:
return(insert_rec);
}
-/**************************************************************
-Writes a log record of copying a record list end to a new created page. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Writes a log record of copying a record list end to a new created page.
+@return 4-byte field where to write the log data length, or NULL if
+logging is disabled */
UNIV_INLINE
byte*
page_copy_rec_list_to_created_page_write_log(
/*=========================================*/
- /* out: 4-byte field where to
- write the log data length,
- or NULL if logging is disabled */
- page_t* page, /* in: index page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /*!< in: index page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
@@ -1493,19 +1526,20 @@ page_copy_rec_list_to_created_page_write_log(
return(log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************
-Parses a log record of copying a record list end to a new created page. */
+/**********************************************************//**
+Parses a log record of copying a record list end to a new created page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_copy_rec_list_to_created_page(
/*=====================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
byte* rec_end;
ulint log_data_len;
@@ -1550,17 +1584,18 @@ page_parse_copy_rec_list_to_created_page(
return(rec_end);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Copies records from page to a newly created page, from a given record onward,
including that record. Infimum and supremum records are not copied. */
UNIV_INTERN
void
page_copy_rec_list_end_to_created_page(
/*===================================*/
- page_t* new_page, /* in/out: index page to copy to */
- rec_t* rec, /* in: first record to copy */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /*!< in/out: index page to copy to */
+ rec_t* rec, /*!< in: first record to copy */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_dir_slot_t* slot = 0; /* remove warning */
byte* heap_top;
@@ -1723,15 +1758,15 @@ page_copy_rec_list_end_to_created_page(
mtr_set_log_mode(mtr, log_mode);
}
-/***************************************************************
+/***********************************************************//**
Writes log record of a record delete on a page. */
UNIV_INLINE
void
page_cur_delete_rec_write_log(
/*==========================*/
- rec_t* rec, /* in: record to be deleted */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mini-transaction handle */
+ rec_t* rec, /*!< in: record to be deleted */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -1753,19 +1788,22 @@ page_cur_delete_rec_write_log(
mlog_close(mtr, log_ptr + 2);
}
+#else /* !UNIV_HOTBACKUP */
+# define page_cur_delete_rec_write_log(rec,index,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses log record of a record delete on a page. */
+/***********************************************************//**
+Parses log record of a record delete on a page.
+@return pointer to record end or NULL */
UNIV_INTERN
byte*
page_cur_parse_delete_rec(
/*======================*/
- /* out: pointer to record end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ulint offset;
page_cur_t cursor;
@@ -1803,17 +1841,17 @@ page_cur_parse_delete_rec(
return(ptr);
}
-/***************************************************************
+/***********************************************************//**
Deletes a record at the page cursor. The cursor is moved to the next
record after the deleted one. */
UNIV_INTERN
void
page_cur_delete_rec(
/*================*/
- page_cur_t* cursor, /* in/out: a page cursor */
- dict_index_t* index, /* in: record descriptor */
- const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
- mtr_t* mtr) /* in: mini-transaction handle */
+ page_cur_t* cursor, /*!< in/out: a page cursor */
+ dict_index_t* index, /*!< in: record descriptor */
+ const ulint* offsets,/*!< in: rec_get_offsets(cursor->rec, index) */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
page_dir_slot_t* cur_dir_slot;
page_dir_slot_t* prev_slot;
@@ -1920,3 +1958,30 @@ page_cur_delete_rec(
ut_a(!page_zip || page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
}
+
+#ifdef UNIV_COMPILE_TEST_FUNCS
+
+/*******************************************************************//**
+Print the first n numbers, generated by page_cur_lcg_prng() to make sure
+(visually) that it works properly. */
+void
+test_page_cur_lcg_prng(
+/*===================*/
+ int n) /*!< in: print first n numbers */
+{
+ int i;
+ unsigned long long rnd;
+
+ for (i = 0; i < n; i++) {
+ rnd = page_cur_lcg_prng();
+ printf("%llu\t%%2=%llu %%3=%llu %%5=%llu %%7=%llu %%11=%llu\n",
+ rnd,
+ rnd % 2,
+ rnd % 3,
+ rnd % 5,
+ rnd % 7,
+ rnd % 11);
+ }
+}
+
+#endif /* UNIV_COMPILE_TEST_FUNCS */
diff --git a/storage/xtradb/page/page0page.c b/storage/xtradb/page/page0page.c
index 0ce532068ce..ab2ba60570e 100644
--- a/storage/xtradb/page/page0page.c
+++ b/storage/xtradb/page/page0page.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file page/page0page.c
Index page routines
Created 2/2/1994 Heikki Tuuri
@@ -31,18 +32,20 @@ Created 2/2/1994 Heikki Tuuri
#include "page0cur.h"
#include "page0zip.h"
-#include "lock0lock.h"
-#include "fut0lst.h"
-#include "btr0sea.h"
#include "buf0buf.h"
-#include "srv0srv.h"
#include "btr0btr.h"
+#ifndef UNIV_HOTBACKUP
+# include "srv0srv.h"
+# include "lock0lock.h"
+# include "fut0lst.h"
+# include "btr0sea.h"
+#endif /* !UNIV_HOTBACKUP */
/* THE INDEX PAGE
==============
The index page consists of a page header which contains the page's
-id and other information. On top of it are the the index records
+id and other information. On top of it are the index records
in a heap linked into a one way linear list according to alphabetic order.
Just below page end is an array of pointers which we call page directory,
@@ -80,14 +83,14 @@ Assuming a page size of 8 kB, a typical index page of a secondary
index contains 300 index entries, and the size of the page directory
is 50 x 4 bytes = 200 bytes. */
-/*******************************************************************
-Looks for the directory slot which owns the given record. */
+/***************************************************************//**
+Looks for the directory slot which owns the given record.
+@return the directory slot number */
UNIV_INTERN
ulint
page_dir_find_owner_slot(
/*=====================*/
- /* out: the directory slot number */
- const rec_t* rec) /* in: the physical record */
+ const rec_t* rec) /*!< in: the physical record */
{
const page_t* page;
register uint16 rec_offs_bytes;
@@ -156,14 +159,14 @@ page_dir_find_owner_slot(
return(((ulint) (first_slot - slot)) / PAGE_DIR_SLOT_SIZE);
}
-/******************************************************************
-Used to check the consistency of a directory slot. */
+/**************************************************************//**
+Used to check the consistency of a directory slot.
+@return TRUE if succeed */
static
ibool
page_dir_slot_check(
/*================*/
- /* out: TRUE if succeed */
- page_dir_slot_t* slot) /* in: slot */
+ page_dir_slot_t* slot) /*!< in: slot */
{
page_t* page;
ulint n_slots;
@@ -199,53 +202,66 @@ page_dir_slot_check(
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Sets the max trx id field value. */
UNIV_INTERN
void
page_set_max_trx_id(
/*================*/
- buf_block_t* block, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dulint trx_id) /* in: transaction id */
+ buf_block_t* block, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in/out: mini-transaction, or NULL */
{
- const ibool is_hashed = block->is_hashed;
page_t* page = buf_block_get_frame(block);
+#ifndef UNIV_HOTBACKUP
+ const ibool is_hashed = block->is_hashed;
if (is_hashed) {
rw_lock_x_lock(&btr_search_latch);
}
+ ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+#endif /* !UNIV_HOTBACKUP */
+
/* It is not necessary to write this change to the redo log, as
during a database recovery we assume that the max trx id of every
page is the maximum trx id assigned before the crash. */
- mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
if (UNIV_LIKELY_NULL(page_zip)) {
+ mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
page_zip_write_header(page_zip,
page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
- 8, NULL);
+ 8, mtr);
+#ifndef UNIV_HOTBACKUP
+ } else if (mtr) {
+ mlog_write_dulint(page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
+ trx_id, mtr);
+#endif /* !UNIV_HOTBACKUP */
+ } else {
+ mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
}
+#ifndef UNIV_HOTBACKUP
if (is_hashed) {
rw_lock_x_unlock(&btr_search_latch);
}
+#endif /* !UNIV_HOTBACKUP */
}
-/****************************************************************
-Allocates a block of memory from the heap of an index page. */
+/************************************************************//**
+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(
/*================*/
- /* out: pointer to start of allocated
- buffer, or NULL if allocation fails */
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page with enough
+ 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
+ ulint need, /*!< in: total number of bytes needed */
+ ulint* heap_no)/*!< out: this contains the heap number
of the allocated record
if allocation succeeds */
{
@@ -271,34 +287,38 @@ page_mem_alloc_heap(
return(NULL);
}
-/**************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Writes a log record of page creation. */
UNIV_INLINE
void
page_create_write_log(
/*==================*/
- buf_frame_t* frame, /* in: a buffer frame where the page is
+ buf_frame_t* frame, /*!< in: a buffer frame where the page is
created */
- mtr_t* mtr, /* in: mini-transaction handle */
- ibool comp) /* in: TRUE=compact page format */
+ mtr_t* mtr, /*!< in: mini-transaction handle */
+ ibool comp) /*!< in: TRUE=compact page format */
{
mlog_write_initial_log_record(frame, comp
? MLOG_COMP_PAGE_CREATE
: MLOG_PAGE_CREATE, mtr);
}
+#else /* !UNIV_HOTBACKUP */
+# define page_create_write_log(frame,mtr,comp) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of creating a page. */
+/***********************************************************//**
+Parses a redo log record of creating a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_create(
/*==============*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- ulint comp, /* in: nonzero=compact page format */
- buf_block_t* block, /* in: block or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ ulint comp, /*!< in: nonzero=compact page format */
+ buf_block_t* block, /*!< in: block or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(ptr && end_ptr);
@@ -311,16 +331,16 @@ page_parse_create(
return(ptr);
}
-/**************************************************************
-The index page creation function. */
+/**********************************************************//**
+The index page creation function.
+@return pointer to the page */
static
page_t*
page_create_low(
/*============*/
- /* out: pointer to the page */
- buf_block_t* block, /* in: a buffer block where the
+ buf_block_t* block, /*!< in: a buffer block where the
page is created */
- ulint comp) /* in: nonzero=compact page format */
+ ulint comp) /*!< in: nonzero=compact page format */
{
page_dir_slot_t* slot;
mem_heap_t* heap;
@@ -343,9 +363,9 @@ page_create_low(
/* The infimum and supremum records use a dummy index. */
if (UNIV_LIKELY(comp)) {
- index = srv_sys->dummy_ind2;
+ index = dict_ind_compact;
} else {
- index = srv_sys->dummy_ind1;
+ index = dict_ind_redundant;
}
/* 1. INCREMENT MODIFY CLOCK */
@@ -437,7 +457,7 @@ page_create_low(
page_header_set_field(page, NULL, PAGE_DIRECTION, PAGE_NO_DIRECTION);
page_header_set_field(page, NULL, PAGE_N_DIRECTION, 0);
page_header_set_field(page, NULL, PAGE_N_RECS, 0);
- page_set_max_trx_id(block, NULL, ut_dulint_zero);
+ page_set_max_trx_id(block, NULL, ut_dulint_zero, NULL);
memset(heap_top, 0, UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START
- page_offset(heap_top));
@@ -464,34 +484,34 @@ page_create_low(
return(page);
}
-/**************************************************************
-Create an uncompressed B-tree index page. */
+/**********************************************************//**
+Create an uncompressed B-tree index page.
+@return pointer to the page */
UNIV_INTERN
page_t*
page_create(
/*========*/
- /* out: pointer to the page */
- buf_block_t* block, /* in: a buffer block where the
+ buf_block_t* block, /*!< in: a buffer block where the
page is created */
- mtr_t* mtr, /* in: mini-transaction handle */
- ulint comp) /* in: nonzero=compact page format */
+ mtr_t* mtr, /*!< in: mini-transaction handle */
+ ulint comp) /*!< in: nonzero=compact page format */
{
page_create_write_log(buf_block_get_frame(block), mtr, comp);
return(page_create_low(block, comp));
}
-/**************************************************************
-Create a compressed B-tree index page. */
+/**********************************************************//**
+Create a compressed B-tree index page.
+@return pointer to the page */
UNIV_INTERN
page_t*
page_create_zip(
/*============*/
- /* out: pointer to the page */
- buf_block_t* block, /* in/out: a buffer frame where the
+ buf_block_t* block, /*!< in/out: a buffer frame where the
page is created */
- dict_index_t* index, /* in: the index of the page */
- ulint level, /* in: the B-tree level of the page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint level, /*!< in: the B-tree level of the page */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
page_t* page;
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
@@ -513,18 +533,18 @@ page_create_zip(
return(page);
}
-/*****************************************************************
+/*************************************************************//**
Differs from page_copy_rec_list_end, because this function does not
touch the lock table and max trx id on page or compress the page. */
UNIV_INTERN
void
page_copy_rec_list_end_no_locks(
/*============================*/
- buf_block_t* new_block, /* in: index page to copy to */
- buf_block_t* block, /* in: index page of rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in: index page to copy to */
+ buf_block_t* block, /*!< in: index page of rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* new_page = buf_block_get_frame(new_block);
page_cur_t cur1;
@@ -584,23 +604,22 @@ page_copy_rec_list_end_no_locks(
}
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Copies records from page to new_page, from a given record onward,
including that record. Infimum and supremum records are not copied.
-The records are copied to the start of the record list on new_page. */
+The records are copied to the start of the record list on new_page.
+@return pointer to the original successor of the infimum record on
+new_page, or NULL on zip overflow (new_block will be decompressed) */
UNIV_INTERN
rec_t*
page_copy_rec_list_end(
/*===================*/
- /* out: pointer to the original
- successor of the infimum record
- on new_page, or NULL on zip overflow
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page to copy to */
- buf_block_t* block, /* in: index page containing rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page to copy to */
+ buf_block_t* block, /*!< in: index page containing rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* new_page = buf_block_get_frame(new_block);
page_zip_des_t* new_page_zip = buf_block_get_page_zip(new_block);
@@ -660,7 +679,7 @@ page_copy_rec_list_end(
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
- new_page))) {
+ new_page, FALSE))) {
ut_error;
}
ut_ad(page_validate(new_page, index));
@@ -681,31 +700,31 @@ page_copy_rec_list_end(
lock_move_rec_list_end(new_block, block, rec);
- page_update_max_trx_id(new_block, new_page_zip,
- page_get_max_trx_id(page));
+ if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
+ page_update_max_trx_id(new_block, new_page_zip,
+ page_get_max_trx_id(page), mtr);
+ }
btr_search_move_or_delete_hash_entries(new_block, block, index);
return(ret);
}
-/*****************************************************************
+/*************************************************************//**
Copies records from page to new_page, up to the given record,
NOT including that record. Infimum and supremum records are not copied.
-The records are copied to the end of the record list on new_page. */
+The records are copied to the end of the record list on new_page.
+@return pointer to the original predecessor of the supremum record on
+new_page, or NULL on zip overflow (new_block will be decompressed) */
UNIV_INTERN
rec_t*
page_copy_rec_list_start(
/*=====================*/
- /* out: pointer to the original
- predecessor of the supremum record
- on new_page, or NULL on zip overflow
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page to copy to */
- buf_block_t* block, /* in: index page containing rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page to copy to */
+ buf_block_t* block, /*!< in: index page containing rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* new_page = buf_block_get_frame(new_block);
page_zip_des_t* new_page_zip = buf_block_get_page_zip(new_block);
@@ -773,7 +792,7 @@ page_copy_rec_list_start(
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
- new_page))) {
+ new_page, FALSE))) {
ut_error;
}
ut_ad(page_validate(new_page, index));
@@ -792,8 +811,12 @@ page_copy_rec_list_start(
/* Update MAX_TRX_ID, the lock table, and possible hash index */
- page_update_max_trx_id(new_block, new_page_zip,
- page_get_max_trx_id(page_align(rec)));
+ if (dict_index_is_sec_or_ibuf(index)
+ && page_is_leaf(page_align(rec))) {
+ page_update_max_trx_id(new_block, new_page_zip,
+ page_get_max_trx_id(page_align(rec)),
+ mtr);
+ }
lock_move_rec_list_start(new_block, block, rec, ret);
@@ -802,17 +825,17 @@ page_copy_rec_list_start(
return(ret);
}
-/**************************************************************
+/**********************************************************//**
Writes a log record of a record list end or start deletion. */
UNIV_INLINE
void
page_delete_rec_list_write_log(
/*===========================*/
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- byte type, /* in: operation type:
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ byte type, /*!< in: operation type:
MLOG_LIST_END_DELETE, ... */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
ut_ad(type == MLOG_LIST_END_DELETE
@@ -827,23 +850,26 @@ page_delete_rec_list_write_log(
mlog_close(mtr, log_ptr + 2);
}
}
+#else /* !UNIV_HOTBACKUP */
+# define page_delete_rec_list_write_log(rec,index,type,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************
-Parses a log record of a record list end or start deletion. */
+/**********************************************************//**
+Parses a log record of a record list end or start deletion.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_delete_rec_list(
/*=======================*/
- /* out: end of log record or NULL */
- byte type, /* in: MLOG_LIST_END_DELETE,
+ byte type, /*!< in: MLOG_LIST_END_DELETE,
MLOG_LIST_START_DELETE,
MLOG_COMP_LIST_END_DELETE or
MLOG_COMP_LIST_START_DELETE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in/out: buffer block or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in/out: buffer block or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
page_t* page;
ulint offset;
@@ -884,22 +910,22 @@ page_parse_delete_rec_list(
return(ptr);
}
-/*****************************************************************
+/*************************************************************//**
Deletes records from a page from a given record onward, including that record.
The infimum and supremum records are not deleted. */
UNIV_INTERN
void
page_delete_rec_list_end(
/*=====================*/
- rec_t* rec, /* in: pointer to record on page */
- buf_block_t* block, /* in: buffer block of the page */
- dict_index_t* index, /* in: record descriptor */
- ulint n_recs, /* in: number of records to delete,
+ rec_t* rec, /*!< in: pointer to record on page */
+ buf_block_t* block, /*!< in: buffer block of the page */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n_recs, /*!< in: number of records to delete,
or ULINT_UNDEFINED if not known */
- ulint size, /* in: the sum of the sizes of the
+ ulint size, /*!< in: the sum of the sizes of the
records in the end of the chain to
delete, or ULINT_UNDEFINED if not known */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
page_dir_slot_t*slot;
ulint slot_index;
@@ -1060,17 +1086,17 @@ page_delete_rec_list_end(
(ulint)(page_get_n_recs(page) - n_recs));
}
-/*****************************************************************
+/*************************************************************//**
Deletes records from page, up to the given record, NOT including
that record. Infimum and supremum records are not deleted. */
UNIV_INTERN
void
page_delete_rec_list_start(
/*=======================*/
- rec_t* rec, /* in: record on page */
- buf_block_t* block, /* in: buffer block of the page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record on page */
+ buf_block_t* block, /*!< in: buffer block of the page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t cur1;
ulint log_mode;
@@ -1132,21 +1158,21 @@ page_delete_rec_list_start(
mtr_set_log_mode(mtr, log_mode);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Moves record list end to another page. Moved records include
-split_rec. */
+split_rec.
+@return TRUE on success; FALSE on compression failure (new_block will
+be decompressed) */
UNIV_INTERN
ibool
page_move_rec_list_end(
/*===================*/
- /* out: TRUE on success; FALSE on
- compression failure
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page where to move */
- buf_block_t* block, /* in: index page from where to move */
- rec_t* split_rec, /* in: first record to move */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page where to move */
+ buf_block_t* block, /*!< in: index page from where to move */
+ rec_t* split_rec, /*!< in: first record to move */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* new_page = buf_block_get_frame(new_block);
ulint old_data_size;
@@ -1187,20 +1213,19 @@ page_move_rec_list_end(
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Moves record list start to another page. Moved records do not include
-split_rec. */
+split_rec.
+@return TRUE on success; FALSE on compression failure */
UNIV_INTERN
ibool
page_move_rec_list_start(
/*=====================*/
- /* out: TRUE on success; FALSE on
- compression failure */
- buf_block_t* new_block, /* in/out: index page where to move */
- buf_block_t* block, /* in/out: page containing split_rec */
- rec_t* split_rec, /* in: first record not to move */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page where to move */
+ buf_block_t* block, /*!< in/out: page containing split_rec */
+ rec_t* split_rec, /*!< in: first record not to move */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_UNLIKELY(!page_copy_rec_list_start(new_block, block,
split_rec, index, mtr))) {
@@ -1212,17 +1237,17 @@ page_move_rec_list_start(
return(TRUE);
}
-/***************************************************************************
+/***********************************************************************//**
This is a low-level operation which is used in a database index creation
to update the page number of a created B-tree to a data dictionary record. */
UNIV_INTERN
void
page_rec_write_index_page_no(
/*=========================*/
- rec_t* rec, /* in: record to update */
- ulint i, /* in: index of the field to update */
- ulint page_no,/* in: value to write */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record to update */
+ ulint i, /*!< in: index of the field to update */
+ ulint page_no,/*!< in: value to write */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* data;
ulint len;
@@ -1233,8 +1258,9 @@ page_rec_write_index_page_no(
mlog_write_ulint(data, page_no, MLOG_4BYTES, mtr);
}
+#endif /* !UNIV_HOTBACKUP */
-/******************************************************************
+/**************************************************************//**
Used to delete n slots from the directory. This function updates
also n_owned fields in the records, so that the first slot after
the deleted ones inherits the records of the deleted slots. */
@@ -1242,9 +1268,9 @@ UNIV_INLINE
void
page_dir_delete_slot(
/*=================*/
- page_t* page, /* in/out: the index page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint slot_no)/* in: slot to be deleted */
+ page_t* page, /*!< in/out: the index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint slot_no)/*!< in: slot to be deleted */
{
page_dir_slot_t* slot;
ulint n_owned;
@@ -1283,7 +1309,7 @@ page_dir_delete_slot(
page_header_set_field(page, page_zip, PAGE_N_DIR_SLOTS, n_slots - 1);
}
-/******************************************************************
+/**************************************************************//**
Used to add n slots to the directory. Does not set the record pointers
in the added slots or update n_owned values: this is the responsibility
of the caller. */
@@ -1291,9 +1317,9 @@ UNIV_INLINE
void
page_dir_add_slot(
/*==============*/
- page_t* page, /* in/out: the index page */
- page_zip_des_t* page_zip,/* in/out: comprssed page, or NULL */
- ulint start) /* in: the slot above which the new slots
+ page_t* page, /*!< in/out: the index page */
+ page_zip_des_t* page_zip,/*!< in/out: comprssed page, or NULL */
+ ulint start) /*!< in: the slot above which the new slots
are added */
{
page_dir_slot_t* slot;
@@ -1312,16 +1338,16 @@ page_dir_add_slot(
(n_slots - 1 - start) * PAGE_DIR_SLOT_SIZE);
}
-/********************************************************************
+/****************************************************************//**
Splits a directory slot which owns too many records. */
UNIV_INTERN
void
page_dir_split_slot(
/*================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be written, or NULL */
- ulint slot_no)/* in: the directory slot */
+ ulint slot_no)/*!< in: the directory slot */
{
rec_t* rec;
page_dir_slot_t* new_slot;
@@ -1373,7 +1399,7 @@ page_dir_split_slot(
page_dir_slot_set_n_owned(slot, page_zip, n_owned - (n_owned / 2));
}
-/*****************************************************************
+/*************************************************************//**
Tries to balance the given directory slot with too few records with the upper
neighbor, so that there are at least the minimum number of records owned by
the slot; this may result in the merging of two slots. */
@@ -1381,9 +1407,9 @@ UNIV_INTERN
void
page_dir_balance_slot(
/*==================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint slot_no)/* in: the directory slot */
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint slot_no)/*!< in: the directory slot */
{
page_dir_slot_t* slot;
page_dir_slot_t* up_slot;
@@ -1444,15 +1470,16 @@ page_dir_balance_slot(
}
}
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Returns the middle record of the record list. If there are an even number
-of records in the list, returns the first record of the upper half-list. */
+of records in the list, returns the first record of the upper half-list.
+@return middle record */
UNIV_INTERN
rec_t*
page_get_middle_rec(
/*================*/
- /* out: middle record */
- page_t* page) /* in: page */
+ page_t* page) /*!< in: page */
{
page_dir_slot_t* slot;
ulint middle;
@@ -1491,16 +1518,17 @@ page_get_middle_rec(
return(rec);
}
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Returns the number of records before the given record in chain.
-The number includes infimum and supremum records. */
+The number includes infimum and supremum records.
+@return number of records */
UNIV_INTERN
ulint
page_rec_get_n_recs_before(
/*=======================*/
- /* out: number of records */
- const rec_t* rec) /* in: the physical record */
+ const rec_t* rec) /*!< in: the physical record */
{
const page_dir_slot_t* slot;
const rec_t* slot_rec;
@@ -1556,15 +1584,16 @@ page_rec_get_n_recs_before(
return((ulint) n);
}
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Prints record contents including the data relevant only in
the index page context. */
UNIV_INTERN
void
page_rec_print(
/*===========*/
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: record descriptor */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: record descriptor */
{
ut_a(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
rec_print_new(stderr, rec, offsets);
@@ -1586,15 +1615,15 @@ page_rec_print(
rec_validate(rec, offsets);
}
-/*******************************************************************
+/***************************************************************//**
This is used to print the contents of the directory for
debugging purposes. */
UNIV_INTERN
void
page_dir_print(
/*===========*/
- page_t* page, /* in: index page */
- ulint pr_n) /* in: print n first and n last entries */
+ page_t* page, /*!< in: index page */
+ ulint pr_n) /*!< in: print n first and n last entries */
{
ulint n;
ulint i;
@@ -1628,16 +1657,16 @@ page_dir_print(
(ulong) (PAGE_HEAP_NO_USER_LOW + page_get_n_recs(page)));
}
-/*******************************************************************
+/***************************************************************//**
This is used to print the contents of the page record list for
debugging purposes. */
UNIV_INTERN
void
page_print_list(
/*============*/
- buf_block_t* block, /* in: index page */
- dict_index_t* index, /* in: dictionary index of the page */
- ulint pr_n) /* in: print n first and n last entries */
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index, /*!< in: dictionary index of the page */
+ ulint pr_n) /*!< in: print n first and n last entries */
{
page_t* page = block->frame;
page_cur_t cur;
@@ -1699,7 +1728,7 @@ page_print_list(
}
}
-/*******************************************************************
+/***************************************************************//**
Prints the info in a page header. */
UNIV_INTERN
void
@@ -1726,18 +1755,18 @@ page_header_print(
(ulong) page_header_get_field(page, PAGE_N_DIRECTION));
}
-/*******************************************************************
+/***************************************************************//**
This is used to print the contents of the page for
debugging purposes. */
UNIV_INTERN
void
page_print(
/*=======*/
- buf_block_t* block, /* in: index page */
- dict_index_t* index, /* in: dictionary index of the page */
- ulint dn, /* in: print dn first and last entries
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index, /*!< in: dictionary index of the page */
+ ulint dn, /*!< in: print dn first and last entries
in directory */
- ulint rn) /* in: print rn first and last records
+ ulint rn) /*!< in: print rn first and last records
in directory */
{
page_t* page = block->frame;
@@ -1746,18 +1775,19 @@ page_print(
page_dir_print(page, dn);
page_print_list(block, index, rn);
}
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
The following is used to validate a record on a page. This function
differs from rec_validate as it can also check the n_owned field and
-the heap_no field. */
+the heap_no field.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_rec_validate(
/*==============*/
- /* out: TRUE if ok */
- rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_owned;
ulint heap_no;
@@ -1795,7 +1825,8 @@ page_rec_validate(
return(TRUE);
}
-/*******************************************************************
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Checks that the first directory slot points to the infimum record and
the last to the supremum. This function is intended to track if the
bug fixed in 4.0.14 has caused corruption to users' databases. */
@@ -1803,7 +1834,7 @@ UNIV_INTERN
void
page_check_dir(
/*===========*/
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
ulint n_slots;
ulint infimum_offs;
@@ -1830,17 +1861,18 @@ page_check_dir(
buf_page_print(page, 0);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
This function checks the consistency of an index page when we do not
know the index. This is also resilient so that this should never crash
-even if the page is total garbage. */
+even if the page is total garbage.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_simple_validate_old(
/*=====================*/
- /* out: TRUE if ok */
- page_t* page) /* in: old-style index page */
+ page_t* page) /*!< in: old-style index page */
{
page_dir_slot_t* slot;
ulint slot_no;
@@ -2041,16 +2073,16 @@ func_exit:
return(ret);
}
-/*******************************************************************
+/***************************************************************//**
This function checks the consistency of an index page when we do not
know the index. This is also resilient so that this should never crash
-even if the page is total garbage. */
+even if the page is total garbage.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_simple_validate_new(
/*=====================*/
- /* out: TRUE if ok */
- page_t* page) /* in: new-style index page */
+ page_t* page) /*!< in: new-style index page */
{
page_dir_slot_t* slot;
ulint slot_no;
@@ -2252,15 +2284,15 @@ func_exit:
return(ret);
}
-/*******************************************************************
-This function checks the consistency of an index page. */
+/***************************************************************//**
+This function checks the consistency of an index page.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_validate(
/*==========*/
- /* out: TRUE if ok */
- page_t* page, /* in: index page */
- dict_index_t* index) /* in: data dictionary index containing
+ page_t* page, /*!< in: index page */
+ dict_index_t* index) /*!< in: data dictionary index containing
the page record type definition */
{
page_dir_slot_t*slot;
@@ -2310,10 +2342,11 @@ page_validate(
if (UNIV_UNLIKELY(!(page_header_get_ptr(page, PAGE_HEAP_TOP)
<= page_dir_get_nth_slot(page, n_slots - 1)))) {
- fputs("InnoDB: Record heap and dir overlap on a page ",
- stderr);
- dict_index_name_print(stderr, NULL, index);
- fprintf(stderr, ", %p, %p\n",
+ fprintf(stderr,
+ "InnoDB: Record heap and dir overlap"
+ " on space %lu page %lu index %s, %p, %p\n",
+ (ulong) page_get_space_id(page),
+ (ulong) page_get_page_no(page), index->name,
page_header_get_ptr(page, PAGE_HEAP_TOP),
page_dir_get_nth_slot(page, n_slots - 1));
@@ -2345,17 +2378,19 @@ page_validate(
goto func_exit;
}
+#ifndef UNIV_HOTBACKUP
/* Check that the records are in the ascending order */
if (UNIV_LIKELY(count >= PAGE_HEAP_NO_USER_LOW)
&& !page_rec_is_supremum(rec)) {
if (UNIV_UNLIKELY
(1 != cmp_rec_rec(rec, old_rec,
offsets, old_offsets, index))) {
- fprintf(stderr,
+ fprintf(stderr,
"InnoDB: Records in wrong order"
- " on page %lu ",
- (ulong) page_get_page_no(page));
- dict_index_name_print(stderr, NULL, index);
+ " on space %lu page %lu index %s\n",
+ (ulong) page_get_space_id(page),
+ (ulong) page_get_page_no(page),
+ index->name);
fputs("\nInnoDB: previous record ", stderr);
rec_print_new(stderr, old_rec, old_offsets);
fputs("\nInnoDB: record ", stderr);
@@ -2365,6 +2400,7 @@ page_validate(
goto func_exit;
}
}
+#endif /* !UNIV_HOTBACKUP */
if (page_rec_is_user_rec(rec)) {
@@ -2510,25 +2546,28 @@ func_exit:
if (UNIV_UNLIKELY(ret == FALSE)) {
func_exit2:
- fprintf(stderr, "InnoDB: Apparent corruption in page %lu in ",
- (ulong) page_get_page_no(page));
- dict_index_name_print(stderr, NULL, index);
- putc('\n', stderr);
+ fprintf(stderr,
+ "InnoDB: Apparent corruption"
+ " in space %lu page %lu index %s\n",
+ (ulong) page_get_space_id(page),
+ (ulong) page_get_page_no(page),
+ index->name);
buf_page_print(page, 0);
}
return(ret);
}
-/*******************************************************************
-Looks in the page record list for a record with the given heap number. */
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
+Looks in the page record list for a record with the given heap number.
+@return record, NULL if not found */
UNIV_INTERN
const rec_t*
page_find_rec_with_heap_no(
/*=======================*/
- /* out: record, NULL if not found */
- const page_t* page, /* in: index page */
- ulint heap_no)/* in: heap number */
+ const page_t* page, /*!< in: index page */
+ ulint heap_no)/*!< in: heap number */
{
const rec_t* rec;
@@ -2566,3 +2605,4 @@ page_find_rec_with_heap_no(
}
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/page/page0zip.c b/storage/xtradb/page/page0zip.c
index 56189ce3bad..aa5e39ff04a 100644
--- a/storage/xtradb/page/page0zip.c
+++ b/storage/xtradb/page/page0zip.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file page/page0zip.c
Compressed page interface
Created June 2005 by Marko Makela
@@ -31,18 +32,25 @@ Created June 2005 by Marko Makela
#include "page0page.h"
#include "mtr0log.h"
#include "ut0sort.h"
-#include "dict0boot.h"
#include "dict0dict.h"
-#include "btr0sea.h"
#include "btr0cur.h"
#include "page0types.h"
-#include "lock0lock.h"
#include "log0recv.h"
#include "zlib.h"
-#include "buf0lru.h"
-
+#ifndef UNIV_HOTBACKUP
+# include "buf0lru.h"
+# include "btr0sea.h"
+# include "dict0boot.h"
+# include "lock0lock.h"
+#else /* !UNIV_HOTBACKUP */
+# define lock_move_reorganize_page(block, temp_block) ((void) 0)
+# define buf_LRU_stat_inc_unzip() ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
+
+#ifndef UNIV_HOTBACKUP
/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
+#endif /* !UNIV_HOTBACKUP */
/* Please refer to ../include/page0zip.ic for a description of the
compressed page format. */
@@ -50,15 +58,18 @@ compressed page format. */
/* The infimum and supremum records are omitted from the compressed page.
On compress, we compare that the records are there, and on uncompress we
restore the records. */
+/** Extra bytes of an infimum record */
static const byte infimum_extra[] = {
0x01, /* info_bits=0, n_owned=1 */
0x00, 0x02 /* heap_no=0, status=2 */
/* ?, ? */ /* next=(first user rec, or supremum) */
};
+/** Data bytes of an infimum record */
static const byte infimum_data[] = {
0x69, 0x6e, 0x66, 0x69,
0x6d, 0x75, 0x6d, 0x00 /* "infimum\0" */
};
+/** Extra bytes and data bytes of a supremum record */
static const byte supremum_extra_data[] = {
/* 0x0?, */ /* info_bits=0, n_owned=1..8 */
0x00, 0x0b, /* heap_no=1, status=3 */
@@ -68,10 +79,13 @@ static const byte supremum_extra_data[] = {
};
/** Assert that a block of memory is filled with zero bytes.
-Compare at most sizeof(field_ref_zero) bytes. */
+Compare at most sizeof(field_ref_zero) bytes.
+@param b in: memory block
+@param s in: size of the memory block, in bytes */
#define ASSERT_ZERO(b, s) \
ut_ad(!memcmp(b, field_ref_zero, ut_min(s, sizeof field_ref_zero)))
-/** Assert that a BLOB pointer is filled with 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))
@@ -80,15 +94,15 @@ independently of any UNIV_ debugging conditions. */
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
# include <stdarg.h>
__attribute__((format (printf, 1, 2)))
-/**************************************************************************
-Report a failure to decompress or compress. */
+/**********************************************************************//**
+Report a failure to decompress or compress.
+@return number of characters printed */
static
int
page_zip_fail_func(
/*===============*/
- /* out: number of characters printed */
- const char* fmt, /* in: printf(3) format string */
- ...) /* in: arguments corresponding to fmt */
+ const char* fmt, /*!< in: printf(3) format string */
+ ...) /*!< in: arguments corresponding to fmt */
{
int res;
va_list ap;
@@ -101,20 +115,25 @@ page_zip_fail_func(
return(res);
}
+/** Wrapper for page_zip_fail_func()
+@param fmt_args in: printf(3) format string and arguments */
# define page_zip_fail(fmt_args) page_zip_fail_func fmt_args
#else /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+/** Dummy wrapper for page_zip_fail_func()
+@param fmt_args ignored: printf(3) format string and arguments */
# define page_zip_fail(fmt_args) /* empty */
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
-/**************************************************************************
-Determine the guaranteed free space on an empty page. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Determine the guaranteed free space on an empty page.
+@return minimum payload size on the page */
UNIV_INTERN
ulint
page_zip_empty_size(
/*================*/
- /* out: minimum payload size on the page */
- ulint n_fields, /* in: number of columns in the index */
- ulint zip_size) /* in: compressed page size in bytes */
+ ulint n_fields, /*!< in: number of columns in the index */
+ ulint zip_size) /*!< in: compressed page size in bytes */
{
lint size = zip_size
/* subtract the page header and the longest
@@ -129,17 +148,17 @@ page_zip_empty_size(
- compressBound(2 * (n_fields + 1));
return(size > 0 ? (ulint) size : 0);
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Gets the size of the compressed page trailer (the dense page directory),
-including deleted records (the free list). */
+including deleted records (the free list).
+@return length of dense page directory, in bytes */
UNIV_INLINE
ulint
page_zip_dir_size(
/*==============*/
- /* out: length of dense page
- directory, in bytes */
- const page_zip_des_t* page_zip) /* in: compressed page */
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
{
/* Exclude the page infimum and supremum from the record count. */
ulint size = PAGE_ZIP_DIR_SLOT_SIZE
@@ -148,17 +167,15 @@ page_zip_dir_size(
return(size);
}
-/*****************************************************************
+/*************************************************************//**
Gets the size of the compressed page trailer (the dense page directory),
-only including user records (excluding the free list). */
+only including user records (excluding the free list).
+@return length of dense page directory comprising existing records, in bytes */
UNIV_INLINE
ulint
page_zip_dir_user_size(
/*===================*/
- /* out: length of dense page
- directory comprising existing
- records, in bytes */
- const page_zip_des_t* page_zip) /* in: compressed page */
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
{
ulint size = PAGE_ZIP_DIR_SLOT_SIZE
* page_get_n_recs(page_zip->data);
@@ -166,17 +183,16 @@ page_zip_dir_user_size(
return(size);
}
-/*****************************************************************
-Find the slot of the given record in the dense page directory. */
+/*************************************************************//**
+Find the slot of the given record in the dense page directory.
+@return dense directory slot, or NULL if record not found */
UNIV_INLINE
byte*
page_zip_dir_find_low(
/*==================*/
- /* out: dense directory slot,
- or NULL if record not found */
- byte* slot, /* in: start of records */
- byte* end, /* in: end of records */
- ulint offset) /* in: offset of user record */
+ byte* slot, /*!< in: start of records */
+ byte* end, /*!< in: end of records */
+ ulint offset) /*!< in: offset of user record */
{
ut_ad(slot <= end);
@@ -190,16 +206,15 @@ page_zip_dir_find_low(
return(NULL);
}
-/*****************************************************************
-Find the slot of the given non-free record in the dense page directory. */
+/*************************************************************//**
+Find the slot of the given non-free record in the dense page directory.
+@return dense directory slot, or NULL if record not found */
UNIV_INLINE
byte*
page_zip_dir_find(
/*==============*/
- /* out: dense directory slot,
- or NULL if record not found */
- page_zip_des_t* page_zip, /* in: compressed page */
- ulint offset) /* in: offset of user record */
+ page_zip_des_t* page_zip, /*!< in: compressed page */
+ ulint offset) /*!< in: offset of user record */
{
byte* end = page_zip->data + page_zip_get_size(page_zip);
@@ -210,16 +225,15 @@ page_zip_dir_find(
offset));
}
-/*****************************************************************
-Find the slot of the given free record in the dense page directory. */
+/*************************************************************//**
+Find the slot of the given free record in the dense page directory.
+@return dense directory slot, or NULL if record not found */
UNIV_INLINE
byte*
page_zip_dir_find_free(
/*===================*/
- /* out: dense directory slot,
- or NULL if record not found */
- page_zip_des_t* page_zip, /* in: compressed page */
- ulint offset) /* in: offset of user record */
+ page_zip_des_t* page_zip, /*!< in: compressed page */
+ ulint offset) /*!< in: offset of user record */
{
byte* end = page_zip->data + page_zip_get_size(page_zip);
@@ -230,19 +244,16 @@ page_zip_dir_find_free(
offset));
}
-/*****************************************************************
-Read a given slot in the dense page directory. */
+/*************************************************************//**
+Read a given slot in the dense page directory.
+@return record offset on the uncompressed page, possibly ORed with
+PAGE_ZIP_DIR_SLOT_DEL or PAGE_ZIP_DIR_SLOT_OWNED */
UNIV_INLINE
ulint
page_zip_dir_get(
/*=============*/
- /* out: record offset
- on the uncompressed page,
- possibly ORed with
- PAGE_ZIP_DIR_SLOT_DEL or
- PAGE_ZIP_DIR_SLOT_OWNED */
- const page_zip_des_t* page_zip, /* in: compressed page */
- ulint slot) /* in: slot
+ const page_zip_des_t* page_zip, /*!< in: compressed page */
+ ulint slot) /*!< in: slot
(0=first user record) */
{
ut_ad(page_zip_simple_validate(page_zip));
@@ -251,20 +262,23 @@ page_zip_dir_get(
- PAGE_ZIP_DIR_SLOT_SIZE * (slot + 1)));
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Write a log record of compressing an index page. */
static
void
page_zip_compress_write_log(
/*========================*/
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page, /* in: uncompressed page */
- dict_index_t* index, /* in: index of the B-tree node */
- mtr_t* mtr) /* in: mini-transaction */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page, /*!< in: uncompressed page */
+ dict_index_t* index, /*!< in: index of the B-tree node */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
byte* log_ptr;
ulint trailer_size;
+ ut_ad(!dict_index_is_ibuf(index));
+
log_ptr = mlog_open(mtr, 11 + 2 + 2);
if (!log_ptr) {
@@ -312,19 +326,20 @@ page_zip_compress_write_log(
mlog_catenate_string(mtr, page_zip->data + page_zip_get_size(page_zip)
- trailer_size, trailer_size);
}
+#endif /* !UNIV_HOTBACKUP */
-/**********************************************************
+/******************************************************//**
Determine how many externally stored columns are contained
in existing records with smaller heap_no than rec. */
static
ulint
page_zip_get_n_prev_extern(
/*=======================*/
- const page_zip_des_t* page_zip,/* in: dense page directory on
+ const page_zip_des_t* page_zip,/*!< in: dense page directory on
compressed page */
- const rec_t* rec, /* in: compact physical record
+ const rec_t* rec, /*!< in: compact physical record
on a B-tree leaf page */
- dict_index_t* index) /* in: record descriptor */
+ dict_index_t* index) /*!< in: record descriptor */
{
const page_t* page = page_align(rec);
ulint n_ext = 0;
@@ -337,6 +352,7 @@ page_zip_get_n_prev_extern(
ut_ad(page_is_comp(page));
ut_ad(dict_table_is_comp(index->table));
ut_ad(dict_index_is_clust(index));
+ ut_ad(!dict_index_is_ibuf(index));
heap_no = rec_get_heap_no_new(rec);
ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
@@ -361,15 +377,15 @@ page_zip_get_n_prev_extern(
return(n_ext);
}
-/**************************************************************************
-Encode the length of a fixed-length column. */
+/**********************************************************************//**
+Encode the length of a fixed-length column.
+@return buf + length of encoded val */
static
byte*
page_zip_fixed_field_encode(
/*========================*/
- /* out: buf + length of encoded val */
- byte* buf, /* in: pointer to buffer where to write */
- ulint val) /* in: value to write */
+ byte* buf, /*!< in: pointer to buffer where to write */
+ ulint val) /*!< in: value to write */
{
ut_ad(val >= 2);
@@ -389,19 +405,19 @@ page_zip_fixed_field_encode(
return(buf);
}
-/**************************************************************************
-Write the index information for the compressed page. */
+/**********************************************************************//**
+Write the index information for the compressed page.
+@return used size of buf */
static
ulint
page_zip_fields_encode(
/*===================*/
- /* out: used size of buf */
- ulint n, /* in: number of fields to compress */
- dict_index_t* index, /* in: index comprising at least n fields */
- ulint trx_id_pos,/* in: position of the trx_id column
+ ulint n, /*!< in: number of fields to compress */
+ dict_index_t* index, /*!< in: index comprising at least n fields */
+ ulint trx_id_pos,/*!< in: position of the trx_id column
in the index, or ULINT_UNDEFINED if
this is a non-leaf page */
- byte* buf) /* out: buffer of (n + 1) * 2 bytes */
+ byte* buf) /*!< out: buffer of (n + 1) * 2 bytes */
{
const byte* buf_start = buf;
ulint i;
@@ -517,16 +533,16 @@ page_zip_fields_encode(
return((ulint) (buf - buf_start));
}
-/**************************************************************************
+/**********************************************************************//**
Populate the dense page directory from the sparse directory. */
static
void
page_zip_dir_encode(
/*================*/
- const page_t* page, /* in: compact page */
- byte* buf, /* in: pointer to dense page directory[-1];
+ const page_t* page, /*!< in: compact page */
+ byte* buf, /*!< in: pointer to dense page directory[-1];
out: dense directory on compressed page */
- const rec_t** recs) /* in: pointer to an array of 0, or NULL;
+ const rec_t** recs) /*!< in: pointer to an array of 0, or NULL;
out: dense page directory sorted by ascending
address (and heap_no) */
{
@@ -633,38 +649,38 @@ page_zip_dir_encode(
ut_a(i + PAGE_HEAP_NO_USER_LOW == n_heap);
}
-/**************************************************************************
+/**********************************************************************//**
Allocate memory for zlib. */
static
void*
page_zip_malloc(
/*============*/
- void* opaque,
- uInt items,
- uInt size)
+ void* opaque, /*!< in/out: memory heap */
+ uInt items, /*!< in: number of items to allocate */
+ uInt size) /*!< in: size of an item in bytes */
{
return(mem_heap_alloc(opaque, items * size));
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate memory for zlib. */
static
void
page_zip_free(
/*==========*/
- void* opaque __attribute__((unused)),
- void* address __attribute__((unused)))
+ void* opaque __attribute__((unused)), /*!< in: memory heap */
+ void* address __attribute__((unused)))/*!< in: object to free */
{
}
-/**************************************************************************
+/**********************************************************************//**
Configure the zlib allocator to use the given memory heap. */
UNIV_INTERN
void
page_zip_set_alloc(
/*===============*/
- void* stream, /* in/out: zlib stream */
- mem_heap_t* heap) /* in: memory heap to use */
+ void* stream, /*!< in/out: zlib stream */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
z_stream* strm = stream;
@@ -674,28 +690,30 @@ page_zip_set_alloc(
}
#if 0 || defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+/** Symbol for enabling compression and decompression diagnostics */
# define PAGE_ZIP_COMPRESS_DBG
#endif
#ifdef PAGE_ZIP_COMPRESS_DBG
-/* Set this variable in a debugger to enable
+/** Set this variable in a debugger to enable
excessive logging in page_zip_compress(). */
UNIV_INTERN ibool page_zip_compress_dbg;
-/* Set this variable in a debugger to enable
+/** Set this variable in a debugger to enable
binary logging of the data passed to deflate().
When this variable is nonzero, it will act
as a log file name generator. */
UNIV_INTERN unsigned page_zip_compress_log;
-/**************************************************************************
-Wrapper for deflate(). Log the operation if page_zip_compress_dbg is set. */
+/**********************************************************************//**
+Wrapper for deflate(). Log the operation if page_zip_compress_dbg is set.
+@return deflate() status: Z_OK, Z_BUF_ERROR, ... */
static
-ibool
+int
page_zip_compress_deflate(
/*======================*/
- FILE* logfile,/* in: log file, or NULL */
- z_streamp strm, /* in/out: compressed stream for deflate() */
- int flush) /* in: deflate() flushing method */
+ FILE* logfile,/*!< in: log file, or NULL */
+ z_streamp strm, /*!< in/out: compressed stream for deflate() */
+ int flush) /*!< in: deflate() flushing method */
{
int status;
if (UNIV_UNLIKELY(page_zip_compress_dbg)) {
@@ -713,29 +731,38 @@ page_zip_compress_deflate(
/* Redefine deflate(). */
# undef deflate
+/** Debug wrapper for the zlib compression routine deflate().
+Log the operation if page_zip_compress_dbg is set.
+@param strm in/out: compressed stream
+@param flush in: flushing method
+@return deflate() status: Z_OK, Z_BUF_ERROR, ... */
# define deflate(strm, flush) page_zip_compress_deflate(logfile, strm, flush)
+/** Declaration of the logfile parameter */
# define FILE_LOGFILE FILE* logfile,
+/** The logfile parameter */
# define LOGFILE logfile,
#else /* PAGE_ZIP_COMPRESS_DBG */
+/** Empty declaration of the logfile parameter */
# define FILE_LOGFILE
+/** Missing logfile parameter */
# define LOGFILE
#endif /* PAGE_ZIP_COMPRESS_DBG */
-/**************************************************************************
-Compress the records of a node pointer page. */
+/**********************************************************************//**
+Compress the records of a node pointer page.
+@return Z_OK, or a zlib error code */
static
int
page_zip_compress_node_ptrs(
/*========================*/
- /* out: Z_OK, or a zlib error code */
FILE_LOGFILE
- z_stream* c_stream, /* in/out: compressed page stream */
- const rec_t** recs, /* in: dense page directory
+ z_stream* c_stream, /*!< in/out: compressed page stream */
+ const rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense, /* in: size of recs[] */
- dict_index_t* index, /* in: the index of the page */
- byte* storage, /* in: end of dense page directory */
- mem_heap_t* heap) /* in: temporary memory heap */
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ byte* storage, /*!< in: end of dense page directory */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err = Z_OK;
ulint* offsets = NULL;
@@ -786,18 +813,18 @@ page_zip_compress_node_ptrs(
return(err);
}
-/**************************************************************************
-Compress the records of a leaf node of a secondary index. */
+/**********************************************************************//**
+Compress the records of a leaf node of a secondary index.
+@return Z_OK, or a zlib error code */
static
int
page_zip_compress_sec(
/*==================*/
- /* out: Z_OK, or a zlib error code */
FILE_LOGFILE
- z_stream* c_stream, /* in/out: compressed page stream */
- const rec_t** recs, /* in: dense page directory
+ z_stream* c_stream, /*!< in/out: compressed page stream */
+ const rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense) /* in: size of recs[] */
+ ulint n_dense) /*!< in: size of recs[] */
{
int err = Z_OK;
@@ -830,25 +857,25 @@ page_zip_compress_sec(
return(err);
}
-/**************************************************************************
+/**********************************************************************//**
Compress a record of a leaf node of a clustered index that contains
-externally stored columns. */
+externally stored columns.
+@return Z_OK, or a zlib error code */
static
int
page_zip_compress_clust_ext(
/*========================*/
- /* out: Z_OK, or a zlib error code */
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) */
- ulint trx_id_col, /* in: position of of DB_TRX_ID */
- byte* deleted, /* in: dense directory entry pointing
+ z_stream* c_stream, /*!< in/out: compressed page stream */
+ const rec_t* rec, /*!< in: record */
+ const ulint* 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 */
- byte* storage, /* in: end of dense page directory */
- byte** externs, /* in/out: pointer to the next
+ byte* storage, /*!< in: end of dense page directory */
+ byte** externs, /*!< in/out: pointer to the next
available BLOB pointer */
- ulint* n_blobs) /* in/out: number of
+ ulint* n_blobs) /*!< in/out: number of
externally stored columns */
{
int err;
@@ -958,26 +985,26 @@ page_zip_compress_clust_ext(
return(Z_OK);
}
-/**************************************************************************
-Compress the records of a leaf node of a clustered index. */
+/**********************************************************************//**
+Compress the records of a leaf node of a clustered index.
+@return Z_OK, or a zlib error code */
static
int
page_zip_compress_clust(
/*====================*/
- /* out: Z_OK, or a zlib error code */
FILE_LOGFILE
- z_stream* c_stream, /* in/out: compressed page stream */
- const rec_t** recs, /* in: dense page directory
+ z_stream* c_stream, /*!< in/out: compressed page stream */
+ const rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense, /* in: size of recs[] */
- dict_index_t* index, /* in: the index of the page */
- ulint* n_blobs, /* in: 0; out: number of
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint* n_blobs, /*!< in: 0; out: number of
externally stored columns */
- ulint trx_id_col, /* index of the trx_id column */
- byte* deleted, /* in: dense directory entry pointing
+ ulint trx_id_col, /*!< index of the trx_id column */
+ byte* deleted, /*!< in: dense directory entry pointing
to the head of the free list */
- byte* storage, /* in: end of dense page directory */
- mem_heap_t* heap) /* in: temporary memory heap */
+ byte* storage, /*!< in: end of dense page directory */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err = Z_OK;
ulint* offsets = NULL;
@@ -1091,35 +1118,37 @@ func_exit:
return(err);
}
-/**************************************************************************
-Compress a page. */
+/**********************************************************************//**
+Compress a page.
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure. */
UNIV_INTERN
ibool
page_zip_compress(
/*==============*/
- /* out: TRUE on success, FALSE on failure;
- page_zip will be left intact on failure. */
- page_zip_des_t* page_zip,/* in: size; out: data, n_blobs,
+ page_zip_des_t* page_zip,/*!< in: size; out: data, n_blobs,
m_start, m_end, m_nonempty */
- const page_t* page, /* in: uncompressed page */
- dict_index_t* index, /* in: index of the B-tree node */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ const page_t* page, /*!< in: uncompressed page */
+ dict_index_t* index, /*!< in: index of the B-tree node */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
{
z_stream c_stream;
int err;
ulint n_fields;/* number of index fields needed */
- byte* fields; /* index field information */
- byte* buf; /* compressed payload of the page */
+ byte* fields; /*!< index field information */
+ byte* buf; /*!< compressed payload of the page */
byte* buf_end;/* end of buf */
ulint n_dense;
ulint slot_size;/* amount of uncompressed bytes per record */
- const rec_t** recs; /* dense page directory, sorted by address */
+ const rec_t** recs; /*!< dense page directory, sorted by address */
mem_heap_t* heap;
ulint trx_id_col;
ulint* offsets = NULL;
ulint n_blobs = 0;
byte* storage;/* storage of uncompressed columns */
+#ifndef UNIV_HOTBACKUP
ullint usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
#ifdef PAGE_ZIP_COMPRESS_DBG
FILE* logfile = NULL;
#endif
@@ -1128,6 +1157,8 @@ page_zip_compress(
ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
ut_ad(page_simple_validate_new((page_t*) page));
ut_ad(page_zip_simple_validate(page_zip));
+ ut_ad(dict_table_is_comp(index->table));
+ ut_ad(!dict_index_is_ibuf(index));
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
@@ -1181,7 +1212,9 @@ page_zip_compress(
}
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
page_zip_stat[page_zip->ssize - 1].compressed++;
+#endif /* !UNIV_HOTBACKUP */
if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
>= page_zip_get_size(page_zip))) {
@@ -1318,8 +1351,10 @@ err_exit:
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
page_zip_stat[page_zip->ssize - 1].compressed_usec
+= ut_time_us(NULL) - usec;
+#endif /* !UNIV_HOTBACKUP */
return(FALSE);
}
@@ -1360,7 +1395,9 @@ err_exit:
#endif /* UNIV_ZIP_DEBUG */
if (mtr) {
+#ifndef UNIV_HOTBACKUP
page_zip_compress_write_log(page_zip, page, index, mtr);
+#endif /* !UNIV_HOTBACKUP */
}
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
@@ -1375,51 +1412,53 @@ err_exit:
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
{
page_zip_stat_t* zip_stat
= &page_zip_stat[page_zip->ssize - 1];
zip_stat->compressed_ok++;
zip_stat->compressed_usec += ut_time_us(NULL) - usec;
}
+#endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
-/**************************************************************************
-Compare two page directory entries. */
+/**********************************************************************//**
+Compare two page directory entries.
+@return positive if rec1 > rec2 */
UNIV_INLINE
ibool
page_zip_dir_cmp(
/*=============*/
- /* out: positive if rec1 > rec2 */
- const rec_t* rec1, /* in: rec1 */
- const rec_t* rec2) /* in: rec2 */
+ const rec_t* rec1, /*!< in: rec1 */
+ const rec_t* rec2) /*!< in: rec2 */
{
return(rec1 > rec2);
}
-/**************************************************************************
+/**********************************************************************//**
Sort the dense page directory by address (heap_no). */
static
void
page_zip_dir_sort(
/*==============*/
- rec_t** arr, /* in/out: dense page directory */
- rec_t** aux_arr,/* in/out: work area */
- ulint low, /* in: lower bound of the sorting area, inclusive */
- ulint high) /* in: upper bound of the sorting area, exclusive */
+ rec_t** arr, /*!< in/out: dense page directory */
+ rec_t** aux_arr,/*!< in/out: work area */
+ ulint low, /*!< in: lower bound of the sorting area, inclusive */
+ ulint high) /*!< in: upper bound of the sorting area, exclusive */
{
UT_SORT_FUNCTION_BODY(page_zip_dir_sort, arr, aux_arr, low, high,
page_zip_dir_cmp);
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate the index information initialized by page_zip_fields_decode(). */
static
void
page_zip_fields_free(
/*=================*/
- dict_index_t* index) /* in: dummy index to be freed */
+ dict_index_t* index) /*!< in: dummy index to be freed */
{
if (index) {
dict_table_t* table = index->table;
@@ -1429,17 +1468,16 @@ page_zip_fields_free(
}
}
-/**************************************************************************
-Read the index information for the compressed page. */
+/**********************************************************************//**
+Read the index information for the compressed page.
+@return own: dummy index describing the page, or NULL on error */
static
dict_index_t*
page_zip_fields_decode(
/*===================*/
- /* out,own: dummy index describing the page,
- or NULL on error */
- const byte* buf, /* in: index information */
- const byte* end, /* in: end of buf */
- ulint* trx_id_col)/* in: NULL for non-leaf pages;
+ const byte* buf, /*!< in: index information */
+ const byte* end, /*!< in: end of buf */
+ ulint* trx_id_col)/*!< in: NULL for non-leaf pages;
for leaf pages, pointer to where to store
the position of the trx_id column */
{
@@ -1546,23 +1584,22 @@ page_zip_fields_decode(
return(index);
}
-/**************************************************************************
-Populate the sparse page directory from the dense directory. */
+/**********************************************************************//**
+Populate the sparse page directory from the dense directory.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_dir_decode(
/*================*/
- /* out: TRUE on success,
- FALSE on failure */
- const page_zip_des_t* page_zip,/* in: dense page directory on
+ const page_zip_des_t* page_zip,/*!< in: dense page directory on
compressed page */
- page_t* page, /* in: compact page with valid header;
+ page_t* page, /*!< in: compact page with valid header;
out: trailer and sparse page directory
filled in */
- rec_t** recs, /* out: dense page directory sorted by
+ rec_t** recs, /*!< out: dense page directory sorted by
ascending address (and heap_no) */
- rec_t** recs_aux,/* in/out: scratch area */
- ulint n_dense)/* in: number of user records, and
+ rec_t** recs_aux,/*!< in/out: scratch area */
+ ulint n_dense)/*!< in: number of user records, and
size of recs[] and recs_aux[] */
{
ulint i;
@@ -1644,17 +1681,16 @@ page_zip_dir_decode(
return(TRUE);
}
-/**************************************************************************
-Initialize the REC_N_NEW_EXTRA_BYTES of each record. */
+/**********************************************************************//**
+Initialize the REC_N_NEW_EXTRA_BYTES of each record.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_set_extra_bytes(
/*=====================*/
- /* out: TRUE on success,
- FALSE on failure */
- const page_zip_des_t* page_zip,/* in: compressed page */
- page_t* page, /* in/out: uncompressed page */
- ulint info_bits)/* in: REC_INFO_MIN_REC_FLAG or 0 */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ page_t* page, /*!< in/out: uncompressed page */
+ ulint info_bits)/*!< in: REC_INFO_MIN_REC_FLAG or 0 */
{
ulint n;
ulint i;
@@ -1742,20 +1778,19 @@ page_zip_set_extra_bytes(
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Apply the modification log to a record containing externally stored
-columns. Do not copy the fields that are stored separately. */
+columns. Do not copy the fields that are stored separately.
+@return pointer to modification log, or NULL on failure */
static
const byte*
page_zip_apply_log_ext(
/*===================*/
- /* out: pointer to modification log,
- or NULL on failure */
- rec_t* rec, /* in/out: record */
- const ulint* 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 */
+ rec_t* rec, /*!< in/out: record */
+ const ulint* 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 */
{
ulint i;
ulint len;
@@ -1832,28 +1867,27 @@ page_zip_apply_log_ext(
return(data);
}
-/**************************************************************************
+/**********************************************************************//**
Apply the modification log to an uncompressed page.
-Do not copy the fields that are stored separately. */
+Do not copy the fields that are stored separately.
+@return pointer to end of modification log, or NULL on failure */
static
const byte*
page_zip_apply_log(
/*===============*/
- /* out: pointer to end of modification log,
- or NULL on failure */
- const byte* data, /* in: modification log */
- ulint size, /* in: maximum length of the log, in bytes */
- rec_t** recs, /* in: dense page directory,
+ const byte* data, /*!< in: modification log */
+ ulint size, /*!< in: maximum length of the log, in bytes */
+ rec_t** recs, /*!< in: dense page directory,
sorted by address (indexed by
heap_no - PAGE_HEAP_NO_USER_LOW) */
- ulint n_dense,/* in: size of recs[] */
- ulint trx_id_col,/* in: column number of trx_id in the index,
+ ulint n_dense,/*!< in: size of recs[] */
+ ulint trx_id_col,/*!< in: column number of trx_id in the index,
or ULINT_UNDEFINED if none */
ulint heap_status,
- /* in: heap_no and status bits for
+ /*!< 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
+ dict_index_t* index, /*!< in: index of the page */
+ ulint* offsets)/*!< in/out: work area for
rec_get_offsets_reverse() */
{
const byte* const end = data + size;
@@ -2034,22 +2068,21 @@ page_zip_apply_log(
}
}
-/**************************************************************************
-Decompress the records of a node pointer page. */
+/**********************************************************************//**
+Decompress the records of a node pointer page.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_decompress_node_ptrs(
/*==========================*/
- /* out: TRUE on success,
- FALSE on failure */
- page_zip_des_t* page_zip, /* in/out: compressed page */
- z_stream* d_stream, /* in/out: compressed page stream */
- rec_t** recs, /* in: dense page directory
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ z_stream* d_stream, /*!< in/out: compressed page stream */
+ rec_t** recs, /*!< in: dense page directory
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 */
- mem_heap_t* heap) /* in: temporary memory heap */
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint* offsets, /*!< in/out: temporary offsets */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
ulint heap_status = REC_STATUS_NODE_PTR
| PAGE_HEAP_NO_USER_LOW << REC_HEAP_NO_SHIFT;
@@ -2228,21 +2261,20 @@ zlib_done:
return(TRUE);
}
-/**************************************************************************
-Decompress the records of a leaf node of a secondary index. */
+/**********************************************************************//**
+Decompress the records of a leaf node of a secondary index.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_decompress_sec(
/*====================*/
- /* out: TRUE on success,
- FALSE on failure */
- page_zip_des_t* page_zip, /* in/out: compressed page */
- z_stream* d_stream, /* in/out: compressed page stream */
- rec_t** recs, /* in: dense page directory
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ z_stream* d_stream, /*!< in/out: compressed page stream */
+ rec_t** recs, /*!< in: dense page directory
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 */
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint* offsets) /*!< in/out: temporary offsets */
{
ulint heap_status = REC_STATUS_ORDINARY
| PAGE_HEAP_NO_USER_LOW << REC_HEAP_NO_SHIFT;
@@ -2370,18 +2402,18 @@ zlib_done:
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Decompress a record of a leaf node of a clustered index that contains
-externally stored columns. */
+externally stored columns.
+@return TRUE on success */
static
ibool
page_zip_decompress_clust_ext(
/*==========================*/
- /* out: TRUE on success */
- z_stream* d_stream, /* in/out: compressed page stream */
- rec_t* rec, /* in/out: record */
- const ulint* offsets, /* in: rec_get_offsets(rec) */
- ulint trx_id_col) /* in: position of of DB_TRX_ID */
+ z_stream* d_stream, /*!< in/out: compressed page stream */
+ rec_t* rec, /*!< in/out: record */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ ulint trx_id_col) /*!< in: position of of DB_TRX_ID */
{
ulint i;
@@ -2479,23 +2511,22 @@ page_zip_decompress_clust_ext(
return(TRUE);
}
-/**************************************************************************
-Compress the records of a leaf node of a clustered index. */
+/**********************************************************************//**
+Compress the records of a leaf node of a clustered index.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_decompress_clust(
/*======================*/
- /* out: TRUE on success,
- FALSE on failure */
- page_zip_des_t* page_zip, /* in/out: compressed page */
- z_stream* d_stream, /* in/out: compressed page stream */
- rec_t** recs, /* in: dense page directory
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ z_stream* d_stream, /*!< in/out: compressed page stream */
+ rec_t** recs, /*!< in: dense page directory
sorted by address */
- 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 */
- mem_heap_t* heap) /* in: temporary memory heap */
+ 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 */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err;
ulint slot;
@@ -2779,27 +2810,33 @@ zlib_done:
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Decompress a page. This function should tolerate errors on the compressed
page. Instead of letting assertions fail, it will return FALSE if an
-inconsistency is detected. */
+inconsistency is detected.
+@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
page_zip_decompress(
/*================*/
- /* out: TRUE on success, FALSE on failure */
- page_zip_des_t* page_zip,/* in: data, ssize;
+ page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
- page_t* page) /* out: uncompressed page, may be trashed */
+ page_t* page, /*!< out: uncompressed page, may be trashed */
+ ibool all) /*!< in: TRUE=decompress the whole page;
+ FALSE=verify but do not copy some
+ page header fields that should not change
+ after page creation */
{
z_stream d_stream;
dict_index_t* index = NULL;
- rec_t** recs; /* dense page directory, sorted by address */
+ rec_t** recs; /*!< dense page directory, sorted by address */
ulint n_dense;/* number of user records on the page */
ulint trx_id_col = ULINT_UNDEFINED;
mem_heap_t* heap;
ulint* offsets;
+#ifndef UNIV_HOTBACKUP
ullint usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
@@ -2818,13 +2855,36 @@ page_zip_decompress(
heap = mem_heap_create(n_dense * (3 * sizeof *recs) + UNIV_PAGE_SIZE);
recs = mem_heap_alloc(heap, n_dense * (2 * sizeof *recs));
+ if (all) {
+ /* Copy the page header. */
+ memcpy(page, page_zip->data, PAGE_DATA);
+ } else {
+ /* Check that the bytes that we skip are identical. */
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ ut_a(!memcmp(FIL_PAGE_TYPE + page,
+ FIL_PAGE_TYPE + page_zip->data,
+ PAGE_HEADER - FIL_PAGE_TYPE));
+ ut_a(!memcmp(PAGE_HEADER + PAGE_LEVEL + page,
+ PAGE_HEADER + PAGE_LEVEL + page_zip->data,
+ PAGE_DATA - (PAGE_HEADER + PAGE_LEVEL)));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+
+ /* Copy the mutable parts of the page header. */
+ memcpy(page, page_zip->data, FIL_PAGE_TYPE);
+ memcpy(PAGE_HEADER + page, PAGE_HEADER + page_zip->data,
+ PAGE_LEVEL - PAGE_N_DIR_SLOTS);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ /* Check that the page headers match after copying. */
+ ut_a(!memcmp(page, page_zip->data, PAGE_DATA));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+ }
+
#ifdef UNIV_ZIP_DEBUG
- /* Clear the page. */
- memset(page, 0x55, UNIV_PAGE_SIZE);
+ /* Clear the uncompressed page, except the header. */
+ memset(PAGE_DATA + page, 0x55, UNIV_PAGE_SIZE - PAGE_DATA);
#endif /* UNIV_ZIP_DEBUG */
- UNIV_MEM_INVALID(page, UNIV_PAGE_SIZE);
- /* Copy the page header. */
- memcpy(page, page_zip->data, PAGE_DATA);
+ UNIV_MEM_INVALID(PAGE_DATA + page, UNIV_PAGE_SIZE - PAGE_DATA);
/* Copy the page directory. */
if (UNIV_UNLIKELY(!page_zip_dir_decode(page_zip, page, recs,
@@ -2955,12 +3015,14 @@ err_exit:
page_zip_fields_free(index);
mem_heap_free(heap);
+#ifndef UNIV_HOTBACKUP
{
page_zip_stat_t* zip_stat
= &page_zip_stat[page_zip->ssize - 1];
zip_stat->decompressed++;
zip_stat->decompressed_usec += ut_time_us(NULL) - usec;
}
+#endif /* !UNIV_HOTBACKUP */
/* Update the stat counter for LRU policy. */
buf_LRU_stat_inc_unzip();
@@ -2969,15 +3031,15 @@ err_exit:
}
#ifdef UNIV_ZIP_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Dump a block of memory on the standard error stream. */
static
void
page_zip_hexdump_func(
/*==================*/
- const char* name, /* in: name of the data structure */
- const void* buf, /* in: data */
- ulint size) /* in: length of the data, in bytes */
+ const char* name, /*!< in: name of the data structure */
+ const void* buf, /*!< in: data */
+ ulint size) /*!< in: length of the data, in bytes */
{
const byte* s = buf;
ulint addr;
@@ -3000,21 +3062,24 @@ page_zip_hexdump_func(
}
}
+/** Dump a block of memory on the standard error stream.
+@param buf in: data
+@param size in: length of the data, in bytes */
#define page_zip_hexdump(buf, size) page_zip_hexdump_func(#buf, buf, size)
-/* Flag: make page_zip_validate() compare page headers only */
+/** Flag: make page_zip_validate() compare page headers only */
UNIV_INTERN ibool page_zip_validate_header_only = FALSE;
-/**************************************************************************
-Check that the compressed and decompressed pages match. */
+/**********************************************************************//**
+Check that the compressed and decompressed pages match.
+@return TRUE if valid, FALSE if not */
UNIV_INTERN
ibool
page_zip_validate_low(
/*==================*/
- /* out: TRUE if valid, FALSE if not */
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page, /* in: uncompressed page */
- ibool sloppy) /* in: FALSE=strict,
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page, /*!< in: uncompressed page */
+ ibool sloppy) /*!< in: FALSE=strict,
TRUE=ignore the MIN_REC_FLAG */
{
page_zip_des_t temp_page_zip;
@@ -3060,7 +3125,7 @@ page_zip_validate_low(
#endif /* UNIV_DEBUG_VALGRIND */
temp_page_zip = *page_zip;
- valid = page_zip_decompress(&temp_page_zip, temp_page);
+ valid = page_zip_decompress(&temp_page_zip, temp_page, TRUE);
if (!valid) {
fputs("page_zip_validate(): failed to decompress\n", stderr);
goto func_exit;
@@ -3142,15 +3207,15 @@ func_exit:
return(valid);
}
-/**************************************************************************
-Check that the compressed and decompressed pages match. */
+/**********************************************************************//**
+Check that the compressed and decompressed pages match.
+@return TRUE if valid, FALSE if not */
UNIV_INTERN
ibool
page_zip_validate(
/*==============*/
- /* out: TRUE if valid, FALSE if not */
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page) /* in: uncompressed page */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page) /*!< in: uncompressed page */
{
return(page_zip_validate_low(page_zip, page,
recv_recovery_is_on()));
@@ -3158,13 +3223,15 @@ page_zip_validate(
#endif /* UNIV_ZIP_DEBUG */
#ifdef UNIV_DEBUG
+/**********************************************************************//**
+Assert that the compressed and decompressed page headers match.
+@return TRUE */
static
ibool
page_zip_header_cmp(
/*================*/
- /* out: TRUE */
- const page_zip_des_t* page_zip,/* in: compressed page */
- const byte* page) /* in: uncompressed page */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const byte* page) /*!< in: uncompressed page */
{
ut_ad(!memcmp(page_zip->data + FIL_PAGE_PREV, page + FIL_PAGE_PREV,
FIL_PAGE_LSN - FIL_PAGE_PREV));
@@ -3177,24 +3244,24 @@ page_zip_header_cmp(
}
#endif /* UNIV_DEBUG */
-/**************************************************************************
+/**********************************************************************//**
Write a record on the compressed page that contains externally stored
-columns. The data must already have been written to the uncompressed page. */
+columns. The data must already have been written to the uncompressed page.
+@return end of modification log */
static
byte*
page_zip_write_rec_ext(
/*===================*/
- /* out: end of modification log */
- page_zip_des_t* page_zip, /* in/out: compressed page */
- 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) */
- 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 */
- byte* storage, /* in: end of dense page directory */
- byte* data) /* in: end of modification log */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ 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) */
+ 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 */
+ byte* storage, /*!< in: end of dense page directory */
+ byte* data) /*!< in: end of modification log */
{
const byte* start = rec;
ulint i;
@@ -3299,18 +3366,18 @@ page_zip_write_rec_ext(
return(data);
}
-/**************************************************************************
+/**********************************************************************//**
Write an entire record on the compressed page. The data must already
have been written to the uncompressed page. */
UNIV_INTERN
void
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) */
- ulint create) /* in: nonzero=insert, zero=update */
+ 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) */
+ ulint create) /*!< in: nonzero=insert, zero=update */
{
const page_t* page;
byte* data;
@@ -3318,7 +3385,7 @@ page_zip_write_rec(
ulint heap_no;
byte* slot;
- ut_ad(buf_frame_get_page_zip(rec) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
> PAGE_DATA + page_zip_dir_size(page_zip));
@@ -3487,17 +3554,17 @@ page_zip_write_rec(
#endif /* UNIV_ZIP_DEBUG */
}
-/***************************************************************
-Parses a log record of writing a BLOB pointer of a record. */
+/***********************************************************//**
+Parses a log record of writing a BLOB pointer of a record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_blob_ptr(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip)/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< in/out: compressed page */
{
ulint offset;
ulint z_offset;
@@ -3546,20 +3613,20 @@ corrupt:
return(ptr + (2 + 2 + BTR_EXTERN_FIELD_REF_SIZE));
}
-/**************************************************************************
+/**********************************************************************//**
Write a BLOB pointer of a record on the leaf page of a clustered index.
The information must already have been updated on the uncompressed page. */
UNIV_INTERN
void
page_zip_write_blob_ptr(
/*====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in/out: record whose data is being
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ 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) */
- ulint n, /* in: column index */
- mtr_t* mtr) /* in: mini-transaction handle,
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* 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 */
{
const byte* field;
@@ -3568,7 +3635,7 @@ page_zip_write_blob_ptr(
ulint blob_no;
ulint len;
- ut_ad(buf_frame_get_page_zip(rec) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_simple_validate_new((page_t*) page));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
@@ -3610,6 +3677,7 @@ page_zip_write_blob_ptr(
#endif /* UNIV_ZIP_DEBUG */
if (mtr) {
+#ifndef UNIV_HOTBACKUP
byte* log_ptr = mlog_open(
mtr, 11 + 2 + 2 + BTR_EXTERN_FIELD_REF_SIZE);
if (UNIV_UNLIKELY(!log_ptr)) {
@@ -3625,20 +3693,21 @@ page_zip_write_blob_ptr(
memcpy(log_ptr, externs, BTR_EXTERN_FIELD_REF_SIZE);
log_ptr += BTR_EXTERN_FIELD_REF_SIZE;
mlog_close(mtr, log_ptr);
+#endif /* !UNIV_HOTBACKUP */
}
}
-/***************************************************************
-Parses a log record of writing the node pointer of a record. */
+/***********************************************************//**
+Parses a log record of writing the node pointer of a record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_node_ptr(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip)/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< in/out: compressed page */
{
ulint offset;
ulint z_offset;
@@ -3705,23 +3774,23 @@ corrupt:
return(ptr + (2 + 2 + REC_NODE_PTR_SIZE));
}
-/**************************************************************************
+/**********************************************************************//**
Write the node pointer of a record on a non-leaf compressed page. */
UNIV_INTERN
void
page_zip_write_node_ptr(
/*====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in/out: record */
- ulint size, /* in: data size of rec */
- ulint ptr, /* in: node pointer */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in/out: record */
+ ulint size, /*!< in: data size of rec */
+ ulint ptr, /*!< in: node pointer */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
{
byte* field;
byte* storage;
page_t* page = page_align(rec);
- ut_ad(buf_frame_get_page_zip(rec) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_simple_validate_new(page));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
@@ -3752,6 +3821,7 @@ page_zip_write_node_ptr(
memcpy(storage, field, REC_NODE_PTR_SIZE);
if (mtr) {
+#ifndef UNIV_HOTBACKUP
byte* log_ptr = mlog_open(mtr,
11 + 2 + 2 + REC_NODE_PTR_SIZE);
if (UNIV_UNLIKELY(!log_ptr)) {
@@ -3767,28 +3837,29 @@ page_zip_write_node_ptr(
memcpy(log_ptr, field, REC_NODE_PTR_SIZE);
log_ptr += REC_NODE_PTR_SIZE;
mlog_close(mtr, log_ptr);
+#endif /* !UNIV_HOTBACKUP */
}
}
-/**************************************************************************
+/**********************************************************************//**
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
UNIV_INTERN
void
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) */
- ulint trx_id_col,/* in: column number of TRX_ID in rec */
- dulint trx_id, /* in: transaction identifier */
- dulint roll_ptr)/* in: 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) */
+ 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 */
{
byte* field;
byte* storage;
page_t* page = page_align(rec);
ulint len;
- ut_ad(buf_frame_get_page_zip(rec) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_simple_validate_new(page));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
@@ -3837,7 +3908,7 @@ page_zip_write_trx_id_and_roll_ptr(
}
#ifdef UNIV_ZIP_DEBUG
-/* Set this variable in a debugger to disable page_zip_clear_rec().
+/** Set this variable in a debugger to disable page_zip_clear_rec().
The only observable effect should be the compression ratio due to
deleted records not being zeroed out. In rare cases, there can be
page_zip_validate() failures on the node_ptr, trx_id and roll_ptr
@@ -3845,16 +3916,16 @@ columns if the space is reallocated for a smaller record. */
UNIV_INTERN ibool page_zip_clear_rec_disable;
#endif /* UNIV_ZIP_DEBUG */
-/**************************************************************************
+/**********************************************************************//**
Clear an area on the uncompressed and compressed page, if possible. */
static
void
page_zip_clear_rec(
/*===============*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in: record to clear */
- dict_index_t* index, /* in: index of rec */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in: record to clear */
+ dict_index_t* index, /*!< in: index of rec */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint heap_no;
page_t* page = page_align(rec);
@@ -3951,16 +4022,16 @@ page_zip_clear_rec(
#endif /* UNIV_ZIP_DEBUG */
}
-/**************************************************************************
+/**********************************************************************//**
Write the "deleted" flag of a record on a compressed page. The flag must
already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_deleted(
/*=====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the deleted flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */
{
byte* slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
@@ -3975,16 +4046,16 @@ page_zip_rec_set_deleted(
#endif /* UNIV_ZIP_DEBUG */
}
-/**************************************************************************
+/**********************************************************************//**
Write the "owned" flag of a record on a compressed page. The n_owned field
must already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_owned(
/*===================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the owned flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the owned flag (nonzero=TRUE) */
{
byte* slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
@@ -3996,17 +4067,17 @@ page_zip_rec_set_owned(
}
}
-/**************************************************************************
+/**********************************************************************//**
Insert a record to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_insert(
/*================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* prev_rec,/* in: record after which to insert */
- const byte* free_rec,/* in: record from which rec was
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* prev_rec,/*!< in: record after which to insert */
+ const byte* free_rec,/*!< in: record from which rec was
allocated, or NULL */
- byte* rec) /* in: record to insert */
+ byte* rec) /*!< in: record to insert */
{
ulint n_dense;
byte* slot_rec;
@@ -4074,18 +4145,18 @@ page_zip_dir_insert(
mach_write_to_2(slot_rec - PAGE_ZIP_DIR_SLOT_SIZE, page_offset(rec));
}
-/**************************************************************************
+/**********************************************************************//**
Shift the dense page directory and the array of BLOB pointers
when a record is deleted. */
UNIV_INTERN
void
page_zip_dir_delete(
/*================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in: record to delete */
- dict_index_t* index, /* in: index of rec */
- const ulint* offsets,/* in: rec_get_offsets(rec) */
- const byte* free) /* in: previous start of the free list */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in: record to delete */
+ dict_index_t* index, /*!< in: index of rec */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec) */
+ const byte* free) /*!< in: previous start of the free list */
{
byte* slot_rec;
byte* slot_free;
@@ -4172,14 +4243,14 @@ skip_blobs:
page_zip_clear_rec(page_zip, rec, index, offsets);
}
-/**************************************************************************
+/**********************************************************************//**
Add a slot to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_add_slot(
/*==================*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint is_clustered) /* in: nonzero for clustered index,
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint is_clustered) /*!< in: nonzero for clustered index,
zero for others */
{
ulint n_dense;
@@ -4228,17 +4299,17 @@ page_zip_dir_add_slot(
memmove(stored - PAGE_ZIP_DIR_SLOT_SIZE, stored, dir - stored);
}
-/***************************************************************
-Parses a log record of writing to the header of a page. */
+/***********************************************************//**
+Parses a log record of writing to the header of a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_header(
/*========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip)/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< in/out: compressed page */
{
ulint offset;
ulint len;
@@ -4286,15 +4357,16 @@ corrupt:
return(ptr + len);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Write a log record of writing to the uncompressed header portion of a page. */
UNIV_INTERN
void
page_zip_write_header_log(
/*======================*/
- const byte* data, /* in: data on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr) /* in: mini-transaction */
+ const byte* data, /*!< in: data on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
byte* log_ptr = mlog_open(mtr, 11 + 1 + 1);
ulint offset = page_offset(data);
@@ -4320,8 +4392,9 @@ page_zip_write_header_log(
mlog_catenate_string(mtr, data, length);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Reorganize and compress a page. This is a low-level operation for
compressed pages, to be used when page_zip_compress() fails.
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.
@@ -4329,20 +4402,19 @@ The function btr_page_reorganize() should be preferred whenever possible.
IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
-will be redo-logged. */
+will be redo-logged.
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure, but page will be overwritten. */
UNIV_INTERN
ibool
page_zip_reorganize(
/*================*/
- /* out: TRUE on success, FALSE on failure;
- page and page_zip will be left intact
- on failure. */
- buf_block_t* block, /* in/out: page with compressed page;
+ buf_block_t* block, /*!< in/out: page with compressed page;
on the compressed page, in: size;
out: data, n_blobs,
m_start, m_end, m_nonempty */
- dict_index_t* index, /* in: index of the B-tree node */
- mtr_t* mtr) /* in: mini-transaction */
+ dict_index_t* index, /*!< in: index of the B-tree node */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
page_t* page = buf_block_get_frame(block);
@@ -4352,6 +4424,7 @@ page_zip_reorganize(
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_is_comp(page));
+ ut_ad(!dict_index_is_ibuf(index));
/* Note that page_zip_validate(page_zip, page) may fail here. */
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
@@ -4359,10 +4432,15 @@ page_zip_reorganize(
/* Disable logging */
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
+#ifndef UNIV_HOTBACKUP
temp_block = buf_block_alloc(0);
- temp_page = temp_block->frame;
-
btr_search_drop_page_hash_index(block);
+ block->check_index_page_at_flush = TRUE;
+#else /* !UNIV_HOTBACKUP */
+ ut_ad(block == back_block1);
+ temp_block = back_block2;
+#endif /* !UNIV_HOTBACKUP */
+ temp_page = temp_block->frame;
/* Copy the old page to temporary space */
buf_frame_copy(temp_page, page);
@@ -4371,7 +4449,6 @@ page_zip_reorganize(
segment headers, next page-field, etc.) is preserved intact */
page_create(block, mtr, TRUE);
- block->check_index_page_at_flush = TRUE;
/* Copy the records from the temporary space to the recreated page;
do not copy the lock bits yet */
@@ -4379,28 +4456,35 @@ page_zip_reorganize(
page_copy_rec_list_end_no_locks(block, temp_block,
page_get_infimum_rec(temp_page),
index, mtr);
- /* Copy max trx id to recreated page */
- page_set_max_trx_id(block, NULL, page_get_max_trx_id(temp_page));
+
+ if (!dict_index_is_clust(index) && page_is_leaf(temp_page)) {
+ /* Copy max trx id to recreated page */
+ trx_id_t max_trx_id = page_get_max_trx_id(temp_page);
+ page_set_max_trx_id(block, NULL, max_trx_id, NULL);
+ ut_ad(!ut_dulint_is_zero(max_trx_id));
+ }
/* Restore logging. */
mtr_set_log_mode(mtr, log_mode);
if (UNIV_UNLIKELY(!page_zip_compress(page_zip, page, index, mtr))) {
- /* Restore the old page and exit. */
- buf_frame_copy(page, temp_page);
-
+#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
+#endif /* !UNIV_HOTBACKUP */
return(FALSE);
}
lock_move_reorganize_page(block, temp_block);
+#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
+#endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Copy the records of a page byte for byte. Do not copy the page header
or trailer, except those B-tree header fields that are directly
related to the storage of records. Also copy PAGE_MAX_TRX_ID.
@@ -4409,17 +4493,18 @@ UNIV_INTERN
void
page_zip_copy_recs(
/*===============*/
- page_zip_des_t* page_zip, /* out: copy of src_zip
+ page_zip_des_t* page_zip, /*!< out: copy of src_zip
(n_blobs, m_start, m_end,
m_nonempty, data[0..size-1]) */
- page_t* page, /* out: copy of src */
- const page_zip_des_t* src_zip, /* in: compressed page */
- const page_t* src, /* in: page */
- dict_index_t* index, /* in: index of the B-tree */
- mtr_t* mtr) /* in: mini-transaction */
+ page_t* page, /*!< out: copy of src */
+ const page_zip_des_t* src_zip, /*!< in: compressed page */
+ const page_t* src, /*!< in: page */
+ dict_index_t* index, /*!< in: index of the B-tree */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
ut_ad(mtr_memo_contains_page(mtr, (page_t*) src, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(!dict_index_is_ibuf(index));
#ifdef UNIV_ZIP_DEBUG
/* The B-tree operations that call this function may set
FIL_PAGE_PREV or PAGE_LEVEL, causing a temporary min_rec_flag
@@ -4433,6 +4518,11 @@ page_zip_copy_recs(
ut_a(dict_index_is_clust(index));
}
+ /* The PAGE_MAX_TRX_ID must be set on leaf pages of secondary
+ indexes. It does not matter on other pages. */
+ ut_a(dict_index_is_clust(index) || !page_is_leaf(src)
+ || !ut_dulint_is_zero(page_get_max_trx_id(src)));
+
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);
@@ -4486,18 +4576,19 @@ page_zip_copy_recs(
page_zip_compress_write_log(page_zip, page, index, mtr);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Parses a log record of compressing an index page. */
+/**********************************************************************//**
+Parses a log record of compressing an index page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_compress(
/*====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* out: uncompressed page */
- page_zip_des_t* page_zip)/* out: compressed page */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< out: compressed page */
{
ulint size;
ulint trailer_size;
@@ -4538,7 +4629,8 @@ corrupt:
memcpy(page_zip->data + page_zip_get_size(page_zip)
- trailer_size, ptr + 8 + size, trailer_size);
- if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page))) {
+ if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page,
+ TRUE))) {
goto corrupt;
}
@@ -4547,15 +4639,15 @@ corrupt:
return(ptr + 8 + size + trailer_size);
}
-/**************************************************************************
-Calculate the compressed page checksum. */
+/**********************************************************************//**
+Calculate the compressed page checksum.
+@return page checksum */
UNIV_INTERN
ulint
page_zip_calc_checksum(
/*===================*/
- /* out: page checksum */
- const void* data, /* in: compressed page */
- ulint size) /* in: size of compressed page */
+ const void* data, /*!< in: compressed page */
+ ulint size) /*!< in: size of compressed page */
{
/* Exclude FIL_PAGE_SPACE_OR_CHKSUM, FIL_PAGE_LSN,
and FIL_PAGE_FILE_FLUSH_LSN from the checksum. */
diff --git a/storage/xtradb/pars/lexyy.c b/storage/xtradb/pars/lexyy.c
index 489752a1900..fc6b5102581 100644
--- a/storage/xtradb/pars/lexyy.c
+++ b/storage/xtradb/pars/lexyy.c
@@ -703,7 +703,7 @@ static int yy_flex_debug = 0;
#define YY_RESTORE_YY_MORE_OFFSET
static char *yytext;
#line 1 "pars0lex.l"
-/******************************************************
+/**************************************************//**
SQL parser lexical analyzer: input file for the GNU Flex lexer generator
(c) 1997 Innobase Oy
@@ -747,13 +747,13 @@ Linux.
static ulint stringbuf_len_alloc = 0; /* Allocated length */
static ulint stringbuf_len = 0; /* Current length */
static char* stringbuf; /* Start of buffer */
-/* Appends a string to the buffer. */
+/** Appends a string to the buffer. */
static
void
string_append(
/*==========*/
- const char* str, /* in: string to be appended */
- ulint len) /* in: length of the string */
+ const char* str, /*!< in: string to be appended */
+ ulint len) /*!< in: length of the string */
{
if (stringbuf == NULL) {
stringbuf = malloc(1);
@@ -2778,3 +2778,18 @@ static void yyfree (void * ptr )
+
+/**********************************************************************
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void)
+/*==================*/
+{
+ if (yy_buffer_stack)
+ yylex_destroy();
+ if (stringbuf)
+ free(stringbuf);
+ stringbuf = NULL;
+ stringbuf_len_alloc = stringbuf_len = 0;
+}
diff --git a/storage/xtradb/pars/pars0lex.l b/storage/xtradb/pars/pars0lex.l
index 38cb744bd44..7bd39f7514b 100644
--- a/storage/xtradb/pars/pars0lex.l
+++ b/storage/xtradb/pars/pars0lex.l
@@ -70,13 +70,13 @@ Created 12/14/1997 Heikki Tuuri
static ulint stringbuf_len_alloc = 0; /* Allocated length */
static ulint stringbuf_len = 0; /* Current length */
static char* stringbuf; /* Start of buffer */
-/* Appends a string to the buffer. */
+/** Appends a string to the buffer. */
static
void
string_append(
/*==========*/
- const char* str, /* in: string to be appended */
- ulint len) /* in: length of the string */
+ const char* str, /*!< in: string to be appended */
+ ulint len) /*!< in: length of the string */
{
if (stringbuf == NULL) {
stringbuf = malloc(1);
@@ -661,3 +661,18 @@ In the state 'id', only two actions are possible (defined below). */
}
%%
+
+/**********************************************************************
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void)
+/*==================*/
+{
+ if (yy_buffer_stack)
+ yylex_destroy();
+ if (stringbuf)
+ free(stringbuf);
+ stringbuf = NULL;
+ stringbuf_len_alloc = stringbuf_len = 0;
+}
diff --git a/storage/xtradb/pars/pars0opt.c b/storage/xtradb/pars/pars0opt.c
index 34246929c53..2e392ba4836 100644
--- a/storage/xtradb/pars/pars0opt.c
+++ b/storage/xtradb/pars/pars0opt.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file pars/pars0opt.c
Simple SQL optimizer
Created 12/21/1997 Heikki Tuuri
@@ -47,15 +48,14 @@ Created 12/21/1997 Heikki Tuuri
#define OPT_SCROLL_COND 4
-/***********************************************************************
-Inverts a comparison operator. */
+/*******************************************************************//**
+Inverts a comparison operator.
+@return the equivalent operator when the order of the arguments is switched */
static
int
opt_invert_cmp_op(
/*==============*/
- /* out: the equivalent operator when the order of
- the arguments is switched */
- int op) /* in: operator */
+ int op) /*!< in: operator */
{
if (op == '<') {
return('>');
@@ -74,18 +74,18 @@ opt_invert_cmp_op(
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if the value of an expression can be calculated BEFORE the nth table
in a join is accessed. If this is the case, it can possibly be used in an
-index search for the nth table. */
+index search for the nth table.
+@return TRUE if already determined */
static
ibool
opt_check_exp_determined_before(
/*============================*/
- /* out: TRUE if already determined */
- que_node_t* exp, /* in: expression */
- sel_node_t* sel_node, /* in: select node */
- ulint nth_table) /* in: nth table will be accessed */
+ que_node_t* exp, /*!< in: expression */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint nth_table) /*!< in: nth table will be accessed */
{
func_node_t* func_node;
sym_node_t* sym_node;
@@ -134,24 +134,22 @@ opt_check_exp_determined_before(
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Looks in a comparison condition if a column value is already restricted by
-it BEFORE the nth table is accessed. */
+it BEFORE the nth table is accessed.
+@return expression restricting the value of the column, or NULL if not known */
static
que_node_t*
opt_look_for_col_in_comparison_before(
/*==================================*/
- /* out: expression restricting the
- value of the column, or NULL if not
- known */
- ulint cmp_type, /* in: OPT_EQUAL, OPT_COMPARISON */
- ulint col_no, /* in: column number */
- func_node_t* search_cond, /* in: comparison condition */
- sel_node_t* sel_node, /* in: select node */
- ulint nth_table, /* in: nth table in a join (a query
+ ulint cmp_type, /*!< in: OPT_EQUAL, OPT_COMPARISON */
+ ulint col_no, /*!< in: column number */
+ func_node_t* search_cond, /*!< in: comparison condition */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint nth_table, /*!< in: nth table in a join (a query
from a single table is considered a
join of 1 table) */
- ulint* op) /* out: comparison operator ('=',
+ ulint* op) /*!< out: comparison operator ('=',
PARS_GE_TOKEN, ... ); this is inverted
if the column appears on the right
side */
@@ -231,26 +229,24 @@ opt_look_for_col_in_comparison_before(
return(NULL);
}
-/***********************************************************************
+/*******************************************************************//**
Looks in a search condition if a column value is already restricted by the
search condition BEFORE the nth table is accessed. Takes into account that
if we will fetch in an ascending order, we cannot utilize an upper limit for
-a column value; in a descending order, respectively, a lower limit. */
+a column value; in a descending order, respectively, a lower limit.
+@return expression restricting the value of the column, or NULL if not known */
static
que_node_t*
opt_look_for_col_in_cond_before(
/*============================*/
- /* out: expression restricting the
- value of the column, or NULL if not
- known */
- ulint cmp_type, /* in: OPT_EQUAL, OPT_COMPARISON */
- ulint col_no, /* in: column number */
- func_node_t* search_cond, /* in: search condition or NULL */
- sel_node_t* sel_node, /* in: select node */
- ulint nth_table, /* in: nth table in a join (a query
+ ulint cmp_type, /*!< in: OPT_EQUAL, OPT_COMPARISON */
+ ulint col_no, /*!< in: column number */
+ func_node_t* search_cond, /*!< in: search condition or NULL */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint nth_table, /*!< in: nth table in a join (a query
from a single table is considered a
join of 1 table) */
- ulint* op) /* out: comparison operator ('=',
+ ulint* op) /*!< out: comparison operator ('=',
PARS_GE_TOKEN, ... ) */
{
func_node_t* new_cond;
@@ -309,24 +305,24 @@ opt_look_for_col_in_cond_before(
return(exp);
}
-/***********************************************************************
+/*******************************************************************//**
Calculates the goodness for an index according to a select node. The
goodness is 4 times the number of first fields in index whose values we
already know exactly in the query. If we have a comparison condition for
an additional field, 2 point are added. If the index is unique, and we know
all the unique fields for the index we add 1024 points. For a clustered index
-we add 1 point. */
+we add 1 point.
+@return goodness */
static
ulint
opt_calc_index_goodness(
/*====================*/
- /* out: goodness */
- dict_index_t* index, /* in: index */
- sel_node_t* sel_node, /* in: parsed select node */
- ulint nth_table, /* in: nth table in a join */
- que_node_t** index_plan, /* in/out: comparison expressions for
+ dict_index_t* index, /*!< in: index */
+ sel_node_t* sel_node, /*!< in: parsed select node */
+ ulint nth_table, /*!< in: nth table in a join */
+ que_node_t** index_plan, /*!< in/out: comparison expressions for
this index */
- ulint* last_op) /* out: last comparison operator, if
+ ulint* last_op) /*!< out: last comparison operator, if
goodness > 1 */
{
que_node_t* exp;
@@ -393,30 +389,29 @@ opt_calc_index_goodness(
return(goodness);
}
-/***********************************************************************
-Calculates the number of matched fields based on an index goodness. */
+/*******************************************************************//**
+Calculates the number of matched fields based on an index goodness.
+@return number of excatly or partially matched fields */
UNIV_INLINE
ulint
opt_calc_n_fields_from_goodness(
/*============================*/
- /* out: number of excatly or partially matched
- fields */
- ulint goodness) /* in: goodness */
+ ulint goodness) /*!< in: goodness */
{
return(((goodness % 1024) + 2) / 4);
}
-/***********************************************************************
+/*******************************************************************//**
Converts a comparison operator to the corresponding search mode PAGE_CUR_GE,
-... */
+...
+@return search mode */
UNIV_INLINE
ulint
opt_op_to_search_mode(
/*==================*/
- /* out: search mode */
- ibool asc, /* in: TRUE if the rows should be fetched in an
+ ibool asc, /*!< in: TRUE if the rows should be fetched in an
ascending order */
- ulint op) /* in: operator '=', PARS_GE_TOKEN, ... */
+ ulint op) /*!< in: operator '=', PARS_GE_TOKEN, ... */
{
if (op == '=') {
if (asc) {
@@ -443,15 +438,15 @@ opt_op_to_search_mode(
return(0);
}
-/***********************************************************************
-Determines if a node is an argument node of a function node. */
+/*******************************************************************//**
+Determines if a node is an argument node of a function node.
+@return TRUE if is an argument */
static
ibool
opt_is_arg(
/*=======*/
- /* out: TRUE if is an argument */
- que_node_t* arg_node, /* in: possible argument node */
- func_node_t* func_node) /* in: function node */
+ que_node_t* arg_node, /*!< in: possible argument node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg;
@@ -469,7 +464,7 @@ opt_is_arg(
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Decides if the fetching of rows should be made in a descending order, and
also checks that the chosen query plan produces a result which satisfies
the order-by. */
@@ -477,7 +472,7 @@ static
void
opt_check_order_by(
/*===============*/
- sel_node_t* sel_node) /* in: select node; asserts an error
+ sel_node_t* sel_node) /*!< in: select node; asserts an error
if the plan does not agree with the
order-by */
{
@@ -521,7 +516,7 @@ opt_check_order_by(
}
}
-/***********************************************************************
+/*******************************************************************//**
Optimizes a select. Decides which indexes to tables to use. The tables
are accessed in the order that they were written to the FROM part in the
select statement. */
@@ -529,9 +524,9 @@ static
void
opt_search_plan_for_table(
/*======================*/
- sel_node_t* sel_node, /* in: parsed select node */
- ulint i, /* in: this is the ith table */
- dict_table_t* table) /* in: table */
+ sel_node_t* sel_node, /*!< in: parsed select node */
+ ulint i, /*!< in: this is the ith table */
+ dict_table_t* table) /*!< in: table */
{
plan_t* plan;
dict_index_t* index;
@@ -617,22 +612,19 @@ opt_search_plan_for_table(
btr_pcur_init(&(plan->clust_pcur));
}
-/***********************************************************************
+/*******************************************************************//**
Looks at a comparison condition and decides if it can, and need, be tested for
-a table AFTER the table has been accessed. */
+a table AFTER the table has been accessed.
+@return OPT_NOT_COND if not for this table, else OPT_END_COND,
+OPT_TEST_COND, or OPT_SCROLL_COND, where the last means that the
+condition need not be tested, except when scroll cursors are used */
static
ulint
opt_classify_comparison(
/*====================*/
- /* out: OPT_NOT_COND if not for this
- table, else OPT_END_COND,
- OPT_TEST_COND, or OPT_SCROLL_COND,
- where the last means that the
- condition need not be tested, except
- when scroll cursors are used */
- sel_node_t* sel_node, /* in: select node */
- ulint i, /* in: ith table in the join */
- func_node_t* cond) /* in: comparison condition */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i, /*!< in: ith table in the join */
+ func_node_t* cond) /*!< in: comparison condition */
{
plan_t* plan;
ulint n_fields;
@@ -713,15 +705,15 @@ opt_classify_comparison(
return(OPT_TEST_COND);
}
-/***********************************************************************
+/*******************************************************************//**
Recursively looks for test conditions for a table in a join. */
static
void
opt_find_test_conds(
/*================*/
- sel_node_t* sel_node, /* in: select node */
- ulint i, /* in: ith table in the join */
- func_node_t* cond) /* in: conjunction of search
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i, /*!< in: ith table in the join */
+ func_node_t* cond) /*!< in: conjunction of search
conditions or NULL */
{
func_node_t* new_cond;
@@ -758,7 +750,7 @@ opt_find_test_conds(
}
}
-/***********************************************************************
+/*******************************************************************//**
Normalizes a list of comparison conditions so that a column of the table
appears on the left side of the comparison if possible. This is accomplished
by switching the arguments of the operator. */
@@ -766,9 +758,9 @@ static
void
opt_normalize_cmp_conds(
/*====================*/
- func_node_t* cond, /* in: first in a list of comparison
+ func_node_t* cond, /*!< in: first in a list of comparison
conditions, or NULL */
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -800,7 +792,7 @@ opt_normalize_cmp_conds(
}
}
-/***********************************************************************
+/*******************************************************************//**
Finds out the search condition conjuncts we can, and need, to test as the ith
table in a join is accessed. The search tuple can eliminate the need to test
some conjuncts. */
@@ -808,8 +800,8 @@ static
void
opt_determine_and_normalize_test_conds(
/*===================================*/
- sel_node_t* sel_node, /* in: select node */
- ulint i) /* in: ith table in the join */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i) /*!< in: ith table in the join */
{
plan_t* plan;
@@ -828,7 +820,7 @@ opt_determine_and_normalize_test_conds(
ut_a(UT_LIST_GET_LEN(plan->end_conds) >= plan->n_exact_match);
}
-/***********************************************************************
+/*******************************************************************//**
Looks for occurrences of the columns of the table in the query subgraph and
adds them to the list of columns if an occurrence of the same column does not
already exist in the list. If the column is already in the list, puts a value
@@ -839,13 +831,13 @@ UNIV_INTERN
void
opt_find_all_cols(
/*==============*/
- ibool copy_val, /* in: if TRUE, new found columns are
+ ibool copy_val, /*!< in: if TRUE, new found columns are
added as columns to copy */
- dict_index_t* index, /* in: index of the table to use */
- sym_node_list_t* col_list, /* in: base node of a list where
+ dict_index_t* index, /*!< in: index of the table to use */
+ sym_node_list_t* col_list, /*!< in: base node of a list where
to add new found columns */
- plan_t* plan, /* in: plan or NULL */
- que_node_t* exp) /* in: expression or condition or
+ plan_t* plan, /*!< in: plan or NULL */
+ que_node_t* exp) /*!< in: expression or condition or
NULL */
{
func_node_t* func_node;
@@ -937,7 +929,7 @@ opt_find_all_cols(
}
}
-/***********************************************************************
+/*******************************************************************//**
Looks for occurrences of the columns of the table in conditions which are
not yet determined AFTER the join operation has fetched a row in the ith
table. The values for these column must be copied to dynamic memory for
@@ -946,9 +938,9 @@ static
void
opt_find_copy_cols(
/*===============*/
- sel_node_t* sel_node, /* in: select node */
- ulint i, /* in: ith table in the join */
- func_node_t* search_cond) /* in: search condition or NULL */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i, /*!< in: ith table in the join */
+ func_node_t* search_cond) /*!< in: search condition or NULL */
{
func_node_t* new_cond;
plan_t* plan;
@@ -985,7 +977,7 @@ opt_find_copy_cols(
}
}
-/***********************************************************************
+/*******************************************************************//**
Classifies the table columns according to whether we use the column only while
holding the latch on the page, or whether we have to copy the column value to
dynamic memory. Puts the first occurrence of a column to either list in the
@@ -994,8 +986,8 @@ static
void
opt_classify_cols(
/*==============*/
- sel_node_t* sel_node, /* in: select node */
- ulint i) /* in: ith table in the join */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i) /*!< in: ith table in the join */
{
plan_t* plan;
que_node_t* exp;
@@ -1029,15 +1021,15 @@ opt_classify_cols(
sel_node->search_cond);
}
-/***********************************************************************
+/*******************************************************************//**
Fills in the info in plan which is used in accessing a clustered index
record. The columns must already be classified for the plan node. */
static
void
opt_clust_access(
/*=============*/
- sel_node_t* sel_node, /* in: select node */
- ulint n) /* in: nth table in select */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint n) /*!< in: nth table in select */
{
plan_t* plan;
dict_table_t* table;
@@ -1101,7 +1093,7 @@ opt_clust_access(
}
}
-/***********************************************************************
+/*******************************************************************//**
Optimizes a select. Decides which indexes to tables to use. The tables
are accessed in the order that they were written to the FROM part in the
select statement. */
@@ -1109,7 +1101,7 @@ UNIV_INTERN
void
opt_search_plan(
/*============*/
- sel_node_t* sel_node) /* in: parsed select node */
+ sel_node_t* sel_node) /*!< in: parsed select node */
{
sym_node_t* table_node;
dict_table_t* table;
@@ -1176,13 +1168,13 @@ opt_search_plan(
#endif
}
-/************************************************************************
+/********************************************************************//**
Prints info of a query plan. */
UNIV_INTERN
void
opt_print_query_plan(
/*=================*/
- sel_node_t* sel_node) /* in: select node */
+ sel_node_t* sel_node) /*!< in: select node */
{
plan_t* plan;
ulint n_fields;
diff --git a/storage/xtradb/pars/pars0pars.c b/storage/xtradb/pars/pars0pars.c
index 62ae3b3d09b..9faf36d00a8 100644
--- a/storage/xtradb/pars/pars0pars.c
+++ b/storage/xtradb/pars/pars0pars.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file pars/pars0pars.c
SQL parser
Created 11/19/1996 Heikki Tuuri
@@ -48,10 +49,9 @@ on 1/27/1998 */
#include "eval0eval.h"
#ifdef UNIV_SQL_DEBUG
-/* If the following is set TRUE, the lexer will print the SQL string
+/** If the following is set TRUE, the lexer will print the SQL string
as it tokenizes it */
-
-ibool pars_print_lexed = FALSE;
+UNIV_INTERN ibool pars_print_lexed = FALSE;
#endif /* UNIV_SQL_DEBUG */
/* Global variable used while parsing a single procedure or query : the code is
@@ -92,19 +92,18 @@ UNIV_INTERN pars_res_word_t pars_share_token = {PARS_SHARE_TOKEN};
UNIV_INTERN pars_res_word_t pars_unique_token = {PARS_UNIQUE_TOKEN};
UNIV_INTERN pars_res_word_t pars_clustered_token = {PARS_CLUSTERED_TOKEN};
-/* Global variable used to denote the '*' in SELECT * FROM.. */
-#define PARS_STAR_DENOTER 12345678
-UNIV_INTERN ulint pars_star_denoter = PARS_STAR_DENOTER;
+/** Global variable used to denote the '*' in SELECT * FROM.. */
+UNIV_INTERN ulint pars_star_denoter = 12345678;
-/*************************************************************************
-Determines the class of a function code. */
+/*********************************************************************//**
+Determines the class of a function code.
+@return function class: PARS_FUNC_ARITH, ... */
static
ulint
pars_func_get_class(
/*================*/
- /* out: function class: PARS_FUNC_ARITH, ... */
- int func) /* in: function code: '=', PARS_GE_TOKEN, ... */
+ int func) /*!< in: function code: '=', PARS_GE_TOKEN, ... */
{
switch (func) {
case '+': case '-': case '*': case '/':
@@ -142,15 +141,15 @@ pars_func_get_class(
}
}
-/*************************************************************************
-Parses an operator or predefined function expression. */
+/*********************************************************************//**
+Parses an operator or predefined function expression.
+@return own: function node in a query tree */
static
func_node_t*
pars_func_low(
/*==========*/
- /* out, own: function node in a query tree */
- int func, /* in: function token code */
- que_node_t* arg) /* in: first argument in the argument list */
+ int func, /*!< in: function token code */
+ que_node_t* arg) /*!< in: first argument in the argument list */
{
func_node_t* node;
@@ -171,29 +170,29 @@ pars_func_low(
return(node);
}
-/*************************************************************************
-Parses a function expression. */
+/*********************************************************************//**
+Parses a function expression.
+@return own: function node in a query tree */
UNIV_INTERN
func_node_t*
pars_func(
/*======*/
- /* out, own: function node in a query tree */
- que_node_t* res_word,/* in: function name reserved word */
- que_node_t* arg) /* in: first argument in the argument list */
+ que_node_t* res_word,/*!< in: function name reserved word */
+ que_node_t* arg) /*!< in: first argument in the argument list */
{
return(pars_func_low(((pars_res_word_t*)res_word)->code, arg));
}
-/*************************************************************************
-Parses an operator expression. */
+/*********************************************************************//**
+Parses an operator expression.
+@return own: function node in a query tree */
UNIV_INTERN
func_node_t*
pars_op(
/*====*/
- /* out, own: function node in a query tree */
- int func, /* in: operator token code */
- que_node_t* arg1, /* in: first argument */
- que_node_t* arg2) /* in: second argument or NULL for an unary
+ int func, /*!< in: operator token code */
+ que_node_t* arg1, /*!< in: first argument */
+ que_node_t* arg2) /*!< in: second argument or NULL for an unary
operator */
{
que_node_list_add_last(NULL, arg1);
@@ -205,15 +204,15 @@ pars_op(
return(pars_func_low(func, arg1));
}
-/*************************************************************************
-Parses an ORDER BY clause. Order by a single column only is supported. */
+/*********************************************************************//**
+Parses an ORDER BY clause. Order by a single column only is supported.
+@return own: order-by node in a query tree */
UNIV_INTERN
order_node_t*
pars_order_by(
/*==========*/
- /* out, own: order-by node in a query tree */
- sym_node_t* column, /* in: column name */
- pars_res_word_t* asc) /* in: &pars_asc_token or pars_desc_token */
+ sym_node_t* column, /*!< in: column name */
+ pars_res_word_t* asc) /*!< in: &pars_asc_token or pars_desc_token */
{
order_node_t* node;
@@ -233,15 +232,15 @@ pars_order_by(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Determine if a data type is a built-in string data type of the InnoDB
-SQL parser. */
+SQL parser.
+@return TRUE if string data type */
static
ibool
pars_is_string_type(
/*================*/
- /* out: TRUE if string data type */
- ulint mtype) /* in: main data type */
+ ulint mtype) /*!< in: main data type */
{
switch (mtype) {
case DATA_VARCHAR: case DATA_CHAR:
@@ -252,14 +251,14 @@ pars_is_string_type(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the data type of a function in an expression. The argument data
types must already be resolved. */
static
void
pars_resolve_func_data_type(
/*========================*/
- func_node_t* node) /* in: function node */
+ func_node_t* node) /*!< in: function node */
{
que_node_t* arg;
@@ -345,18 +344,18 @@ pars_resolve_func_data_type(
}
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the meaning of variables in an expression and the data types of
functions. It is an error if some identifier cannot be resolved here. */
static
void
pars_resolve_exp_variables_and_types(
/*=================================*/
- sel_node_t* select_node, /* in: select node or NULL; if
+ sel_node_t* select_node, /*!< in: select node or NULL; if
this is not NULL then the variable
sym nodes are added to the
copy_variables list of select_node */
- que_node_t* exp_node) /* in: expression */
+ que_node_t* exp_node) /*!< in: expression */
{
func_node_t* func_node;
que_node_t* arg;
@@ -435,7 +434,7 @@ pars_resolve_exp_variables_and_types(
que_node_get_data_type(node));
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the meaning of variables in an expression list. It is an error if
some identifier cannot be resolved here. Resolves also the data types of
functions. */
@@ -443,8 +442,8 @@ static
void
pars_resolve_exp_list_variables_and_types(
/*======================================*/
- sel_node_t* select_node, /* in: select node or NULL */
- que_node_t* exp_node) /* in: expression list first node, or
+ sel_node_t* select_node, /*!< in: select node or NULL */
+ que_node_t* exp_node) /*!< in: expression list first node, or
NULL */
{
while (exp_node) {
@@ -454,14 +453,14 @@ pars_resolve_exp_list_variables_and_types(
}
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the columns in an expression. */
static
void
pars_resolve_exp_columns(
/*=====================*/
- sym_node_t* table_node, /* in: first node in a table list */
- que_node_t* exp_node) /* in: expression */
+ sym_node_t* table_node, /*!< in: first node in a table list */
+ que_node_t* exp_node) /*!< in: expression */
{
func_node_t* func_node;
que_node_t* arg;
@@ -535,14 +534,14 @@ pars_resolve_exp_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the meaning of columns in an expression list. */
static
void
pars_resolve_exp_list_columns(
/*==========================*/
- sym_node_t* table_node, /* in: first node in a table list */
- que_node_t* exp_node) /* in: expression list first node, or
+ sym_node_t* table_node, /*!< in: first node in a table list */
+ que_node_t* exp_node) /*!< in: expression list first node, or
NULL */
{
while (exp_node) {
@@ -552,13 +551,13 @@ pars_resolve_exp_list_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Retrieves the table definition for a table name id. */
static
void
pars_retrieve_table_def(
/*====================*/
- sym_node_t* sym_node) /* in: table node */
+ sym_node_t* sym_node) /*!< in: table node */
{
const char* table_name;
@@ -575,14 +574,14 @@ pars_retrieve_table_def(
ut_a(sym_node->table);
}
-/*************************************************************************
-Retrieves the table definitions for a list of table name ids. */
+/*********************************************************************//**
+Retrieves the table definitions for a list of table name ids.
+@return number of tables */
static
ulint
pars_retrieve_table_list_defs(
/*==========================*/
- /* out: number of tables */
- sym_node_t* sym_node) /* in: first table node in list */
+ sym_node_t* sym_node) /*!< in: first table node in list */
{
ulint count = 0;
@@ -602,13 +601,13 @@ pars_retrieve_table_list_defs(
return(count);
}
-/*************************************************************************
+/*********************************************************************//**
Adds all columns to the select list if the query is SELECT * FROM ... */
static
void
pars_select_all_columns(
/*====================*/
- sel_node_t* select_node) /* in: select node already containing
+ sel_node_t* select_node) /*!< in: select node already containing
the table list */
{
sym_node_t* col_node;
@@ -639,17 +638,16 @@ pars_select_all_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Parses a select list; creates a query graph node for the whole SELECT
-statement. */
+statement.
+@return own: select node in a query tree */
UNIV_INTERN
sel_node_t*
pars_select_list(
/*=============*/
- /* out, own: select node in a query
- tree */
- que_node_t* select_list, /* in: select list */
- sym_node_t* into_list) /* in: variables list or NULL */
+ que_node_t* select_list, /*!< in: select list */
+ sym_node_t* into_list) /*!< in: variables list or NULL */
{
sel_node_t* node;
@@ -663,14 +661,14 @@ pars_select_list(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if the query is an aggregate query, in which case the selct list must
contain only aggregate function items. */
static
void
pars_check_aggregate(
/*=================*/
- sel_node_t* select_node) /* in: select node already containing
+ sel_node_t* select_node) /*!< in: select node already containing
the select list */
{
que_node_t* exp_node;
@@ -706,21 +704,20 @@ pars_check_aggregate(
}
}
-/*************************************************************************
-Parses a select statement. */
+/*********************************************************************//**
+Parses a select statement.
+@return own: select node in a query tree */
UNIV_INTERN
sel_node_t*
pars_select_statement(
/*==================*/
- /* out, own: select node in a query
- tree */
- sel_node_t* select_node, /* in: select node already containing
+ sel_node_t* select_node, /*!< in: select node already containing
the select list */
- sym_node_t* table_list, /* in: table list */
- que_node_t* search_cond, /* in: search condition or NULL */
- pars_res_word_t* for_update, /* in: NULL or &pars_update_token */
- pars_res_word_t* lock_shared, /* in: NULL or &pars_share_token */
- order_node_t* order_by) /* in: NULL or an order-by node */
+ sym_node_t* table_list, /*!< in: table list */
+ que_node_t* search_cond, /*!< in: search condition or NULL */
+ pars_res_word_t* for_update, /*!< in: NULL or &pars_update_token */
+ pars_res_word_t* lock_shared, /*!< in: NULL or &pars_share_token */
+ order_node_t* order_by) /*!< in: NULL or an order-by node */
{
select_node->state = SEL_NODE_OPEN;
@@ -790,16 +787,16 @@ pars_select_statement(
return(select_node);
}
-/*************************************************************************
-Parses a cursor declaration. */
+/*********************************************************************//**
+Parses a cursor declaration.
+@return sym_node */
UNIV_INTERN
que_node_t*
pars_cursor_declaration(
/*====================*/
- /* out: sym_node */
- sym_node_t* sym_node, /* in: cursor id node in the symbol
+ sym_node_t* sym_node, /*!< in: cursor id node in the symbol
table */
- sel_node_t* select_node) /* in: select node */
+ sel_node_t* select_node) /*!< in: select node */
{
sym_node->resolved = TRUE;
sym_node->token_type = SYM_CURSOR;
@@ -811,14 +808,14 @@ pars_cursor_declaration(
return(sym_node);
}
-/*************************************************************************
-Parses a function declaration. */
+/*********************************************************************//**
+Parses a function declaration.
+@return sym_node */
UNIV_INTERN
que_node_t*
pars_function_declaration(
/*======================*/
- /* out: sym_node */
- sym_node_t* sym_node) /* in: function id node in the symbol
+ sym_node_t* sym_node) /*!< in: function id node in the symbol
table */
{
sym_node->resolved = TRUE;
@@ -831,17 +828,16 @@ pars_function_declaration(
return(sym_node);
}
-/*************************************************************************
-Parses a delete or update statement start. */
+/*********************************************************************//**
+Parses a delete or update statement start.
+@return own: update node in a query tree */
UNIV_INTERN
upd_node_t*
pars_update_statement_start(
/*========================*/
- /* out, own: update node in a query
- tree */
- ibool is_delete, /* in: TRUE if delete */
- sym_node_t* table_sym, /* in: table name node */
- col_assign_node_t* col_assign_list)/* in: column assignment list, NULL
+ ibool is_delete, /*!< in: TRUE if delete */
+ sym_node_t* table_sym, /*!< in: table name node */
+ col_assign_node_t* col_assign_list)/*!< in: column assignment list, NULL
if delete */
{
upd_node_t* node;
@@ -856,15 +852,15 @@ pars_update_statement_start(
return(node);
}
-/*************************************************************************
-Parses a column assignment in an update. */
+/*********************************************************************//**
+Parses a column assignment in an update.
+@return column assignment node */
UNIV_INTERN
col_assign_node_t*
pars_column_assignment(
/*===================*/
- /* out: column assignment node */
- sym_node_t* column, /* in: column to assign */
- que_node_t* exp) /* in: value to assign */
+ sym_node_t* column, /*!< in: column to assign */
+ que_node_t* exp) /*!< in: value to assign */
{
col_assign_node_t* node;
@@ -878,13 +874,13 @@ pars_column_assignment(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Processes an update node assignment list. */
static
void
pars_process_assign_list(
/*=====================*/
- upd_node_t* node) /* in: update node */
+ upd_node_t* node) /*!< in: update node */
{
col_assign_node_t* col_assign_list;
sym_node_t* table_sym;
@@ -945,7 +941,8 @@ pars_process_assign_list(
if (!dict_col_get_fixed_size(
dict_index_get_nth_col(clust_index,
- upd_field->field_no))) {
+ upd_field->field_no),
+ dict_table_is_comp(node->table))) {
changes_field_size = 0;
}
@@ -964,18 +961,17 @@ pars_process_assign_list(
node->cmpl_info = changes_ord_field | changes_field_size;
}
-/*************************************************************************
-Parses an update or delete statement. */
+/*********************************************************************//**
+Parses an update or delete statement.
+@return own: update node in a query tree */
UNIV_INTERN
upd_node_t*
pars_update_statement(
/*==================*/
- /* out, own: update node in a query
- tree */
- upd_node_t* node, /* in: update node */
- sym_node_t* cursor_sym, /* in: pointer to a cursor entry in
+ upd_node_t* node, /*!< in: update node */
+ sym_node_t* cursor_sym, /*!< in: pointer to a cursor entry in
the symbol table or NULL */
- que_node_t* search_cond) /* in: search condition or NULL */
+ que_node_t* search_cond) /*!< in: search condition or NULL */
{
sym_node_t* table_sym;
sel_node_t* sel_node;
@@ -1051,17 +1047,16 @@ pars_update_statement(
return(node);
}
-/*************************************************************************
-Parses an insert statement. */
+/*********************************************************************//**
+Parses an insert statement.
+@return own: update node in a query tree */
UNIV_INTERN
ins_node_t*
pars_insert_statement(
/*==================*/
- /* out, own: update node in a query
- tree */
- sym_node_t* table_sym, /* in: table name node */
- que_node_t* values_list, /* in: value expression list or NULL */
- sel_node_t* select) /* in: select condition or NULL */
+ sym_node_t* table_sym, /*!< in: table name node */
+ que_node_t* values_list, /*!< in: value expression list or NULL */
+ sel_node_t* select) /*!< in: select condition or NULL */
{
ins_node_t* node;
dtuple_t* row;
@@ -1109,19 +1104,19 @@ pars_insert_statement(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Set the type of a dfield. */
static
void
pars_set_dfield_type(
/*=================*/
- dfield_t* dfield, /* in: dfield */
- pars_res_word_t* type, /* in: pointer to a type
+ dfield_t* dfield, /*!< in: dfield */
+ 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
+ ulint len, /*!< in: length, or 0 */
+ ibool is_unsigned, /*!< in: if TRUE, column is
UNSIGNED. */
- ibool is_not_null) /* in: if TRUE, column is
+ ibool is_not_null) /*!< in: if TRUE, column is
NOT NULL. */
{
ulint flags = 0;
@@ -1159,17 +1154,16 @@ pars_set_dfield_type(
}
}
-/*************************************************************************
-Parses a variable declaration. */
+/*********************************************************************//**
+Parses a variable declaration.
+@return own: symbol table node of type SYM_VAR */
UNIV_INTERN
sym_node_t*
pars_variable_declaration(
/*======================*/
- /* out, own: symbol table node of type
- SYM_VAR */
- sym_node_t* node, /* in: symbol table node allocated for the
+ sym_node_t* node, /*!< in: symbol table node allocated for the
id of the variable */
- pars_res_word_t* type) /* in: pointer to a type token */
+ pars_res_word_t* type) /*!< in: pointer to a type token */
{
node->resolved = TRUE;
node->token_type = SYM_VAR;
@@ -1181,19 +1175,18 @@ pars_variable_declaration(
return(node);
}
-/*************************************************************************
-Parses a procedure parameter declaration. */
+/*********************************************************************//**
+Parses a procedure parameter declaration.
+@return own: symbol table node of type SYM_VAR */
UNIV_INTERN
sym_node_t*
pars_parameter_declaration(
/*=======================*/
- /* out, own: symbol table node of type
- SYM_VAR */
- sym_node_t* node, /* in: symbol table node allocated for the
+ 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 */
+ /*!< 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));
@@ -1204,14 +1197,14 @@ pars_parameter_declaration(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the parent field in a query node list. */
static
void
pars_set_parent_in_list(
/*====================*/
- que_node_t* node_list, /* in: first node in a list */
- que_node_t* parent) /* in: parent value to set in all
+ que_node_t* node_list, /*!< in: first node in a list */
+ que_node_t* parent) /*!< in: parent value to set in all
nodes of the list */
{
que_common_t* common;
@@ -1225,15 +1218,15 @@ pars_set_parent_in_list(
}
}
-/*************************************************************************
-Parses an elsif element. */
+/*********************************************************************//**
+Parses an elsif element.
+@return elsif node */
UNIV_INTERN
elsif_node_t*
pars_elsif_element(
/*===============*/
- /* out: elsif node */
- que_node_t* cond, /* in: if-condition */
- que_node_t* stat_list) /* in: statement list */
+ que_node_t* cond, /*!< in: if-condition */
+ que_node_t* stat_list) /*!< in: statement list */
{
elsif_node_t* node;
@@ -1250,16 +1243,16 @@ pars_elsif_element(
return(node);
}
-/*************************************************************************
-Parses an if-statement. */
+/*********************************************************************//**
+Parses an if-statement.
+@return if-statement node */
UNIV_INTERN
if_node_t*
pars_if_statement(
/*==============*/
- /* out: if-statement node */
- que_node_t* cond, /* in: if-condition */
- que_node_t* stat_list, /* in: statement list */
- que_node_t* else_part) /* in: else-part statement list
+ que_node_t* cond, /*!< in: if-condition */
+ que_node_t* stat_list, /*!< in: statement list */
+ que_node_t* else_part) /*!< in: else-part statement list
or elsif element list */
{
if_node_t* node;
@@ -1301,15 +1294,15 @@ pars_if_statement(
return(node);
}
-/*************************************************************************
-Parses a while-statement. */
+/*********************************************************************//**
+Parses a while-statement.
+@return while-statement node */
UNIV_INTERN
while_node_t*
pars_while_statement(
/*=================*/
- /* out: while-statement node */
- que_node_t* cond, /* in: while-condition */
- que_node_t* stat_list) /* in: statement list */
+ que_node_t* cond, /*!< in: while-condition */
+ que_node_t* stat_list) /*!< in: statement list */
{
while_node_t* node;
@@ -1328,17 +1321,17 @@ pars_while_statement(
return(node);
}
-/*************************************************************************
-Parses a for-loop-statement. */
+/*********************************************************************//**
+Parses a for-loop-statement.
+@return for-statement node */
UNIV_INTERN
for_node_t*
pars_for_statement(
/*===============*/
- /* out: for-statement node */
- sym_node_t* loop_var, /* in: loop variable */
- que_node_t* loop_start_limit,/* in: loop start expression */
- que_node_t* loop_end_limit, /* in: loop end expression */
- que_node_t* stat_list) /* in: statement list */
+ sym_node_t* loop_var, /*!< in: loop variable */
+ que_node_t* loop_start_limit,/*!< in: loop start expression */
+ que_node_t* loop_end_limit, /*!< in: loop end expression */
+ que_node_t* stat_list) /*!< in: statement list */
{
for_node_t* node;
@@ -1364,13 +1357,13 @@ pars_for_statement(
return(node);
}
-/*************************************************************************
-Parses an exit statement. */
+/*********************************************************************//**
+Parses an exit statement.
+@return exit statement node */
UNIV_INTERN
exit_node_t*
pars_exit_statement(void)
/*=====================*/
- /* out: exit statement node */
{
exit_node_t* node;
@@ -1380,13 +1373,13 @@ pars_exit_statement(void)
return(node);
}
-/*************************************************************************
-Parses a return-statement. */
+/*********************************************************************//**
+Parses a return-statement.
+@return return-statement node */
UNIV_INTERN
return_node_t*
pars_return_statement(void)
/*=======================*/
- /* out: return-statement node */
{
return_node_t* node;
@@ -1397,15 +1390,15 @@ pars_return_statement(void)
return(node);
}
-/*************************************************************************
-Parses an assignment statement. */
+/*********************************************************************//**
+Parses an assignment statement.
+@return assignment statement node */
UNIV_INTERN
assign_node_t*
pars_assignment_statement(
/*======================*/
- /* out: assignment statement node */
- sym_node_t* var, /* in: variable to assign */
- que_node_t* val) /* in: value to assign */
+ sym_node_t* var, /*!< in: variable to assign */
+ que_node_t* val) /*!< in: value to assign */
{
assign_node_t* node;
@@ -1425,15 +1418,15 @@ pars_assignment_statement(
return(node);
}
-/*************************************************************************
-Parses a procedure call. */
+/*********************************************************************//**
+Parses a procedure call.
+@return function node */
UNIV_INTERN
func_node_t*
pars_procedure_call(
/*================*/
- /* out: function node */
- que_node_t* res_word,/* in: procedure name reserved word */
- que_node_t* args) /* in: argument list */
+ que_node_t* res_word,/*!< in: procedure name reserved word */
+ que_node_t* args) /*!< in: argument list */
{
func_node_t* node;
@@ -1444,17 +1437,17 @@ pars_procedure_call(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Parses a fetch statement. into_list or user_func (but not both) must be
-non-NULL. */
+non-NULL.
+@return fetch statement node */
UNIV_INTERN
fetch_node_t*
pars_fetch_statement(
/*=================*/
- /* out: fetch statement node */
- sym_node_t* cursor, /* in: cursor node */
- sym_node_t* into_list, /* in: variables to set, or NULL */
- sym_node_t* user_func) /* in: user function name, or NULL */
+ sym_node_t* cursor, /*!< in: cursor node */
+ sym_node_t* into_list, /*!< in: variables to set, or NULL */
+ sym_node_t* user_func) /*!< in: user function name, or NULL */
{
sym_node_t* cursor_decl;
fetch_node_t* node;
@@ -1496,16 +1489,16 @@ pars_fetch_statement(
return(node);
}
-/*************************************************************************
-Parses an open or close cursor statement. */
+/*********************************************************************//**
+Parses an open or close cursor statement.
+@return fetch statement node */
UNIV_INTERN
open_node_t*
pars_open_statement(
/*================*/
- /* out: fetch statement node */
- ulint type, /* in: ROW_SEL_OPEN_CURSOR
+ ulint type, /*!< in: ROW_SEL_OPEN_CURSOR
or ROW_SEL_CLOSE_CURSOR */
- sym_node_t* cursor) /* in: cursor node */
+ sym_node_t* cursor) /*!< in: cursor node */
{
sym_node_t* cursor_decl;
open_node_t* node;
@@ -1526,14 +1519,14 @@ pars_open_statement(
return(node);
}
-/*************************************************************************
-Parses a row_printf-statement. */
+/*********************************************************************//**
+Parses a row_printf-statement.
+@return row_printf-statement node */
UNIV_INTERN
row_printf_node_t*
pars_row_printf_statement(
/*======================*/
- /* out: row_printf-statement node */
- sel_node_t* sel_node) /* in: select node */
+ sel_node_t* sel_node) /*!< in: select node */
{
row_printf_node_t* node;
@@ -1548,8 +1541,9 @@ pars_row_printf_statement(
return(node);
}
-/*************************************************************************
-Parses a commit statement. */
+/*********************************************************************//**
+Parses a commit statement.
+@return own: commit node struct */
UNIV_INTERN
commit_node_t*
pars_commit_statement(void)
@@ -1558,8 +1552,9 @@ pars_commit_statement(void)
return(commit_node_create(pars_sym_tab_global->heap));
}
-/*************************************************************************
-Parses a rollback statement. */
+/*********************************************************************//**
+Parses a rollback statement.
+@return own: rollback node struct */
UNIV_INTERN
roll_node_t*
pars_rollback_statement(void)
@@ -1568,22 +1563,21 @@ pars_rollback_statement(void)
return(roll_node_create(pars_sym_tab_global->heap));
}
-/*************************************************************************
-Parses a column definition at a table creation. */
+/*********************************************************************//**
+Parses a column definition at a table creation.
+@return column sym table node */
UNIV_INTERN
sym_node_t*
pars_column_def(
/*============*/
- /* out: column sym table
- node */
- sym_node_t* sym_node, /* in: column node in the
+ sym_node_t* sym_node, /*!< in: column node in the
symbol table */
- pars_res_word_t* type, /* in: data type */
- sym_node_t* len, /* in: length of column, or
+ 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
+ void* is_unsigned, /*!< in: if not NULL, column
is of type UNSIGNED. */
- void* is_not_null) /* in: if not NULL, column
+ void* is_not_null) /*!< in: if not NULL, column
is of type NOT NULL. */
{
ulint len2;
@@ -1600,18 +1594,18 @@ pars_column_def(
return(sym_node);
}
-/*************************************************************************
-Parses a table creation operation. */
+/*********************************************************************//**
+Parses a table creation operation.
+@return table create subgraph */
UNIV_INTERN
tab_node_t*
pars_create_table(
/*==============*/
- /* out: table create subgraph */
- sym_node_t* table_sym, /* in: table name node in the symbol
+ 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* column_defs, /*!< in: list of column names */
void* not_fit_in_memory __attribute__((unused)))
- /* in: a non-NULL pointer means that
+ /*!< in: a non-NULL pointer means that
this is a table which in simulations
should be simulated as not fitting
in memory; thread is put to sleep
@@ -1662,20 +1656,20 @@ pars_create_table(
return(node);
}
-/*************************************************************************
-Parses an index creation operation. */
+/*********************************************************************//**
+Parses an index creation operation.
+@return index create subgraph */
UNIV_INTERN
ind_node_t*
pars_create_index(
/*==============*/
- /* out: index create subgraph */
- pars_res_word_t* unique_def, /* in: not NULL if a unique index */
- pars_res_word_t* clustered_def, /* in: not NULL if a clustered index */
- sym_node_t* index_sym, /* in: index name node in the symbol
+ pars_res_word_t* unique_def, /*!< in: not NULL if a unique index */
+ pars_res_word_t* clustered_def, /*!< in: not NULL if a clustered index */
+ sym_node_t* index_sym, /*!< in: index name node in the symbol
table */
- sym_node_t* table_sym, /* in: table name node in the symbol
+ sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_list) /* in: list of column names */
+ sym_node_t* column_list) /*!< in: list of column names */
{
dict_index_t* index;
sym_node_t* column;
@@ -1719,17 +1713,17 @@ pars_create_index(
return(node);
}
-/*************************************************************************
-Parses a procedure definition. */
+/*********************************************************************//**
+Parses a procedure definition.
+@return query fork node */
UNIV_INTERN
que_fork_t*
pars_procedure_definition(
/*======================*/
- /* out: query fork node */
- sym_node_t* sym_node, /* in: procedure id node in the symbol
+ 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 */
+ sym_node_t* param_list, /*!< in: parameter declaration list */
+ que_node_t* stat_list) /*!< in: statement list */
{
proc_node_t* node;
que_fork_t* fork;
@@ -1766,32 +1760,32 @@ pars_procedure_definition(
return(fork);
}
-/*****************************************************************
+/*************************************************************//**
Parses a stored procedure call, when this is not within another stored
procedure, that is, the client issues a procedure call directly.
In MySQL/InnoDB, stored InnoDB procedures are invoked via the
-parsed procedure tree, not via InnoDB SQL, so this function is not used. */
+parsed procedure tree, not via InnoDB SQL, so this function is not used.
+@return query graph */
UNIV_INTERN
que_fork_t*
pars_stored_procedure_call(
/*=======================*/
- /* out: query graph */
sym_node_t* sym_node __attribute__((unused)))
- /* in: stored procedure name */
+ /*!< in: stored procedure name */
{
ut_error;
return(NULL);
}
-/*****************************************************************
+/*************************************************************//**
Retrieves characters to the lexical analyzer. */
UNIV_INTERN
void
pars_get_lex_chars(
/*===============*/
- char* buf, /* in/out: buffer where to copy */
- int* result, /* out: number of characters copied or EOF */
- int max_size) /* in: maximum number of characters which fit
+ char* buf, /*!< in/out: buffer where to copy */
+ int* result, /*!< out: number of characters copied or EOF */
+ int max_size) /*!< in: maximum number of characters which fit
in the buffer */
{
int len;
@@ -1831,14 +1825,14 @@ pars_get_lex_chars(
pars_sym_tab_global->next_char_pos += len;
}
-/*****************************************************************
+/*************************************************************//**
Called by yyparse on error. */
UNIV_INTERN
void
yyerror(
/*====*/
const char* s __attribute__((unused)))
- /* in: error message string */
+ /*!< in: error message string */
{
ut_ad(s);
@@ -1847,15 +1841,15 @@ yyerror(
ut_error;
}
-/*****************************************************************
-Parses an SQL string returning the query graph. */
+/*************************************************************//**
+Parses an SQL string returning the query graph.
+@return own: the query graph */
UNIV_INTERN
que_t*
pars_sql(
/*=====*/
- /* out, own: the query graph */
- pars_info_t* info, /* in: extra information, or NULL */
- const char* str) /* in: SQL string */
+ pars_info_t* info, /*!< in: extra information, or NULL */
+ const char* str) /*!< in: SQL string */
{
sym_node_t* sym_node;
mem_heap_t* heap;
@@ -1896,19 +1890,19 @@ pars_sql(
return(graph);
}
-/**********************************************************************
+/******************************************************************//**
Completes a query graph by adding query thread and fork nodes
above it and prepares the graph for running. The fork created is of
-type QUE_FORK_MYSQL_INTERFACE. */
+type QUE_FORK_MYSQL_INTERFACE.
+@return query thread node to run */
UNIV_INTERN
que_thr_t*
pars_complete_graph_for_exec(
/*=========================*/
- /* out: query thread node to run */
- que_node_t* node, /* in: root node for an incomplete
+ que_node_t* node, /*!< in: root node for an incomplete
query graph */
- trx_t* trx, /* in: transaction handle */
- mem_heap_t* heap) /* in: memory heap from which allocated */
+ trx_t* trx, /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
que_fork_t* fork;
que_thr_t* thr;
@@ -1927,13 +1921,13 @@ pars_complete_graph_for_exec(
return(thr);
}
-/********************************************************************
-Create parser info struct.*/
+/****************************************************************//**
+Create parser info struct.
+@return own: info struct */
UNIV_INTERN
pars_info_t*
pars_info_create(void)
/*==================*/
- /* out, own: info struct */
{
pars_info_t* info;
mem_heap_t* heap;
@@ -1951,29 +1945,29 @@ pars_info_create(void)
return(info);
}
-/********************************************************************
-Free info struct and everything it contains.*/
+/****************************************************************//**
+Free info struct and everything it contains. */
UNIV_INTERN
void
pars_info_free(
/*===========*/
- pars_info_t* info) /* in: info struct */
+ pars_info_t* info) /*!< in, own: info struct */
{
mem_heap_free(info->heap);
}
-/********************************************************************
+/****************************************************************//**
Add bound literal. */
UNIV_INTERN
void
pars_info_add_literal(
/*==================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const void* address, /* in: address */
- ulint length, /* in: length of data */
- ulint type, /* in: type, e.g. DATA_FIXBINARY */
- ulint prtype) /* in: precise type, e.g.
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const void* address, /*!< in: address */
+ ulint length, /*!< in: length of data */
+ ulint type, /*!< in: type, e.g. DATA_FIXBINARY */
+ ulint prtype) /*!< in: precise type, e.g.
DATA_UNSIGNED */
{
pars_bound_lit_t* pbl;
@@ -1995,22 +1989,22 @@ pars_info_add_literal(
ib_vector_push(info->bound_lits, pbl);
}
-/********************************************************************
+/****************************************************************//**
Equivalent to pars_info_add_literal(info, name, str, strlen(str),
DATA_VARCHAR, DATA_ENGLISH). */
UNIV_INTERN
void
pars_info_add_str_literal(
/*======================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const char* str) /* in: string */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const char* str) /*!< in: string */
{
pars_info_add_literal(info, name, str, strlen(str),
DATA_VARCHAR, DATA_ENGLISH);
}
-/********************************************************************
+/****************************************************************//**
Equivalent to:
char buf[4];
@@ -2023,9 +2017,9 @@ UNIV_INTERN
void
pars_info_add_int4_literal(
/*=======================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- lint val) /* in: value */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ lint val) /*!< in: value */
{
byte* buf = mem_heap_alloc(info->heap, 4);
@@ -2033,7 +2027,7 @@ pars_info_add_int4_literal(
pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
}
-/********************************************************************
+/****************************************************************//**
Equivalent to:
char buf[8];
@@ -2046,9 +2040,9 @@ UNIV_INTERN
void
pars_info_add_dulint_literal(
/*=========================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- dulint val) /* in: value */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ dulint val) /*!< in: value */
{
byte* buf = mem_heap_alloc(info->heap, 8);
@@ -2057,16 +2051,16 @@ pars_info_add_dulint_literal(
pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
}
-/********************************************************************
+/****************************************************************//**
Add user function. */
UNIV_INTERN
void
pars_info_add_function(
/*===================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: function name */
- pars_user_func_cb_t func, /* in: function address */
- void* arg) /* in: user-supplied argument */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: function name */
+ pars_user_func_cb_t func, /*!< in: function address */
+ void* arg) /*!< in: user-supplied argument */
{
pars_user_func_t* puf;
@@ -2085,15 +2079,15 @@ pars_info_add_function(
ib_vector_push(info->funcs, puf);
}
-/********************************************************************
+/****************************************************************//**
Add bound id. */
UNIV_INTERN
void
pars_info_add_id(
/*=============*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const char* id) /* in: id */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const char* id) /*!< in: id */
{
pars_bound_id_t* bid;
@@ -2111,16 +2105,15 @@ pars_info_add_id(
ib_vector_push(info->bound_ids, bid);
}
-/********************************************************************
-Get user function with the given name.*/
+/****************************************************************//**
+Get user function with the given name.
+@return user func, or NULL if not found */
UNIV_INTERN
pars_user_func_t*
pars_info_get_user_func(
/*====================*/
- /* out: user func, or NULL if not
- found */
- pars_info_t* info, /* in: info struct */
- const char* name) /* in: function name to find*/
+ pars_info_t* info, /*!< in: info struct */
+ const char* name) /*!< in: function name to find*/
{
ulint i;
ib_vector_t* vec;
@@ -2142,16 +2135,15 @@ pars_info_get_user_func(
return(NULL);
}
-/********************************************************************
-Get bound literal with the given name.*/
+/****************************************************************//**
+Get bound literal with the given name.
+@return bound literal, or NULL if not found */
UNIV_INTERN
pars_bound_lit_t*
pars_info_get_bound_lit(
/*====================*/
- /* out: bound literal, or NULL if
- not found */
- pars_info_t* info, /* in: info struct */
- const char* name) /* in: bound literal name to find */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name) /*!< in: bound literal name to find */
{
ulint i;
ib_vector_t* vec;
@@ -2173,16 +2165,15 @@ pars_info_get_bound_lit(
return(NULL);
}
-/********************************************************************
-Get bound id with the given name.*/
+/****************************************************************//**
+Get bound id with the given name.
+@return bound id, or NULL if not found */
UNIV_INTERN
pars_bound_id_t*
pars_info_get_bound_id(
/*===================*/
- /* out: bound id, or NULL if not
- found */
- pars_info_t* info, /* in: info struct */
- const char* name) /* in: bound id name to find */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name) /*!< in: bound id name to find */
{
ulint i;
ib_vector_t* vec;
diff --git a/storage/xtradb/pars/pars0sym.c b/storage/xtradb/pars/pars0sym.c
index fb23547e767..b56350116bb 100644
--- a/storage/xtradb/pars/pars0sym.c
+++ b/storage/xtradb/pars/pars0sym.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file pars/pars0sym.c
SQL parser symbol table
Created 12/15/1997 Heikki Tuuri
@@ -37,14 +38,14 @@ Created 12/15/1997 Heikki Tuuri
#include "eval0eval.h"
#include "row0sel.h"
-/**********************************************************************
-Creates a symbol table for a single stored procedure or query. */
+/******************************************************************//**
+Creates a symbol table for a single stored procedure or query.
+@return own: symbol table */
UNIV_INTERN
sym_tab_t*
sym_tab_create(
/*===========*/
- /* out, own: symbol table */
- mem_heap_t* heap) /* in: memory heap where to create */
+ mem_heap_t* heap) /*!< in: memory heap where to create */
{
sym_tab_t* sym_tab;
@@ -58,7 +59,7 @@ sym_tab_create(
return(sym_tab);
}
-/**********************************************************************
+/******************************************************************//**
Frees the memory allocated dynamically AFTER parsing phase for variables
etc. in the symbol table. Does not free the mem heap where the table was
originally created. Frees also SQL explicit cursor definitions. */
@@ -66,7 +67,7 @@ UNIV_INTERN
void
sym_tab_free_private(
/*=================*/
- sym_tab_t* sym_tab) /* in, own: symbol table */
+ sym_tab_t* sym_tab) /*!< in, own: symbol table */
{
sym_node_t* sym;
func_node_t* func;
@@ -96,15 +97,15 @@ sym_tab_free_private(
}
}
-/**********************************************************************
-Adds an integer literal to a symbol table. */
+/******************************************************************//**
+Adds an integer literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_int_lit(
/*================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- ulint val) /* in: integer value */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ ulint val) /*!< in: integer value */
{
sym_node_t* node;
byte* data;
@@ -136,17 +137,17 @@ sym_tab_add_int_lit(
return(node);
}
-/**********************************************************************
-Adds a string literal to a symbol table. */
+/******************************************************************//**
+Adds a string literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_str_lit(
/*================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- byte* str, /* in: string with no quotes around
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ byte* str, /*!< in: string with no quotes around
it */
- ulint len) /* in: string length */
+ ulint len) /*!< in: string length */
{
sym_node_t* node;
byte* data;
@@ -183,16 +184,16 @@ sym_tab_add_str_lit(
return(node);
}
-/**********************************************************************
-Add a bound literal to a symbol table. */
+/******************************************************************//**
+Add a bound literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_bound_lit(
/*==================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- const char* name, /* in: name of bound literal */
- ulint* lit_type) /* out: type of literal (PARS_*_LIT) */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ const char* name, /*!< in: name of bound literal */
+ ulint* lit_type) /*!< out: type of literal (PARS_*_LIT) */
{
sym_node_t* node;
pars_bound_lit_t* blit;
@@ -259,14 +260,14 @@ sym_tab_add_bound_lit(
return(node);
}
-/**********************************************************************
-Adds an SQL null literal to a symbol table. */
+/******************************************************************//**
+Adds an SQL null literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_null_lit(
/*=================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab) /* in: symbol table */
+ sym_tab_t* sym_tab) /*!< in: symbol table */
{
sym_node_t* node;
@@ -294,16 +295,16 @@ sym_tab_add_null_lit(
return(node);
}
-/**********************************************************************
-Adds an identifier to a symbol table. */
+/******************************************************************//**
+Adds an identifier to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_id(
/*===========*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- byte* name, /* in: identifier name */
- ulint len) /* in: identifier length */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ byte* name, /*!< in: identifier name */
+ ulint len) /*!< in: identifier length */
{
sym_node_t* node;
@@ -330,15 +331,15 @@ sym_tab_add_id(
return(node);
}
-/**********************************************************************
-Add a bound identifier to a symbol table. */
+/******************************************************************//**
+Add a bound identifier to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_bound_id(
/*===========*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- const char* name) /* in: name of bound id */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ const char* name) /*!< in: name of bound id */
{
sym_node_t* node;
pars_bound_id_t* bid;
diff --git a/storage/xtradb/plug.in b/storage/xtradb/plug.in
index 35c0ac750b0..2d7bd51ec17 100644
--- a/storage/xtradb/plug.in
+++ b/storage/xtradb/plug.in
@@ -42,7 +42,9 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
*solaris*|*SunOS*)
CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
esac
+
INNODB_DYNAMIC_CFLAGS="-DMYSQL_DYNAMIC_PLUGIN"
+
case "$target_cpu" in
x86_64)
# The AMD64 ABI forbids absolute addresses in shared libraries
@@ -53,30 +55,173 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
;;
esac
AC_SUBST(INNODB_DYNAMIC_CFLAGS)
+
+ AC_MSG_CHECKING(whether GCC atomic builtins are available)
+ # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not
+ AC_TRY_RUN(
+ [
+ int main()
+ {
+ long x;
+ long y;
+ long res;
+ char c;
+
+ x = 10;
+ y = 123;
+ res = __sync_bool_compare_and_swap(&x, x, y);
+ if (!res || x != y) {
+ return(1);
+ }
+
+ x = 10;
+ y = 123;
+ res = __sync_bool_compare_and_swap(&x, x + 1, y);
+ if (res || x != 10) {
+ return(1);
+ }
+
+ x = 10;
+ y = 123;
+ res = __sync_add_and_fetch(&x, y);
+ if (res != 123 + 10 || x != 123 + 10) {
+ return(1);
+ }
+
+ c = 10;
+ res = __sync_lock_test_and_set(&c, 123);
+ if (res != 10 || c != 123) {
+ return(1);
+ }
+
+ return(0);
+ }
+ ],
+ [
+ AC_DEFINE([HAVE_IB_GCC_ATOMIC_BUILTINS], [1],
+ [GCC atomic builtins are available])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
+
AC_MSG_CHECKING(whether pthread_t can be used by GCC atomic builtins)
+ # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not
AC_TRY_RUN(
[
#include <pthread.h>
+ #include <string.h>
int main(int argc, char** argv) {
pthread_t x1;
pthread_t x2;
pthread_t x3;
+ memset(&x1, 0x0, sizeof(x1));
+ memset(&x2, 0x0, sizeof(x2));
+ memset(&x3, 0x0, sizeof(x3));
+
__sync_bool_compare_and_swap(&x1, x2, x3);
return(0);
}
],
[
- AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1],
+ AC_DEFINE([HAVE_IB_ATOMIC_PTHREAD_T_GCC], [1],
[pthread_t can be used by GCC atomic builtins])
AC_MSG_RESULT(yes)
],
[
AC_MSG_RESULT(no)
]
- )
+ )
+
+ AC_MSG_CHECKING(whether Solaris libc atomic functions are available)
+ # either define HAVE_IB_SOLARIS_ATOMICS or not
+ AC_CHECK_FUNCS(atomic_add_long \
+ atomic_cas_32 \
+ atomic_cas_64 \
+ atomic_cas_ulong,
+
+ AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1],
+ [Define to 1 if Solaris libc atomic functions \
+ are available])
+ )
+
+ AC_MSG_CHECKING(whether pthread_t can be used by Solaris libc atomic functions)
+ # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not
+ AC_TRY_RUN(
+ [
+ #include <pthread.h>
+ #include <string.h>
+
+ int main(int argc, char** argv) {
+ pthread_t x1;
+ pthread_t x2;
+ pthread_t x3;
+
+ memset(&x1, 0x0, sizeof(x1));
+ memset(&x2, 0x0, sizeof(x2));
+ memset(&x3, 0x0, sizeof(x3));
+
+ if (sizeof(pthread_t) == 4) {
+
+ atomic_cas_32(&x1, x2, x3);
+
+ } else if (sizeof(pthread_t) == 8) {
+
+ atomic_cas_64(&x1, x2, x3);
+
+ } else {
+
+ return(1);
+ }
+
+ return(0);
+ }
+ ],
+ [
+ AC_DEFINE([HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS], [1],
+ [pthread_t can be used by solaris atomics])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
+
+ # this is needed to know which one of atomic_cas_32() or atomic_cas_64()
+ # to use in the source
+ AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>])
+
+ # Check for x86 PAUSE instruction
+ AC_MSG_CHECKING(for x86 PAUSE instruction)
+ # We have to actually try running the test program, because of a bug
+ # in Solaris on x86_64, where it wrongly reports that PAUSE is not
+ # supported when trying to run an application. See
+ # http://bugs.opensolaris.org/bugdatabase/printableBug.do?bug_id=6478684
+ # We use ib_ prefix to avoid collisoins if this code is added to
+ # mysql's configure.in.
+ AC_TRY_RUN(
+ [
+ int main() {
+ __asm__ __volatile__ ("pause");
+ return(0);
+ }
+ ],
+ [
+ AC_DEFINE([HAVE_IB_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
])
# vim: set ft=config:
diff --git a/storage/xtradb/que/que0que.c b/storage/xtradb/que/que0que.c
index 91a9d30ec4c..2fe046fa9b8 100644
--- a/storage/xtradb/que/que0que.c
+++ b/storage/xtradb/que/que0que.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file que/que0que.c
Query graph
Created 5/27/1996 Heikki Tuuri
@@ -123,7 +124,7 @@ When the execution of the graph completes, it is like returning
from a subprocedure: the query thread which requested the operation
starts running again. */
-/**************************************************************************
+/**********************************************************************//**
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction.
***NOTE***: This is the only function in which such a transition is allowed
@@ -132,35 +133,35 @@ static
void
que_thr_move_to_run_state(
/*======================*/
- que_thr_t* thr); /* in: an query thread */
+ que_thr_t* thr); /*!< in: an query thread */
-/***************************************************************************
+/***********************************************************************//**
Adds a query graph to the session's list of graphs. */
UNIV_INTERN
void
que_graph_publish(
/*==============*/
- que_t* graph, /* in: graph */
- sess_t* sess) /* in: session */
+ que_t* graph, /*!< in: graph */
+ sess_t* sess) /*!< in: session */
{
ut_ad(mutex_own(&kernel_mutex));
UT_LIST_ADD_LAST(graphs, sess->graphs, graph);
}
-/***************************************************************************
-Creates a query graph fork node. */
+/***********************************************************************//**
+Creates a query graph fork node.
+@return own: fork node */
UNIV_INTERN
que_fork_t*
que_fork_create(
/*============*/
- /* out, own: fork node */
- que_t* graph, /* in: graph, if NULL then this
+ que_t* graph, /*!< in: graph, if NULL then this
fork node is assumed to be the
graph root */
- que_node_t* parent, /* in: parent node */
- ulint fork_type, /* in: fork type */
- mem_heap_t* heap) /* in: memory heap where created */
+ que_node_t* parent, /*!< in: parent node */
+ ulint fork_type, /*!< in: fork type */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
que_fork_t* fork;
@@ -194,15 +195,15 @@ que_fork_create(
return(fork);
}
-/***************************************************************************
-Creates a query graph thread node. */
+/***********************************************************************//**
+Creates a query graph thread node.
+@return own: query thread node */
UNIV_INTERN
que_thr_t*
que_thr_create(
/*===========*/
- /* out, own: query thread node */
- que_fork_t* parent, /* in: parent node, i.e., a fork node */
- mem_heap_t* heap) /* in: memory heap where created */
+ que_fork_t* parent, /*!< in: parent node, i.e., a fork node */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
que_thr_t* thr;
@@ -230,7 +231,7 @@ que_thr_create(
return(thr);
}
-/**************************************************************************
+/**********************************************************************//**
Moves a suspended query thread to the QUE_THR_RUNNING state and may release
a single worker thread to execute it. This function should be used to end
the wait state of a query thread waiting for a lock or a stored procedure
@@ -239,11 +240,11 @@ UNIV_INTERN
void
que_thr_end_wait(
/*=============*/
- que_thr_t* thr, /* in: query thread in the
+ que_thr_t* thr, /*!< in: query thread in the
QUE_THR_LOCK_WAIT,
or QUE_THR_PROCEDURE_WAIT, or
QUE_THR_SIG_REPLY_WAIT state */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -278,13 +279,13 @@ que_thr_end_wait(
}
}
-/**************************************************************************
+/**********************************************************************//**
Same as que_thr_end_wait, but no parameter next_thr available. */
UNIV_INTERN
void
que_thr_end_wait_no_next_thr(
/*=========================*/
- que_thr_t* thr) /* in: query thread in the QUE_THR_LOCK_WAIT,
+ que_thr_t* thr) /*!< in: query thread in the QUE_THR_LOCK_WAIT,
or QUE_THR_PROCEDURE_WAIT, or
QUE_THR_SIG_REPLY_WAIT state */
{
@@ -315,13 +316,13 @@ que_thr_end_wait_no_next_thr(
/* srv_que_task_enqueue_low(thr); */
}
-/**************************************************************************
+/**********************************************************************//**
Inits a query thread for a command. */
UNIV_INLINE
void
que_thr_init_command(
/*=================*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
thr->run_node = thr;
thr->prev_node = thr->common.parent;
@@ -329,20 +330,19 @@ que_thr_init_command(
que_thr_move_to_run_state(thr);
}
-/**************************************************************************
+/**********************************************************************//**
Starts execution of a command in a query fork. Picks a query thread which
is not in the QUE_THR_RUNNING state and moves it to that state. If none
can be chosen, a situation which may arise in parallelized fetches, NULL
-is returned. */
+is returned.
+@return a query thread of the graph moved to QUE_THR_RUNNING state, or
+NULL; the query thread should be executed by que_run_threads by the
+caller */
UNIV_INTERN
que_thr_t*
que_fork_start_command(
/*===================*/
- /* out: a query thread of the graph moved to
- QUE_THR_RUNNING state, or NULL; the query
- thread should be executed by que_run_threads
- by the caller */
- que_fork_t* fork) /* in: a query fork */
+ que_fork_t* fork) /*!< in: a query fork */
{
que_thr_t* thr;
que_thr_t* suspended_thr = NULL;
@@ -418,7 +418,7 @@ que_fork_start_command(
return(thr);
}
-/**************************************************************************
+/**********************************************************************//**
After signal handling is finished, returns control to a query graph error
handling routine. (Currently, just returns the control to the root of the
graph so that the graph can communicate an error message to the client.) */
@@ -426,8 +426,8 @@ UNIV_INTERN
void
que_fork_error_handle(
/*==================*/
- trx_t* trx __attribute__((unused)), /* in: trx */
- que_t* fork) /* in: query graph which was run before signal
+ trx_t* trx __attribute__((unused)), /*!< in: trx */
+ que_t* fork) /*!< in: query graph which was run before signal
handling started, NULL not allowed */
{
que_thr_t* thr;
@@ -459,16 +459,16 @@ que_fork_error_handle(
srv_que_task_enqueue_low(thr);
}
-/********************************************************************
-Tests if all the query threads in the same fork have a given state. */
+/****************************************************************//**
+Tests if all the query threads in the same fork have a given state.
+@return TRUE if all the query threads in the same fork were in the
+given state */
UNIV_INLINE
ibool
que_fork_all_thrs_in_state(
/*=======================*/
- /* out: TRUE if all the query threads in the
- same fork were in the given state */
- que_fork_t* fork, /* in: query fork */
- ulint state) /* in: state */
+ que_fork_t* fork, /*!< in: query fork */
+ ulint state) /*!< in: state */
{
que_thr_t* thr_node;
@@ -486,13 +486,13 @@ que_fork_all_thrs_in_state(
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Calls que_graph_free_recursive for statements in a statement list. */
static
void
que_graph_free_stat_list(
/*=====================*/
- que_node_t* node) /* in: first query graph node in the list */
+ que_node_t* node) /*!< in: first query graph node in the list */
{
while (node) {
que_graph_free_recursive(node);
@@ -501,14 +501,14 @@ que_graph_free_stat_list(
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees a query graph, but not the heap where it was created. Does not free
explicit cursor declarations, they are freed in que_graph_free. */
UNIV_INTERN
void
que_graph_free_recursive(
/*=====================*/
- que_node_t* node) /* in: query graph node */
+ que_node_t* node) /*!< in: query graph node */
{
que_fork_t* fork;
que_thr_t* thr;
@@ -518,6 +518,7 @@ que_graph_free_recursive(
upd_node_t* upd;
tab_node_t* cre_tab;
ind_node_t* cre_ind;
+ purge_node_t* purge;
if (node == NULL) {
@@ -579,6 +580,13 @@ que_graph_free_recursive(
mem_heap_free(ins->entry_sys_heap);
break;
+ case QUE_NODE_PURGE:
+ purge = node;
+
+ mem_heap_free(purge->heap);
+
+ break;
+
case QUE_NODE_UPDATE:
upd = node;
@@ -665,13 +673,13 @@ que_graph_free_recursive(
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees a query graph. */
UNIV_INTERN
void
que_graph_free(
/*===========*/
- que_t* graph) /* in: query graph; we assume that the memory
+ que_t* graph) /*!< in: query graph; we assume that the memory
heap where this graph was created is private
to this graph: if not, then use
que_graph_free_recursive and free the heap
@@ -696,46 +704,14 @@ que_graph_free(
mem_heap_free(graph->heap);
}
-/**************************************************************************
-Checks if the query graph is in a state where it should be freed, and
-frees it in that case. If the session is in a state where it should be
-closed, also this is done. */
-UNIV_INTERN
-ibool
-que_graph_try_free(
-/*===============*/
- /* out: TRUE if freed */
- que_t* graph) /* in: query graph */
-{
- sess_t* sess;
-
- ut_ad(mutex_own(&kernel_mutex));
-
- sess = (graph->trx)->sess;
-
- if ((graph->state == QUE_FORK_BEING_FREED)
- && (graph->n_active_thrs == 0)) {
-
- UT_LIST_REMOVE(graphs, sess->graphs, graph);
- que_graph_free(graph);
-
- sess_try_close(sess);
-
- return(TRUE);
- }
-
- return(FALSE);
-}
-
-/********************************************************************
-Performs an execution step on a thr node. */
+/****************************************************************//**
+Performs an execution step on a thr node.
+@return query thread to run next, or NULL if none */
static
que_thr_t*
que_thr_node_step(
/*==============*/
- /* out: query thread to run next, or NULL
- if none */
- que_thr_t* thr) /* in: query thread where run_node must
+ que_thr_t* thr) /*!< in: query thread where run_node must
be the thread node itself */
{
ut_ad(thr->run_node == thr);
@@ -767,7 +743,7 @@ que_thr_node_step(
return(NULL);
}
-/**************************************************************************
+/**********************************************************************//**
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction if thr was
not active.
@@ -777,7 +753,7 @@ static
void
que_thr_move_to_run_state(
/*======================*/
- que_thr_t* thr) /* in: an query thread */
+ que_thr_t* thr) /*!< in: an query thread */
{
trx_t* trx;
@@ -800,7 +776,7 @@ que_thr_move_to_run_state(
thr->state = QUE_THR_RUNNING;
}
-/**************************************************************************
+/**********************************************************************//**
Decrements the query thread reference counts in the query graph and the
transaction. May start signal handling, e.g., a rollback.
*** NOTE ***:
@@ -812,8 +788,8 @@ static
void
que_thr_dec_refer_count(
/*====================*/
- que_thr_t* thr, /* in: query thread */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ que_thr_t* thr, /*!< in: query thread */
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -902,7 +878,7 @@ que_thr_dec_refer_count(
break;
default:
- ut_error; /* not used in MySQL */
+ ut_error; /*!< not used in MySQL */
}
}
@@ -923,16 +899,16 @@ que_thr_dec_refer_count(
mutex_exit(&kernel_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Stops a query thread if graph or trx is in a state requiring it. The
conditions are tested in the order (1) graph, (2) trx. The kernel mutex has
-to be reserved. */
+to be reserved.
+@return TRUE if stopped */
UNIV_INTERN
ibool
que_thr_stop(
/*=========*/
- /* out: TRUE if stopped */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
que_t* graph;
@@ -970,7 +946,7 @@ que_thr_stop(
return(ret);
}
-/**************************************************************************
+/**********************************************************************//**
A patch for MySQL used to 'stop' a dummy query thread used in MySQL. The
query thread is stopped and made inactive, except in the case where
it was put to the lock wait state in lock0lock.c, but the lock has already
@@ -979,7 +955,7 @@ UNIV_INTERN
void
que_thr_stop_for_mysql(
/*===================*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
@@ -1017,7 +993,7 @@ que_thr_stop_for_mysql(
mutex_exit(&kernel_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction if thr was
not active. */
@@ -1025,8 +1001,8 @@ UNIV_INTERN
void
que_thr_move_to_run_state_for_mysql(
/*================================*/
- que_thr_t* thr, /* in: an query thread */
- trx_t* trx) /* in: transaction */
+ que_thr_t* thr, /*!< in: an query thread */
+ trx_t* trx) /*!< in: transaction */
{
if (thr->magic_n != QUE_THR_MAGIC_N) {
fprintf(stderr,
@@ -1050,15 +1026,15 @@ que_thr_move_to_run_state_for_mysql(
thr->state = QUE_THR_RUNNING;
}
-/**************************************************************************
+/**********************************************************************//**
A patch for MySQL used to 'stop' a dummy query thread used in MySQL
select, when there is no error or lock wait. */
UNIV_INTERN
void
que_thr_stop_for_mysql_no_error(
/*============================*/
- que_thr_t* thr, /* in: query thread */
- trx_t* trx) /* in: transaction */
+ que_thr_t* thr, /*!< in: query thread */
+ trx_t* trx) /*!< in: transaction */
{
ut_ad(thr->state == QUE_THR_RUNNING);
ut_ad(thr->is_active == TRUE);
@@ -1083,15 +1059,15 @@ que_thr_stop_for_mysql_no_error(
trx->n_active_thrs--;
}
-/********************************************************************
+/****************************************************************//**
Get the first containing loop node (e.g. while_node_t or for_node_t) for the
-given node, or NULL if the node is not within a loop. */
+given node, or NULL if the node is not within a loop.
+@return containing loop node, or NULL. */
UNIV_INTERN
que_node_t*
que_node_get_containing_loop_node(
/*==============================*/
- /* out: containing loop node, or NULL. */
- que_node_t* node) /* in: node */
+ que_node_t* node) /*!< in: node */
{
ut_ad(node);
@@ -1114,13 +1090,13 @@ que_node_get_containing_loop_node(
return(node);
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of an SQL query graph node. */
UNIV_INTERN
void
que_node_print_info(
/*================*/
- que_node_t* node) /* in: query graph node */
+ que_node_t* node) /*!< in: query graph node */
{
ulint type;
const char* str;
@@ -1177,16 +1153,15 @@ que_node_print_info(
(ulong) type, str, (void*) node);
}
-/**************************************************************************
-Performs an execution step on a query thread. */
+/**********************************************************************//**
+Performs an execution step on a query thread.
+@return query thread to run next: it may differ from the input
+parameter if, e.g., a subprocedure call is made */
UNIV_INLINE
que_thr_t*
que_thr_step(
/*=========*/
- /* out: query thread to run next: it may
- differ from the input parameter if, e.g., a
- subprocedure call is made */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
que_node_t* node;
que_thr_t* old_thr;
@@ -1300,13 +1275,13 @@ que_thr_step(
return(thr);
}
-/**************************************************************************
+/**********************************************************************//**
Run a query thread until it finishes or encounters e.g. a lock wait. */
static
void
que_run_threads_low(
/*================*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
que_thr_t* next_thr;
ulint cumul_resource;
@@ -1360,13 +1335,13 @@ loop:
goto loop;
}
-/**************************************************************************
+/**********************************************************************//**
Run a query thread. Handles lock waits. */
UNIV_INTERN
void
que_run_threads(
/*============*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
loop:
ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
@@ -1415,19 +1390,19 @@ loop:
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
-Evaluate the given SQL. */
+/*********************************************************************//**
+Evaluate the given SQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
que_eval_sql(
/*=========*/
- /* out: error code or DB_SUCCESS */
- pars_info_t* info, /* in: info struct, or NULL */
- const char* sql, /* in: SQL string */
+ pars_info_t* info, /*!< in: info struct, or NULL */
+ const char* sql, /*!< in: SQL string */
ibool reserve_dict_mutex,
- /* in: if TRUE, acquire/release
+ /*!< in: if TRUE, acquire/release
dict_sys->mutex around call to pars_sql. */
- trx_t* trx) /* in: trx */
+ trx_t* trx) /*!< in: trx */
{
que_thr_t* thr;
que_t* graph;
diff --git a/storage/xtradb/read/read0read.c b/storage/xtradb/read/read0read.c
index e3e5ee5d623..85adae4ddff 100644
--- a/storage/xtradb/read/read0read.c
+++ b/storage/xtradb/read/read0read.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file read/read0read.c
Cursor read
Created 2/16/1997 Heikki Tuuri
@@ -136,39 +137,40 @@ TODO: proof this
*/
-/*************************************************************************
-Creates a read view object. */
+/*********************************************************************//**
+Creates a read view object.
+@return own: read view struct */
UNIV_INLINE
read_view_t*
read_view_create_low(
/*=================*/
- /* out, own: read view struct */
- ulint n, /* in: number of cells in the trx_ids array */
- mem_heap_t* heap) /* in: memory heap from which allocated */
+ ulint n, /*!< in: number of cells in the trx_ids array */
+ mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
read_view_t* view;
view = mem_heap_alloc(heap, sizeof(read_view_t));
view->n_trx_ids = n;
- view->trx_ids = mem_heap_alloc(heap, n * sizeof(dulint));
+ view->trx_ids = mem_heap_alloc(heap, n * sizeof *view->trx_ids);
return(view);
}
-/*************************************************************************
+/*********************************************************************//**
Makes a copy of the oldest existing read view, with the exception that also
the creating trx of the oldest view is set as not visible in the 'copied'
view. Opens a new view if no views currently exist. The view must be closed
-with ..._close. This is used in purge. */
+with ..._close. This is used in purge.
+@return own: read view struct */
UNIV_INTERN
read_view_t*
read_view_oldest_copy_or_open_new(
/*==============================*/
- /* out, own: read view struct */
- dulint cr_trx_id, /* in: trx_id of creating
- transaction, or (0, 0) used in purge*/
- mem_heap_t* heap) /* in: memory heap from which
+ trx_id_t cr_trx_id, /*!< in: trx_id of creating
+ transaction, or ut_dulint_zero
+ used in purge */
+ mem_heap_t* heap) /*!< in: memory heap from which
allocated */
{
read_view_t* old_view;
@@ -241,18 +243,18 @@ read_view_oldest_copy_or_open_new(
return(view_copy);
}
-/*************************************************************************
+/*********************************************************************//**
Opens a read view where exactly the transactions serialized before this
-point in time are seen in the view. */
+point in time are seen in the view.
+@return own: read view struct */
UNIV_INTERN
read_view_t*
read_view_open_now(
/*===============*/
- /* out, own: read view struct */
- dulint cr_trx_id, /* in: trx_id of creating
- transaction, or (0, 0) used in
- purge */
- mem_heap_t* heap) /* in: memory heap from which
+ trx_id_t cr_trx_id, /*!< in: trx_id of creating
+ transaction, or ut_dulint_zero
+ used in purge */
+ mem_heap_t* heap) /*!< in: memory heap from which
allocated */
{
read_view_t* view;
@@ -316,27 +318,27 @@ read_view_open_now(
return(view);
}
-/*************************************************************************
+/*********************************************************************//**
Closes a read view. */
UNIV_INTERN
void
read_view_close(
/*============*/
- read_view_t* view) /* in: read view */
+ read_view_t* view) /*!< in: read view */
{
ut_ad(mutex_own(&kernel_mutex));
UT_LIST_REMOVE(view_list, trx_sys->view_list, view);
}
-/*************************************************************************
+/*********************************************************************//**
Closes a consistent read view for MySQL. This function is called at an SQL
statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
UNIV_INTERN
void
read_view_close_for_mysql(
/*======================*/
- trx_t* trx) /* in: trx which has a read view */
+ trx_t* trx) /*!< in: trx which has a read view */
{
ut_a(trx->global_read_view);
@@ -352,13 +354,13 @@ read_view_close_for_mysql(
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Prints a read view to stderr. */
UNIV_INTERN
void
read_view_print(
/*============*/
- read_view_t* view) /* in: read view */
+ const read_view_t* view) /*!< in: read view */
{
ulint n_ids;
ulint i;
@@ -393,7 +395,7 @@ read_view_print(
}
}
-/*************************************************************************
+/*********************************************************************//**
Create a high-granularity consistent cursor view for mysql to be used
in cursors. In this consistent read view modifications done by the
creating transaction after the cursor is created or future transactions
@@ -402,7 +404,7 @@ UNIV_INTERN
cursor_view_t*
read_cursor_view_create_for_mysql(
/*==============================*/
- trx_t* cr_trx) /* in: trx where cursor view is created */
+ trx_t* cr_trx) /*!< in: trx where cursor view is created */
{
cursor_view_t* curview;
read_view_t* view;
@@ -485,15 +487,15 @@ read_cursor_view_create_for_mysql(
return(curview);
}
-/*************************************************************************
+/*********************************************************************//**
Close a given consistent cursor view for mysql and restore global read view
back to a transaction read view. */
UNIV_INTERN
void
read_cursor_view_close_for_mysql(
/*=============================*/
- trx_t* trx, /* in: trx */
- cursor_view_t* curview)/* in: cursor view to be closed */
+ trx_t* trx, /*!< in: trx */
+ cursor_view_t* curview)/*!< in: cursor view to be closed */
{
ut_a(curview);
ut_a(curview->read_view);
@@ -513,7 +515,7 @@ read_cursor_view_close_for_mysql(
mem_heap_free(curview->heap);
}
-/*************************************************************************
+/*********************************************************************//**
This function sets a given consistent cursor view to a transaction
read view if given consistent cursor view is not NULL. Otherwise, function
restores a global read view to a transaction read view. */
@@ -521,8 +523,8 @@ UNIV_INTERN
void
read_cursor_set_for_mysql(
/*======================*/
- trx_t* trx, /* in: transaction where cursor is set */
- cursor_view_t* curview)/* in: consistent cursor view to be set */
+ trx_t* trx, /*!< in: transaction where cursor is set */
+ cursor_view_t* curview)/*!< in: consistent cursor view to be set */
{
ut_a(trx);
diff --git a/storage/xtradb/rem/rem0cmp.c b/storage/xtradb/rem/rem0cmp.c
index f8e5a6b88ff..45230f1d7b1 100644
--- a/storage/xtradb/rem/rem0cmp.c
+++ b/storage/xtradb/rem/rem0cmp.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file rem/rem0cmp.c
Comparison services for records
Created 7/1/1994 Heikki Tuuri
@@ -35,7 +36,7 @@ Created 7/1/1994 Heikki Tuuri
The records are put into alphabetical order in the following
way: let F be the first field where two records disagree.
-If there is a character in some position n where the the
+If there is a character in some position n where the
records disagree, the order is determined by comparison of
the characters at position n, possibly after
collating transformation. If there is no such character,
@@ -50,75 +51,70 @@ where two records disagree only in the way that one
has more fields than the other. */
#ifdef UNIV_DEBUG
-/*****************************************************************
+/*************************************************************//**
Used in debug checking of cmp_dtuple_... .
This function is used to compare a data tuple to a physical record. If
dtuple has n fields then rec must have either m >= n fields, or it must
-differ from dtuple in some of the m fields rec has. */
+differ from dtuple in some of the m fields rec has.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared */
static
int
cmp_debug_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 which differs from
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record which differs from
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() */
- ulint* matched_fields);/* in/out: number of already
+ 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 */
#endif /* UNIV_DEBUG */
-#ifndef UNIV_HOTBACKUP
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two data fields for which the data type
is such that we must use MySQL code to compare them. The prototype here
-must be a copy of the the one in ha_innobase.cc! */
+must be a copy of the one in ha_innobase.cc!
+@return 1, 0, -1, if a is greater, equal, less than b, respectively */
extern
int
innobase_mysql_cmp(
/*===============*/
- /* out: 1, 0, -1, if a is greater,
- equal, less than b, respectively */
- int mysql_type, /* in: MySQL type */
- uint charset_number, /* in: number of the charset */
- const unsigned char* a, /* in: data field */
- unsigned int a_length, /* in: data field length,
+ int mysql_type, /*!< in: MySQL type */
+ uint charset_number, /*!< in: number of the charset */
+ const unsigned char* a, /*!< in: data field */
+ unsigned int a_length, /*!< in: data field length,
not UNIV_SQL_NULL */
- const unsigned char* b, /* in: data field */
- unsigned int b_length); /* in: data field length,
+ const unsigned char* b, /*!< in: data field */
+ unsigned int b_length); /*!< in: data field length,
not UNIV_SQL_NULL */
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Transforms the character code so that it is ordered appropriately for the
language. This is only used for the latin1 char set. MySQL does the
-comparisons for other char sets. */
+comparisons for other char sets.
+@return collation order position */
UNIV_INLINE
ulint
cmp_collate(
/*========*/
- /* out: collation order position */
- ulint code) /* in: code of a character stored in database record */
+ ulint code) /*!< in: code of a character stored in database record */
{
return((ulint) srv_latin1_ordering[code]);
}
-/*****************************************************************
-Returns TRUE if two columns are equal for comparison purposes. */
+/*************************************************************//**
+Returns TRUE if two columns are equal for comparison purposes.
+@return TRUE if the columns are considered equal in comparisons */
UNIV_INTERN
ibool
cmp_cols_are_equal(
/*===============*/
- /* out: TRUE if the columns are
- considered equal in comparisons */
- const dict_col_t* col1, /* in: column 1 */
- const dict_col_t* col2, /* in: column 2 */
+ const dict_col_t* col1, /*!< in: column 1 */
+ const dict_col_t* col2, /*!< in: column 2 */
ibool check_charsets)
- /* in: whether to check charsets */
+ /*!< in: whether to check charsets */
{
if (dtype_is_non_binary_string_type(col1->mtype, col1->prtype)
&& dtype_is_non_binary_string_type(col2->mtype, col2->prtype)) {
@@ -161,23 +157,21 @@ cmp_cols_are_equal(
return(col1->mtype != DATA_INT || col1->len == col2->len);
}
-#ifndef UNIV_HOTBACKUP
-/*****************************************************************
+/*************************************************************//**
Innobase uses this function to compare two data fields for which the data type
-is such that we must compare whole fields or call MySQL to do the comparison */
+is such that we must compare whole fields or call MySQL to do the comparison
+@return 1, 0, -1, if a is greater, equal, less than b, respectively */
static
int
cmp_whole_field(
/*============*/
- /* out: 1, 0, -1, if a is greater,
- equal, less than b, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* a, /* in: data field */
- unsigned int a_length, /* in: data field length,
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* a, /*!< in: data field */
+ unsigned int a_length, /*!< in: data field length,
not UNIV_SQL_NULL */
- const byte* b, /* in: data field */
- unsigned int b_length) /* in: data field length,
+ const byte* b, /*!< in: data field */
+ unsigned int b_length) /*!< in: data field length,
not UNIV_SQL_NULL */
{
float f_1;
@@ -288,27 +282,24 @@ cmp_whole_field(
return(0);
}
-#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two data fields for which we know the
-data type. */
+data type.
+@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
UNIV_INTERN
int
cmp_data_data_slow(
/*===============*/
- /* out: 1, 0, -1, if data1 is greater, equal,
- less than data2, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* data1, /* in: data field (== a pointer to a memory
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* data1, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len1, /* in: data field length or UNIV_SQL_NULL */
- const byte* data2, /* in: data field (== a pointer to a memory
+ ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
+ const byte* data2, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len2) /* in: data field length or UNIV_SQL_NULL */
+ ulint len2) /*!< in: data field length or UNIV_SQL_NULL */
{
-#ifndef UNIV_HOTBACKUP
ulint data1_byte;
ulint data2_byte;
ulint cur_bytes;
@@ -401,48 +392,39 @@ next_byte:
data1++;
data2++;
}
-#else /* !UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* !UNIV_HOTBACKUP */
return(0); /* Not reached */
}
-/*****************************************************************
+/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
-the the data tuple! If we denote by n = n_fields_cmp, then rec must
+the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
-made. */
+made.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared, or until
+the first externally stored field in rec */
UNIV_INTERN
int
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, or
- until the first externally stored field in
- rec */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record which differs from
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record which differs from
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() */
- ulint* matched_fields, /* in/out: number of already completely
+ 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
+ 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 */
{
-#ifndef UNIV_HOTBACKUP
const dfield_t* dtuple_field; /* current field in logical record */
ulint dtuple_f_len; /* the length of the current field
in the logical record */
@@ -650,27 +632,19 @@ order_resolved:
*matched_bytes = cur_bytes;
return(ret);
-#else /* !UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(0);
-#endif /* !UNIV_HOTBACKUP */
}
-/******************************************************************
-Compares a data tuple to a physical record. */
+/**************************************************************//**
+Compares a data tuple to a physical record.
+@see cmp_dtuple_rec_with_match
+@return 1, 0, -1, if dtuple is greater, equal, less than rec, respectively */
UNIV_INTERN
int
cmp_dtuple_rec(
/*===========*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively; see the comments
- for cmp_dtuple_rec_with_match */
- 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 dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint matched_fields = 0;
ulint matched_bytes = 0;
@@ -680,17 +654,17 @@ cmp_dtuple_rec(
&matched_fields, &matched_bytes));
}
-/******************************************************************
+/**************************************************************//**
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. */
+is allowed to be a prefix of the corresponding field in the record.
+@return TRUE if prefix */
UNIV_INTERN
ibool
cmp_dtuple_is_prefix_of_rec(
/*========================*/
- /* out: TRUE if prefix */
- 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 dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
ulint matched_fields = 0;
@@ -720,33 +694,31 @@ cmp_dtuple_is_prefix_of_rec(
return(FALSE);
}
-#ifndef UNIV_HOTBACKUP
-/*****************************************************************
+/*************************************************************//**
Compare two physical records that contain the same number of columns,
-none of which are stored externally. */
+none of which are stored externally.
+@return 1, 0, -1 if rec1 is greater, equal, less, respectively, than rec2 */
UNIV_INTERN
int
cmp_rec_rec_simple(
/*===============*/
- /* out: 1, 0 , -1 if rec1 is greater,
- equal, less, respectively, than rec2 */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- const dict_index_t* index) /* in: data dictionary index */
+ 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 dict_index_t* index) /*!< in: data dictionary index */
{
- ulint rec1_f_len; /* length of current field in rec1 */
- const byte* rec1_b_ptr; /* pointer to the current byte
+ ulint rec1_f_len; /*!< length of current field in rec1 */
+ const byte* rec1_b_ptr; /*!< pointer to the current byte
in rec1 field */
- ulint rec1_byte; /* value of current byte to be
+ ulint rec1_byte; /*!< value of current byte to be
compared in rec1 */
- ulint rec2_f_len; /* length of current field in rec2 */
- const byte* rec2_b_ptr; /* pointer to the current byte
+ ulint rec2_f_len; /*!< length of current field in rec2 */
+ const byte* rec2_b_ptr; /*!< pointer to the current byte
in rec2 field */
- ulint rec2_byte; /* value of current byte to be
+ ulint rec2_byte; /*!< value of current byte to be
compared in rec2 */
- ulint cur_field; /* current field number */
+ ulint cur_field; /*!< current field number */
ulint n_uniq;
n_uniq = dict_index_get_n_unique(index);
@@ -870,35 +842,31 @@ next_field:
/* If we ran out of fields, rec1 was equal to rec2. */
return(0);
}
-#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two physical records. Only the common
first fields are compared, and if an externally stored field is
-encountered, then 0 is returned. */
+encountered, then 0 is returned.
+@return 1, 0, -1 if rec1 is greater, equal, less, respectively */
UNIV_INTERN
int
cmp_rec_rec_with_match(
/*===================*/
- /* out: 1, 0 , -1 if rec1 is greater, equal,
- less, respectively, than rec2; only the common
- first fields are compared */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- dict_index_t* index, /* in: data dictionary index */
- ulint* matched_fields, /* in/out: number of already completely
+ const rec_t* rec1, /*!< in: physical record */
+ const rec_t* rec2, /*!< in: physical record */
+ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
+ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
+ dict_index_t* index, /*!< in: data dictionary index */
+ ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when the function returns,
contains the value the for current
comparison */
- ulint* matched_bytes, /* in/out: number of already matched
+ ulint* matched_bytes, /*!< in/out: number of already matched
bytes within the first field not completely
matched; when the function returns, contains
the value for the current comparison */
ulint stats_method)
{
-#ifndef UNIV_HOTBACKUP
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
@@ -1116,36 +1084,28 @@ order_resolved:
*matched_bytes = cur_bytes;
return(ret);
-#else /* !UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(0);
-#endif /* !UNIV_HOTBACKUP */
}
#ifdef UNIV_DEBUG
-/*****************************************************************
+/*************************************************************//**
Used in debug checking of cmp_dtuple_... .
This function is used to compare a data tuple to a physical record. If
dtuple has n fields then rec must have either m >= n fields, or it must
differ from dtuple in some of the m fields rec has. If encounters an
-externally stored field, returns 0. */
+externally stored field, returns 0.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared */
static
int
cmp_debug_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 which differs from
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record which differs from
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() */
- ulint* matched_fields) /* in/out: number of already
+ 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 */
diff --git a/storage/xtradb/rem/rem0rec.c b/storage/xtradb/rem/rem0rec.c
index d6899c810e3..1c8b3fd8c1e 100644
--- a/storage/xtradb/rem/rem0rec.c
+++ b/storage/xtradb/rem/rem0rec.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file rem/rem0rec.c
Record manager
Created 5/30/1994 Heikki Tuuri
@@ -143,26 +144,26 @@ the corresponding canonical strings have the same property. */
/* this is used to fool compiler in rec_validate */
UNIV_INTERN ulint rec_dummy;
-/*******************************************************************
-Validates the consistency of an old-style physical record. */
+/***************************************************************//**
+Validates the consistency of an old-style physical record.
+@return TRUE if ok */
static
ibool
rec_validate_old(
/*=============*/
- /* out: TRUE if ok */
- const rec_t* rec); /* in: physical record */
+ const rec_t* rec); /*!< in: physical record */
-/**********************************************************
+/******************************************************//**
Determine how many of the first n columns in a compact
-physical record are stored externally. */
+physical record are stored externally.
+@return number of externally stored columns */
UNIV_INTERN
ulint
rec_get_n_extern_new(
/*=================*/
- /* out: number of externally stored columns */
- const rec_t* rec, /* in: compact physical record */
- dict_index_t* index, /* in: record descriptor */
- ulint n) /* in: number of columns to scan */
+ const rec_t* rec, /*!< in: compact physical record */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n) /*!< in: number of columns to scan */
{
const byte* nulls;
const byte* lens;
@@ -227,7 +228,7 @@ rec_get_n_extern_new(
return(n_extern);
}
-/**********************************************************
+/******************************************************//**
Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT. This is a special case of
rec_init_offsets() and rec_get_offsets_func(). */
@@ -235,14 +236,14 @@ UNIV_INTERN
void
rec_init_offsets_comp_ordinary(
/*===========================*/
- const rec_t* rec, /* in: physical record in
+ const rec_t* rec, /*!< in: physical record in
ROW_FORMAT=COMPACT */
- ulint extra, /* in: number of bytes to reserve
+ ulint extra, /*!< in: number of bytes to reserve
between the record header and
the data payload
(usually REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets)/* in/out: array of offsets;
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
@@ -329,7 +330,7 @@ resolved:
= (rec - (lens + 1)) | REC_OFFS_COMPACT | any_ext;
}
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field in the
record. The offsets are written to a previously allocated array of
ulint, where rec_offs_n_fields(offsets) has been initialized to the
@@ -347,9 +348,9 @@ 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;
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
@@ -491,26 +492,26 @@ resolved:
}
}
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field
-in the record. It can reuse a previously returned array. */
+in the record. It can reuse a previously returned array.
+@return the new offsets */
UNIV_INTERN
ulint*
rec_get_offsets_func(
/*=================*/
- /* out: the new offsets */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets,/* in/out: array consisting of
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets,/*!< in/out: array consisting of
offsets[0] allocated elements,
or an array from rec_get_offsets(),
or NULL */
- ulint n_fields,/* in: maximum number of
+ ulint n_fields,/*!< in: maximum number of
initialized fields
(ULINT_UNDEFINED if all fields) */
- mem_heap_t** heap, /* in/out: memory heap */
- const char* file, /* in: file name where called */
- ulint line) /* in: line number where called */
+ mem_heap_t** heap, /*!< in/out: memory heap */
+ const char* file, /*!< in: file name where called */
+ ulint line) /*!< in: line number where called */
{
ulint n;
ulint size;
@@ -563,21 +564,21 @@ rec_get_offsets_func(
return(offsets);
}
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field
in the record. It can reuse a previously allocated array. */
UNIV_INTERN
void
rec_get_offsets_reverse(
/*====================*/
- const byte* extra, /* in: the extra bytes of a
+ const byte* extra, /*!< in: the extra bytes of a
compact record in reverse order,
excluding the fixed-size
REC_N_NEW_EXTRA_BYTES */
- const dict_index_t* index, /* in: record descriptor */
- ulint node_ptr,/* in: nonzero=node pointer,
+ 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
+ ulint* offsets)/*!< in/out: array consisting of
offsets[0] allocated elements */
{
ulint n;
@@ -678,17 +679,17 @@ resolved:
| REC_OFFS_COMPACT | any_ext;
}
-/****************************************************************
+/************************************************************//**
The following function is used to get the offset to the nth
-data field in an old-style record. */
+data field in an old-style record.
+@return offset to the field */
UNIV_INTERN
ulint
rec_get_nth_field_offs_old(
/*=======================*/
- /* out: offset to the field */
- const rec_t* rec, /* in: record */
- ulint n, /* in: index of the field */
- ulint* len) /* out: length of the field;
+ const rec_t* rec, /*!< in: record */
+ ulint n, /*!< in: index of the field */
+ ulint* len) /*!< out: length of the field;
UNIV_SQL_NULL if SQL null */
{
ulint os;
@@ -742,20 +743,20 @@ rec_get_nth_field_offs_old(
return(os);
}
-/**************************************************************
-Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. */
+/**********************************************************//**
+Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
+@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_comp_prefix(
/*===============================*/
- /* out: total size */
- const dict_index_t* index, /* in: record descriptor;
+ const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields,/* in: number of data fields */
- ulint* extra) /* out: extra size */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
{
ulint extra_size;
ulint data_size;
@@ -817,21 +818,21 @@ rec_get_converted_size_comp_prefix(
return(extra_size + data_size);
}
-/**************************************************************
-Determines the size of a data tuple in ROW_FORMAT=COMPACT. */
+/**********************************************************//**
+Determines the size of a data tuple in ROW_FORMAT=COMPACT.
+@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_comp(
/*========================*/
- /* out: total size */
- const dict_index_t* index, /* in: record descriptor;
+ const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
- ulint status, /* in: status bits of the record */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields,/* in: number of data fields */
- ulint* extra) /* out: extra size */
+ ulint status, /*!< in: status bits of the record */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
{
ulint size;
ut_ad(index);
@@ -865,15 +866,15 @@ rec_get_converted_size_comp(
n_fields, extra));
}
-/***************************************************************
+/***********************************************************//**
Sets the value of the ith field SQL null bit of an old-style record. */
UNIV_INTERN
void
rec_set_nth_field_null_bit(
/*=======================*/
- rec_t* rec, /* in: record */
- ulint i, /* in: ith field */
- ibool val) /* in: value to set */
+ rec_t* rec, /*!< in: record */
+ ulint i, /*!< in: ith field */
+ ibool val) /*!< in: value to set */
{
ulint info;
@@ -903,15 +904,15 @@ rec_set_nth_field_null_bit(
rec_2_set_field_end_info(rec, i, info);
}
-/***************************************************************
+/***********************************************************//**
Sets an old-style record field to SQL null.
The physical size of the field is not changed. */
UNIV_INTERN
void
rec_set_nth_field_sql_null(
/*=======================*/
- rec_t* rec, /* in: record */
- ulint n) /* in: index of the field */
+ rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: index of the field */
{
ulint offset;
@@ -922,18 +923,17 @@ rec_set_nth_field_sql_null(
rec_set_nth_field_null_bit(rec, n, TRUE);
}
-/*************************************************************
+/*********************************************************//**
Builds an old-style physical record out of a data tuple and
-stores it beginning from the start of the given buffer. */
+stores it beginning from the start of the given buffer.
+@return pointer to the origin of physical record */
static
rec_t*
rec_convert_dtuple_to_rec_old(
/*==========================*/
- /* out: pointer to the origin of
- physical record */
- byte* buf, /* in: start address of the physical record */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext) /* in: number of externally stored columns */
+ byte* buf, /*!< in: start address of the physical record */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext) /*!< in: number of externally stored columns */
{
const dfield_t* field;
ulint n_fields;
@@ -949,7 +949,7 @@ rec_convert_dtuple_to_rec_old(
ut_ad(dtuple_check_typed(dtuple));
n_fields = dtuple_get_n_fields(dtuple);
- data_size = dtuple_get_data_size(dtuple);
+ data_size = dtuple_get_data_size(dtuple, 0);
ut_ad(n_fields > 0);
@@ -982,7 +982,7 @@ rec_convert_dtuple_to_rec_old(
if (dfield_is_null(field)) {
len = dtype_get_sql_null_size(
- dfield_get_type(field));
+ dfield_get_type(field), 0);
data_write_sql_null(rec + end_offset, len);
end_offset += len;
@@ -1010,7 +1010,7 @@ rec_convert_dtuple_to_rec_old(
if (dfield_is_null(field)) {
len = dtype_get_sql_null_size(
- dfield_get_type(field));
+ dfield_get_type(field), 0);
data_write_sql_null(rec + end_offset, len);
end_offset += len;
@@ -1038,21 +1038,21 @@ rec_convert_dtuple_to_rec_old(
return(rec);
}
-/*************************************************************
+/*********************************************************//**
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
UNIV_INTERN
void
rec_convert_dtuple_to_rec_comp(
/*===========================*/
- rec_t* rec, /* in: origin of record */
- ulint extra, /* in: number of bytes to
+ rec_t* rec, /*!< in: origin of record */
+ ulint extra, /*!< in: number of bytes to
reserve between the record
header and the data payload
(normally REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /* in: record descriptor */
- ulint status, /* in: status bits of the record */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields)/* in: number of data fields */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint status, /*!< in: status bits of the record */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields)/*!< in: number of data fields */
{
const dfield_t* field;
const dtype_t* type;
@@ -1160,19 +1160,18 @@ rec_convert_dtuple_to_rec_comp(
}
}
-/*************************************************************
+/*********************************************************//**
Builds a new-style physical record out of a data tuple and
-stores it beginning from the start of the given buffer. */
+stores it beginning from the start of the given buffer.
+@return pointer to the origin of physical record */
static
rec_t*
rec_convert_dtuple_to_rec_new(
/*==========================*/
- /* out: pointer to the origin
- of physical record */
- byte* buf, /* in: start address of
+ byte* buf, /*!< in: start address of
the physical record */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple) /* in: data tuple */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple) /*!< in: data tuple */
{
ulint extra_size;
ulint status;
@@ -1194,20 +1193,19 @@ rec_convert_dtuple_to_rec_new(
return(rec);
}
-/*************************************************************
+/*********************************************************//**
Builds a physical record out of a data tuple and
-stores it beginning from the start of the given buffer. */
+stores it beginning from the start of the given buffer.
+@return pointer to the origin of physical record */
UNIV_INTERN
rec_t*
rec_convert_dtuple_to_rec(
/*======================*/
- /* out: pointer to the origin
- of physical record */
- byte* buf, /* in: start address of the
+ byte* buf, /*!< in: start address of the
physical record */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext) /* in: number of
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext) /*!< in: number of
externally stored columns */
{
rec_t* rec;
@@ -1240,19 +1238,19 @@ rec_convert_dtuple_to_rec(
return(rec);
}
-/******************************************************************
+/**************************************************************//**
Copies the first n fields of a physical record to a data tuple. The fields
are copied to the memory heap. */
UNIV_INTERN
void
rec_copy_prefix_to_dtuple(
/*======================*/
- dtuple_t* tuple, /* out: data tuple */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint n_fields, /* in: number of fields
+ dtuple_t* tuple, /*!< out: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint n_fields, /*!< in: number of fields
to copy */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ulint i;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -1285,20 +1283,20 @@ rec_copy_prefix_to_dtuple(
}
}
-/******************************************************************
+/**************************************************************//**
Copies the first n fields of an old-style physical record
-to a new physical record in a buffer. */
+to a new physical record in a buffer.
+@return own: copied record */
static
rec_t*
rec_copy_prefix_to_buf_old(
/*=======================*/
- /* out, own: copied record */
- const rec_t* rec, /* in: physical record */
- ulint n_fields, /* in: number of fields to copy */
- ulint area_end, /* in: end of the prefix data */
- byte** buf, /* in/out: memory buffer for
+ const rec_t* rec, /*!< in: physical record */
+ ulint n_fields, /*!< in: number of fields to copy */
+ ulint area_end, /*!< in: end of the prefix data */
+ byte** buf, /*!< in/out: memory buffer for
the copied prefix, or NULL */
- ulint* buf_size) /* in/out: buffer size */
+ ulint* buf_size) /*!< in/out: buffer size */
{
rec_t* copy_rec;
ulint area_start;
@@ -1329,22 +1327,22 @@ rec_copy_prefix_to_buf_old(
return(copy_rec);
}
-/******************************************************************
+/**************************************************************//**
Copies the first n fields of a physical record to a new physical record in
-a buffer. */
+a buffer.
+@return own: copied record */
UNIV_INTERN
rec_t*
rec_copy_prefix_to_buf(
/*===================*/
- /* out, own: copied record */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint n_fields, /* in: number of fields
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint n_fields, /*!< in: number of fields
to copy */
- byte** buf, /* in/out: memory buffer
+ byte** buf, /*!< in/out: memory buffer
for the copied prefix,
or NULL */
- ulint* buf_size) /* in/out: buffer size */
+ ulint* buf_size) /*!< in/out: buffer size */
{
const byte* nulls;
const byte* lens;
@@ -1444,14 +1442,14 @@ rec_copy_prefix_to_buf(
return(*buf + (rec - (lens + 1)));
}
-/*******************************************************************
-Validates the consistency of an old-style physical record. */
+/***************************************************************//**
+Validates the consistency of an old-style physical record.
+@return TRUE if ok */
static
ibool
rec_validate_old(
/*=============*/
- /* out: TRUE if ok */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
const byte* data;
ulint len;
@@ -1504,15 +1502,15 @@ rec_validate_old(
return(TRUE);
}
-/*******************************************************************
-Validates the consistency of a physical record. */
+/***************************************************************//**
+Validates the consistency of a physical record.
+@return TRUE if ok */
UNIV_INTERN
ibool
rec_validate(
/*=========*/
- /* out: TRUE if ok */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
const byte* data;
ulint len;
@@ -1571,14 +1569,14 @@ rec_validate(
return(TRUE);
}
-/*******************************************************************
+/***************************************************************//**
Prints an old-style physical record. */
UNIV_INTERN
void
rec_print_old(
/*==========*/
- FILE* file, /* in: file where to print */
- const rec_t* rec) /* in: physical record */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec) /*!< in: physical record */
{
const byte* data;
ulint len;
@@ -1623,16 +1621,17 @@ rec_print_old(
rec_validate_old(rec);
}
-/*******************************************************************
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Prints a physical record in ROW_FORMAT=COMPACT. Ignores the
record header. */
UNIV_INTERN
void
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() */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint i;
@@ -1662,15 +1661,15 @@ rec_print_comp(
}
}
-/*******************************************************************
+/***************************************************************//**
Prints a physical record. */
UNIV_INTERN
void
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() */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec);
ut_ad(offsets);
@@ -1690,15 +1689,15 @@ rec_print_new(
rec_validate(rec, offsets);
}
-/*******************************************************************
+/***************************************************************//**
Prints a physical record. */
UNIV_INTERN
void
rec_print(
/*======*/
- FILE* file, /* in: file where to print */
- const rec_t* rec, /* in: physical record */
- dict_index_t* index) /* in: record descriptor */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ dict_index_t* index) /*!< in: record descriptor */
{
ut_ad(index);
@@ -1718,3 +1717,4 @@ rec_print(
}
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/row/row0ext.c b/storage/xtradb/row/row0ext.c
index 83dfa024ffc..7320f5b1dca 100644
--- a/storage/xtradb/row/row0ext.c
+++ b/storage/xtradb/row/row0ext.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0ext.c
Caching of externally stored column prefixes
Created September 2006 Marko Makela
@@ -30,16 +31,16 @@ Created September 2006 Marko Makela
#include "btr0cur.h"
-/************************************************************************
+/********************************************************************//**
Fills the column prefix cache of an externally stored column. */
static
void
row_ext_cache_fill(
/*===============*/
- row_ext_t* ext, /* in/out: column prefix cache */
- ulint i, /* in: index of ext->ext[] */
- ulint zip_size,/* compressed page size in bytes, or 0 */
- const dfield_t* dfield) /* in: data field */
+ row_ext_t* ext, /*!< in/out: column prefix cache */
+ ulint i, /*!< in: index of ext->ext[] */
+ ulint zip_size,/*!< compressed page size in bytes, or 0 */
+ const dfield_t* dfield) /*!< in: data field */
{
const byte* field = dfield_get_data(dfield);
ulint f_len = dfield_get_len(dfield);
@@ -66,26 +67,26 @@ row_ext_cache_fill(
}
}
-/************************************************************************
-Creates a cache of column prefixes of externally stored columns. */
+/********************************************************************//**
+Creates a cache of column prefixes of externally stored columns.
+@return own: column prefix cache */
UNIV_INTERN
row_ext_t*
row_ext_create(
/*===========*/
- /* out,own: column prefix cache */
- ulint n_ext, /* in: number of externally stored columns */
- const ulint* ext, /* in: col_no's of externally stored columns
+ ulint n_ext, /*!< in: number of externally stored columns */
+ const ulint* ext, /*!< in: col_no's of externally stored columns
in the InnoDB table object, as reported by
dict_col_get_no(); NOT relative to the records
in the clustered index */
- const dtuple_t* tuple, /* in: data tuple containing the field
+ const dtuple_t* tuple, /*!< in: data tuple containing the field
references of the externally stored
columns; must be indexed by col_no;
the clustered index record must be
covered by a lock or a page latch
to prevent deletion (rollback or purge). */
- ulint zip_size,/* compressed page size in bytes, or 0 */
- mem_heap_t* heap) /* in: heap where created */
+ ulint zip_size,/*!< compressed page size in bytes, or 0 */
+ mem_heap_t* heap) /*!< in: heap where created */
{
ulint i;
row_ext_t* ret = mem_heap_alloc(heap, (sizeof *ret)
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index ceb0f7d75a2..fe51fce82c4 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0ins.c
Insert into a table
Created 4/20/1996 Heikki Tuuri
@@ -28,6 +29,7 @@ Created 4/20/1996 Heikki Tuuri
#include "row0ins.ic"
#endif
+#include "ha_prototypes.h"
#include "dict0dict.h"
#include "dict0boot.h"
#include "trx0undo.h"
@@ -50,33 +52,16 @@ Created 4/20/1996 Heikki Tuuri
#define ROW_INS_NEXT 2
-/*********************************************************************
-This prototype is copied from /mysql/sql/ha_innodb.cc.
-Invalidates the MySQL query cache for the table.
-NOTE that the exact prototype of this function has to be in
-/xtradb/row/row0ins.c! */
-extern
-void
-innobase_invalidate_query_cache(
-/*============================*/
- trx_t* trx, /* in: transaction which modifies the table */
- char* full_name, /* in: concatenation of database name, null
- char '\0', table name, null char'\0';
- NOTE that in Windows this is always
- in LOWER CASE! */
- ulint full_name_len); /* in: full name length where also the null
- chars count */
-
-/*************************************************************************
-Creates an insert node struct. */
+/*********************************************************************//**
+Creates an insert node struct.
+@return own: insert node struct */
UNIV_INTERN
ins_node_t*
ins_node_create(
/*============*/
- /* out, own: insert node struct */
- ulint ins_type, /* in: INS_VALUES, ... */
- dict_table_t* table, /* in: table where to insert */
- mem_heap_t* heap) /* in: mem heap where created */
+ ulint ins_type, /*!< in: INS_VALUES, ... */
+ dict_table_t* table, /*!< in: table where to insert */
+ mem_heap_t* heap) /*!< in: mem heap where created */
{
ins_node_t* node;
@@ -102,13 +87,13 @@ ins_node_create(
return(node);
}
-/***************************************************************
+/***********************************************************//**
Creates an entry template for each index of a table. */
UNIV_INTERN
void
ins_node_create_entry_list(
/*=======================*/
- ins_node_t* node) /* in: row insert node */
+ ins_node_t* node) /*!< in: row insert node */
{
dict_index_t* index;
dtuple_t* entry;
@@ -128,13 +113,13 @@ ins_node_create_entry_list(
}
}
-/*********************************************************************
+/*****************************************************************//**
Adds system field buffers to a row. */
static
void
row_ins_alloc_sys_fields(
/*=====================*/
- ins_node_t* node) /* in: insert node */
+ ins_node_t* node) /*!< in: insert node */
{
dtuple_t* row;
dict_table_t* table;
@@ -156,7 +141,7 @@ row_ins_alloc_sys_fields(
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROW_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROW_ID_LEN);
dfield_set_data(dfield, ptr, DATA_ROW_ID_LEN);
@@ -167,7 +152,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_TRX_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_TRX_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_TRX_ID_LEN);
dfield_set_data(dfield, ptr, DATA_TRX_ID_LEN);
@@ -178,12 +163,12 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_ROLL_PTR);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROLL_PTR_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROLL_PTR_LEN);
dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
}
-/*************************************************************************
+/*********************************************************************//**
Sets a new row to insert for an INS_DIRECT node. This function is only used
if we have constructed the row separately, which is a rare case; this
function is quite slow. */
@@ -191,8 +176,8 @@ UNIV_INTERN
void
ins_node_set_new_row(
/*=================*/
- ins_node_t* node, /* in: insert node */
- dtuple_t* row) /* in: new row (or first row) for the node */
+ ins_node_t* node, /*!< in: insert node */
+ dtuple_t* row) /*!< in: new row (or first row) for the node */
{
node->state = INS_NODE_SET_IX_LOCK;
node->index = NULL;
@@ -216,22 +201,22 @@ ins_node_set_new_row(
node->trx_id = ut_dulint_zero;
}
-/***********************************************************************
+/*******************************************************************//**
Does an insert operation by updating a delete-marked existing record
in the index. This situation can occur if the delete-marked record is
-kept in the index for consistent reads. */
+kept in the index for consistent reads.
+@return DB_SUCCESS or error code */
static
ulint
row_ins_sec_index_entry_by_modify(
/*==============================*/
- /* out: DB_SUCCESS or error code */
- ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether mtr holds just a leaf
latch or also a tree latch */
- btr_cur_t* cursor, /* in: B-tree cursor */
- const dtuple_t* entry, /* in: index entry to insert */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ btr_cur_t* cursor, /*!< in: B-tree cursor */
+ const dtuple_t* entry, /*!< in: index entry to insert */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
big_rec_t* dummy_big_rec;
@@ -287,26 +272,26 @@ func_exit:
return(err);
}
-/***********************************************************************
+/*******************************************************************//**
Does an insert operation by delete unmarking and updating a delete marked
existing record in the index. This situation can occur if the delete marked
-record is kept in the index for consistent reads. */
+record is kept in the index for consistent reads.
+@return DB_SUCCESS, DB_FAIL, or error code */
static
ulint
row_ins_clust_index_entry_by_modify(
/*================================*/
- /* out: DB_SUCCESS, DB_FAIL, or error code */
- ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether mtr holds just a leaf
latch or also a tree latch */
- btr_cur_t* cursor, /* in: B-tree cursor */
- mem_heap_t** heap, /* in/out: pointer to memory heap, or NULL */
- big_rec_t** big_rec,/* out: possible big rec vector of fields
+ btr_cur_t* cursor, /*!< in: B-tree cursor */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ big_rec_t** big_rec,/*!< out: possible big rec vector of fields
which have to be stored externally by the
caller */
- const dtuple_t* entry, /* in: index entry to insert */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ const dtuple_t* entry, /*!< in: index entry to insert */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
rec_t* rec;
@@ -359,16 +344,16 @@ row_ins_clust_index_entry_by_modify(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Returns TRUE if in a cascaded update/delete an ancestor node of node
-updates (not DELETE, but UPDATE) table. */
+updates (not DELETE, but UPDATE) table.
+@return TRUE if an ancestor updates table */
static
ibool
row_ins_cascade_ancestor_updates_table(
/*===================================*/
- /* out: TRUE if an ancestor updates table */
- que_node_t* node, /* in: node in a query graph */
- dict_table_t* table) /* in: table */
+ que_node_t* node, /*!< in: node in a query graph */
+ dict_table_t* table) /*!< in: table */
{
que_node_t* parent;
upd_node_t* upd_node;
@@ -392,15 +377,15 @@ row_ins_cascade_ancestor_updates_table(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Returns the number of ancestor UPDATE or DELETE nodes of a
-cascaded update/delete node. */
+cascaded update/delete node.
+@return number of ancestors */
static
ulint
row_ins_cascade_n_ancestors(
/*========================*/
- /* out: number of ancestors */
- que_node_t* node) /* in: node in a query graph */
+ que_node_t* node) /*!< in: node in a query graph */
{
que_node_t* parent;
ulint n_ancestors = 0;
@@ -418,26 +403,22 @@ row_ins_cascade_n_ancestors(
return(n_ancestors);
}
-/**********************************************************************
+/******************************************************************//**
Calculates the update vector node->cascade->update for a child table in
-a cascaded update. */
+a cascaded update.
+@return number of fields in the calculated update vector; the value
+can also be 0 if no foreign key fields changed; the returned value is
+ULINT_UNDEFINED if the column type in the child table is too short to
+fit the new value in the parent table: that means the update fails */
static
ulint
row_ins_cascade_calc_update_vec(
/*============================*/
- /* out: number of fields in the
- calculated update vector; the value
- can also be 0 if no foreign key
- fields changed; the returned value
- is ULINT_UNDEFINED if the column
- type in the child table is too short
- to fit the new value in the parent
- table: that means the update fails */
- upd_node_t* node, /* in: update node of the parent
+ upd_node_t* node, /*!< in: update node of the parent
table */
- dict_foreign_t* foreign, /* in: foreign key constraint whose
+ dict_foreign_t* foreign, /*!< in: foreign key constraint whose
type is != 0 */
- mem_heap_t* heap) /* in: memory heap to use as
+ mem_heap_t* heap) /*!< in: memory heap to use as
temporary storage */
{
upd_node_t* cascade = node->cascade_node;
@@ -606,15 +587,15 @@ row_ins_cascade_calc_update_vec(
return(n_fields_updated);
}
-/*************************************************************************
+/*********************************************************************//**
Set detailed error message associated with foreign key errors for
the given transaction. */
static
void
row_ins_set_detailed(
/*=================*/
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign) /* in: foreign key constraint */
+ trx_t* trx, /*!< in: transaction */
+ dict_foreign_t* foreign) /*!< in: foreign key constraint */
{
mutex_enter(&srv_misc_tmpfile_mutex);
rewind(srv_misc_tmpfile);
@@ -632,21 +613,21 @@ row_ins_set_detailed(
mutex_exit(&srv_misc_tmpfile_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Reports a foreign key error associated with an update or a delete of a
parent table index entry. */
static
void
row_ins_foreign_report_err(
/*=======================*/
- const char* errstr, /* in: error string from the viewpoint
+ const char* errstr, /*!< in: error string from the viewpoint
of the parent table */
- que_thr_t* thr, /* in: query thread whose run_node
+ que_thr_t* thr, /*!< in: query thread whose run_node
is an update node */
- dict_foreign_t* foreign, /* in: foreign key constraint */
- const rec_t* rec, /* in: a matching index record in the
+ dict_foreign_t* foreign, /*!< in: foreign key constraint */
+ const rec_t* rec, /*!< in: a matching index record in the
child table */
- const dtuple_t* entry) /* in: index entry in the parent
+ const dtuple_t* entry) /*!< in: index entry in the parent
table */
{
FILE* ef = dict_foreign_err_file;
@@ -688,7 +669,7 @@ row_ins_foreign_report_err(
mutex_exit(&dict_foreign_err_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Reports a foreign key error to dict_foreign_err_file when we are trying
to add an index entry to a child table. Note that the adding may be the result
of an update, too. */
@@ -696,12 +677,12 @@ static
void
row_ins_foreign_report_add_err(
/*===========================*/
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign, /* in: foreign key constraint */
- const rec_t* rec, /* in: a record in the parent table:
+ trx_t* trx, /*!< in: transaction */
+ dict_foreign_t* foreign, /*!< in: foreign key constraint */
+ const rec_t* rec, /*!< in: a record in the parent table:
it does not match entry because we
have an error! */
- const dtuple_t* entry) /* in: index entry to insert in the
+ const dtuple_t* entry) /*!< in: index entry to insert in the
child table */
{
FILE* ef = dict_foreign_err_file;
@@ -746,15 +727,15 @@ row_ins_foreign_report_add_err(
mutex_exit(&dict_foreign_err_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Invalidate the query cache for the given table. */
static
void
row_ins_invalidate_query_cache(
/*===========================*/
- que_thr_t* thr, /* in: query thread whose run_node
+ que_thr_t* thr, /*!< in: query thread whose run_node
is an update node */
- const char* name) /* in: table name prefixed with
+ const char* name) /*!< in: table name prefixed with
database name and a '/' character */
{
char* buf;
@@ -767,32 +748,28 @@ row_ins_invalidate_query_cache(
ut_a(ptr);
*ptr = '\0';
- /* We call a function in ha_innodb.cc */
-#ifndef UNIV_HOTBACKUP
innobase_invalidate_query_cache(thr_get_trx(thr), buf, len);
-#endif
mem_free(buf);
}
-/*************************************************************************
+/*********************************************************************//**
Perform referential actions or checks when a parent row is deleted or updated
and the constraint had an ON DELETE or ON UPDATE condition which was not
-RESTRICT. */
+RESTRICT.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
static
ulint
row_ins_foreign_check_on_constraint(
/*================================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- or error code */
- que_thr_t* thr, /* in: query thread whose run_node
+ que_thr_t* thr, /*!< in: query thread whose run_node
is an update node */
- dict_foreign_t* foreign, /* in: foreign key constraint whose
+ dict_foreign_t* foreign, /*!< in: foreign key constraint whose
type is != 0 */
- btr_pcur_t* pcur, /* in: cursor placed on a matching
+ btr_pcur_t* pcur, /*!< in: cursor placed on a matching
index record in the child table */
- dtuple_t* entry, /* in: index entry in the parent
+ dtuple_t* entry, /*!< in: index entry in the parent
table */
- mtr_t* mtr) /* in: mtr holding the latch of pcur
+ mtr_t* mtr) /*!< in: mtr holding the latch of pcur
page */
{
upd_node_t* node;
@@ -1141,21 +1118,21 @@ nonstandard_exit_func:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Sets a shared lock on a record. Used in locking possible duplicate key
-records and also in checking foreign key constraints. */
+records and also in checking foreign key constraints.
+@return DB_SUCCESS or error code */
static
ulint
row_ins_set_shared_rec_lock(
/*========================*/
- /* out: DB_SUCCESS or error code */
- ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP type 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) */
- que_thr_t* thr) /* in: query thread */
+ 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) */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -1172,22 +1149,21 @@ row_ins_set_shared_rec_lock(
return(err);
}
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+/*********************************************************************//**
Sets a exclusive lock on a record. Used in locking possible duplicate key
-records */
+records
+@return DB_SUCCESS or error code */
static
ulint
row_ins_set_exclusive_rec_lock(
/*===========================*/
- /* out: DB_SUCCESS or error code */
- ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP type 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) */
- que_thr_t* thr) /* in: query thread */
+ 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) */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -1203,29 +1179,26 @@ row_ins_set_exclusive_rec_lock(
return(err);
}
-#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Checks if foreign key constraint fails for an index entry. Sets shared locks
which lock either the success or the failure of the constraint. NOTE that
-the caller must have a shared latch on dict_operation_lock. */
+the caller must have a shared latch on dict_operation_lock.
+@return DB_SUCCESS, DB_NO_REFERENCED_ROW, or DB_ROW_IS_REFERENCED */
UNIV_INTERN
ulint
row_ins_check_foreign_constraint(
/*=============================*/
- /* out: DB_SUCCESS,
- DB_NO_REFERENCED_ROW,
- or DB_ROW_IS_REFERENCED */
- ibool check_ref,/* in: TRUE if we want to check that
+ ibool check_ref,/*!< in: TRUE if we want to check that
the referenced table is ok, FALSE if we
- want to to check the foreign key table */
- dict_foreign_t* foreign,/* in: foreign constraint; NOTE that the
+ want to check the foreign key table */
+ dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
- dict_table_t* table, /* in: if check_ref is TRUE, then the foreign
+ dict_table_t* table, /*!< in: if check_ref is TRUE, then the foreign
table, else the referenced table */
- dtuple_t* entry, /* in: index entry for index */
- que_thr_t* thr) /* in: query thread */
+ dtuple_t* entry, /*!< in: index entry for index */
+ que_thr_t* thr) /*!< in: query thread */
{
upd_node_t* upd_node;
dict_table_t* check_table;
@@ -1529,21 +1502,21 @@ exit_func:
return(err);
}
-/*******************************************************************
+/***************************************************************//**
Checks if foreign key constraints fail for an index entry. If index
is not mentioned in any constraint, this function does nothing,
Otherwise does searches to the indexes of referenced tables and
sets shared locks which lock either the success or the failure of
-a constraint. */
+a constraint.
+@return DB_SUCCESS or error code */
static
ulint
row_ins_check_foreign_constraints(
/*==============================*/
- /* out: DB_SUCCESS or error code */
- dict_table_t* table, /* in: table */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry for index */
- que_thr_t* thr) /* in: query thread */
+ dict_table_t* table, /*!< in: table */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry for index */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_foreign_t* foreign;
ulint err;
@@ -1611,21 +1584,20 @@ row_ins_check_foreign_constraints(
return(DB_SUCCESS);
}
-#ifndef UNIV_HOTBACKUP
-/*******************************************************************
+/***************************************************************//**
Checks if a unique key violation to rec would occur at the index entry
-insert. */
+insert.
+@return TRUE if error */
static
ibool
row_ins_dupl_error_with_rec(
/*========================*/
- /* out: TRUE if error */
- const rec_t* rec, /* in: user record; NOTE that we assume
+ const rec_t* rec, /*!< in: user record; NOTE that we assume
that the caller already has a record lock on
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 dtuple_t* entry, /*!< in: entry to insert */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint matched_fields;
ulint matched_bytes;
@@ -1663,23 +1635,20 @@ row_ins_dupl_error_with_rec(
return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
}
-#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Scans a unique non-clustered index at a given index entry to determine
whether a uniqueness violation has occurred for the key value of the entry.
-Set shared locks on possible duplicate records. */
+Set shared locks on possible duplicate records.
+@return DB_SUCCESS, DB_DUPLICATE_KEY, or DB_LOCK_WAIT */
static
ulint
row_ins_scan_sec_index_for_duplicate(
/*=================================*/
- /* out: DB_SUCCESS, DB_DUPLICATE_KEY, or
- DB_LOCK_WAIT */
- dict_index_t* index, /* in: non-clustered unique index */
- dtuple_t* entry, /* in: index entry */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: non-clustered unique index */
+ dtuple_t* entry, /*!< in: index entry */
+ que_thr_t* thr) /*!< in: query thread */
{
-#ifndef UNIV_HOTBACKUP
ulint n_unique;
ulint i;
int cmp;
@@ -1789,33 +1758,24 @@ row_ins_scan_sec_index_for_duplicate(
dtuple_set_n_fields_cmp(entry, n_fields_cmp);
return(err);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(DB_FAIL);
-#endif /* UNIV_HOTBACKUP */
}
-/*******************************************************************
+/***************************************************************//**
Checks if a unique key violation error would occur at an index entry
insert. Sets shared locks on possible duplicate records. Works only
-for a clustered index! */
+for a clustered index!
+@return DB_SUCCESS if no error, DB_DUPLICATE_KEY if error,
+DB_LOCK_WAIT if we have to wait for a lock on a possible duplicate
+record */
static
ulint
row_ins_duplicate_error_in_clust(
/*=============================*/
- /* out: DB_SUCCESS if no error,
- DB_DUPLICATE_KEY if error, DB_LOCK_WAIT if we
- have to wait for a lock on a possible
- duplicate record */
- btr_cur_t* cursor, /* in: B-tree cursor */
- dtuple_t* entry, /* in: entry to insert */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
+ btr_cur_t* cursor, /*!< in: B-tree cursor */
+ dtuple_t* entry, /*!< in: entry to insert */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
{
-#ifndef UNIV_HOTBACKUP
ulint err;
rec_t* rec;
ulint n_unique;
@@ -1939,31 +1899,22 @@ func_exit:
mem_heap_free(heap);
}
return(err);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(DB_FAIL);
-#endif /* UNIV_HOTBACKUP */
}
-/*******************************************************************
+/***************************************************************//**
Checks if an index entry has long enough common prefix with an existing
record so that the intended insert of the entry must be changed to a modify of
the existing record. In the case of a clustered index, the prefix must be
n_unique fields long, and in the case of a secondary index, all fields must be
-equal. */
+equal.
+@return 0 if no update, ROW_INS_PREV if previous should be updated;
+currently we do the search so that only the low_match record can match
+enough to the search tuple, not the next record */
UNIV_INLINE
ulint
row_ins_must_modify(
/*================*/
- /* out: 0 if no update, ROW_INS_PREV if
- previous should be updated; currently we
- do the search so that only the low_match
- record can match enough to the search tuple,
- not the next record */
- btr_cur_t* cursor) /* in: B-tree cursor */
+ btr_cur_t* cursor) /*!< in: B-tree cursor */
{
ulint enough_match;
rec_t* rec;
@@ -1990,7 +1941,7 @@ row_ins_must_modify(
return(0);
}
-/*******************************************************************
+/***************************************************************//**
Tries to insert an index entry to an index. If the index is clustered
and a record with the same unique key is found, the other record is
necessarily marked deleted by a committed transaction, or a unique key
@@ -1998,20 +1949,20 @@ violation error occurs. The delete marked record is then updated to an
existing record, and we must write an undo log record on the delete
marked record. If the index is secondary, and a record with exactly the
same fields is found, the other record is necessarily marked deleted.
-It is then unmarked. Otherwise, the entry is just inserted to the index. */
+It is then unmarked. Otherwise, the entry is just inserted to the index.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL if pessimistic retry needed,
+or error code */
static
ulint
row_ins_index_entry_low(
/*====================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL
- if pessimistic retry needed, or error code */
- ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether we wish optimistic or
pessimistic descent down the index tree */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry to insert */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr) /*!< in: query thread */
{
btr_cur_t cursor;
ulint ignore_sec_unique = 0;
@@ -2177,22 +2128,21 @@ function_exit:
return(err);
}
-/*******************************************************************
+/***************************************************************//**
Inserts an index entry to index. Tries first optimistic, then pessimistic
descent down the tree. If the entry matches enough to a delete marked record,
performs the insert by updating or delete unmarking the delete marked
-record. */
+record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
UNIV_INTERN
ulint
row_ins_index_entry(
/*================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DUPLICATE_KEY, or some other error code */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry to insert */
- ulint n_ext, /* in: number of externally stored columns */
- ibool foreign,/* in: TRUE=check foreign key constraints */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ ibool foreign,/*!< in: TRUE=check foreign key constraints */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -2221,16 +2171,16 @@ row_ins_index_entry(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Sets the values of the dtuple fields in entry from the values of appropriate
columns in row. */
static
void
row_ins_index_entry_set_vals(
/*=========================*/
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry to make */
- const dtuple_t* row) /* in: row */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry to make */
+ const dtuple_t* row) /*!< in: row */
{
ulint n_fields;
ulint i;
@@ -2273,16 +2223,16 @@ row_ins_index_entry_set_vals(
}
}
-/***************************************************************
-Inserts a single index entry to the table. */
+/***********************************************************//**
+Inserts a single index entry to the table.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_ins_index_entry_step(
/*=====================*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- ins_node_t* node, /* in: row insert node */
- que_thr_t* thr) /* in: query thread */
+ ins_node_t* node, /*!< in: row insert node */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -2297,13 +2247,13 @@ row_ins_index_entry_step(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Allocates a row id for row and inits the node->index field. */
UNIV_INLINE
void
row_ins_alloc_row_id_step(
/*======================*/
- ins_node_t* node) /* in: row insert node */
+ ins_node_t* node) /*!< in: row insert node */
{
dulint row_id;
@@ -2323,13 +2273,13 @@ row_ins_alloc_row_id_step(
dict_sys_write_row_id(node->row_id_buf, row_id);
}
-/***************************************************************
+/***********************************************************//**
Gets a row to insert from the values list. */
UNIV_INLINE
void
row_ins_get_row_from_values(
/*========================*/
- ins_node_t* node) /* in: row insert node */
+ ins_node_t* node) /*!< in: row insert node */
{
que_node_t* list_node;
dfield_t* dfield;
@@ -2356,13 +2306,13 @@ row_ins_get_row_from_values(
}
}
-/***************************************************************
+/***********************************************************//**
Gets a row to insert from the select list. */
UNIV_INLINE
void
row_ins_get_row_from_select(
/*========================*/
- ins_node_t* node) /* in: row insert node */
+ ins_node_t* node) /*!< in: row insert node */
{
que_node_t* list_node;
dfield_t* dfield;
@@ -2387,16 +2337,16 @@ row_ins_get_row_from_select(
}
}
-/***************************************************************
-Inserts a row to a table. */
+/***********************************************************//**
+Inserts a row to a table.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_ins(
/*====*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- ins_node_t* node, /* in: row insert node */
- que_thr_t* thr) /* in: query thread */
+ ins_node_t* node, /*!< in: row insert node */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -2442,15 +2392,15 @@ row_ins(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Inserts a row to a table. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_ins_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ins_node_t* node;
que_node_t* parent;
diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c
index efed3d26e5b..25f041c0885 100644
--- a/storage/xtradb/row/row0merge.c
+++ b/storage/xtradb/row/row0merge.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0merge.c
New index creation routines using a merge sort
Created 12/4/2005 Jan Lindstrom
@@ -57,69 +58,85 @@ Completed by Sunny Bains and Marko Makela
#include "handler0alter.h"
#ifdef UNIV_DEBUG
-/* Set these in order ot enable debug printout. */
+/** Set these in order ot enable debug printout. */
+/* @{ */
+/** Log the outcome of each row_merge_cmp() call, comparing records. */
static ibool row_merge_print_cmp;
+/** Log each record read from temporary file. */
static ibool row_merge_print_read;
+/** Log each record write to temporary file. */
static ibool row_merge_print_write;
+/** Log each row_merge_blocks() call, merging two blocks of records to
+a bigger one. */
+static ibool row_merge_print_block;
+/** Log each block read from temporary file. */
+static ibool row_merge_print_block_read;
+/** Log each block read from temporary file. */
+static ibool row_merge_print_block_write;
+/* @} */
#endif /* UNIV_DEBUG */
-/* Block size for I/O operations in merge sort. The minimum is
-UNIV_PAGE_SIZE, or page_get_free_space_of_empty() rounded to a power of 2.
+/** @brief Block size for I/O operations in merge sort.
+
+The minimum is UNIV_PAGE_SIZE, or page_get_free_space_of_empty()
+rounded to a power of 2.
When not creating a PRIMARY KEY that contains column prefixes, this
can be set as small as UNIV_PAGE_SIZE / 2. See the comment above
ut_ad(data_size < sizeof(row_merge_block_t)). */
-
typedef byte row_merge_block_t[1048576];
-/* Secondary buffer for I/O operations of merge records. This buffer
-is used for writing or reading a record that spans two row_merge_block_t.
-Thus, it must be able to hold one merge record, whose maximum size is
-the same as the minimum size of row_merge_block_t. */
+/** @brief Secondary buffer for I/O operations of merge records.
+This buffer is used for writing or reading a record that spans two
+row_merge_block_t. Thus, it must be able to hold one merge record,
+whose maximum size is the same as the minimum size of
+row_merge_block_t. */
typedef byte mrec_buf_t[UNIV_PAGE_SIZE];
-/* Merge record in row_merge_block_t. The format is the same as a
-record in ROW_FORMAT=COMPACT with the exception that the
-REC_N_NEW_EXTRA_BYTES are omitted. */
+/** @brief Merge record in row_merge_block_t.
+
+The format is the same as a record in ROW_FORMAT=COMPACT with the
+exception that the REC_N_NEW_EXTRA_BYTES are omitted. */
typedef byte mrec_t;
-/* Buffer for sorting in main memory. */
+/** Buffer for sorting in main memory. */
struct row_merge_buf_struct {
- mem_heap_t* heap; /* memory heap where allocated */
- dict_index_t* index; /* the index the tuples belong to */
- ulint total_size; /* total amount of data bytes */
- ulint n_tuples; /* number of data tuples */
- ulint max_tuples; /* maximum number of data tuples */
- const dfield_t**tuples; /* array of pointers to
+ mem_heap_t* heap; /*!< memory heap where allocated */
+ dict_index_t* index; /*!< the index the tuples belong to */
+ ulint total_size; /*!< total amount of data bytes */
+ ulint n_tuples; /*!< number of data tuples */
+ ulint max_tuples; /*!< maximum number of data tuples */
+ const dfield_t**tuples; /*!< array of pointers to
arrays of fields that form
the data tuples */
- const dfield_t**tmp_tuples; /* temporary copy of tuples,
+ const dfield_t**tmp_tuples; /*!< temporary copy of tuples,
for sorting */
};
+/** Buffer for sorting in main memory. */
typedef struct row_merge_buf_struct row_merge_buf_t;
-/* Information about temporary files used in merge sort are stored
-to this structure */
-
+/** Information about temporary files used in merge sort */
struct merge_file_struct {
- int fd; /* File descriptor */
- ulint offset; /* File offset */
+ int fd; /*!< file descriptor */
+ ulint offset; /*!< file offset (end of file) */
+ ib_uint64_t n_rec; /*!< number of records in the file */
};
+/** Information about temporary files used in merge sort */
typedef struct merge_file_struct merge_file_t;
#ifdef UNIV_DEBUG
-/**********************************************************
+/******************************************************//**
Display a merge tuple. */
static
void
row_merge_tuple_print(
/*==================*/
- FILE* f, /* in: output stream */
- const dfield_t* entry, /* in: tuple to print */
- ulint n_fields)/* in: number of fields in the tuple */
+ FILE* f, /*!< in: output stream */
+ const dfield_t* entry, /*!< in: tuple to print */
+ ulint n_fields)/*!< in: number of fields in the tuple */
{
ulint j;
@@ -146,17 +163,17 @@ row_merge_tuple_print(
}
#endif /* UNIV_DEBUG */
-/**********************************************************
-Allocate a sort buffer. */
+/******************************************************//**
+Allocate a sort buffer.
+@return own: sort buffer */
static
row_merge_buf_t*
row_merge_buf_create_low(
/*=====================*/
- /* out,own: sort buffer */
- mem_heap_t* heap, /* in: heap where allocated */
- dict_index_t* index, /* in: secondary index */
- ulint max_tuples, /* in: maximum number of data tuples */
- ulint buf_size) /* in: size of the buffer, in bytes */
+ mem_heap_t* heap, /*!< in: heap where allocated */
+ dict_index_t* index, /*!< in: secondary index */
+ ulint max_tuples, /*!< in: maximum number of data tuples */
+ ulint buf_size) /*!< in: size of the buffer, in bytes */
{
row_merge_buf_t* buf;
@@ -175,14 +192,14 @@ row_merge_buf_create_low(
return(buf);
}
-/**********************************************************
-Allocate a sort buffer. */
+/******************************************************//**
+Allocate a sort buffer.
+@return own: sort buffer */
static
row_merge_buf_t*
row_merge_buf_create(
/*=================*/
- /* out,own: sort buffer */
- dict_index_t* index) /* in: secondary index */
+ dict_index_t* index) /*!< in: secondary index */
{
row_merge_buf_t* buf;
ulint max_tuples;
@@ -201,14 +218,14 @@ row_merge_buf_create(
return(buf);
}
-/**********************************************************
-Empty a sort buffer. */
+/******************************************************//**
+Empty a sort buffer.
+@return sort buffer */
static
row_merge_buf_t*
row_merge_buf_empty(
/*================*/
- /* out: sort buffer */
- row_merge_buf_t* buf) /* in,own: sort buffer */
+ row_merge_buf_t* buf) /*!< in,own: sort buffer */
{
ulint buf_size;
ulint max_tuples = buf->max_tuples;
@@ -222,28 +239,27 @@ row_merge_buf_empty(
return(row_merge_buf_create_low(heap, index, max_tuples, buf_size));
}
-/**********************************************************
+/******************************************************//**
Deallocate a sort buffer. */
static
void
row_merge_buf_free(
/*===============*/
- row_merge_buf_t* buf) /* in,own: sort buffer, to be freed */
+ row_merge_buf_t* buf) /*!< in,own: sort buffer, to be freed */
{
mem_heap_free(buf->heap);
}
-/**********************************************************
-Insert a data tuple into a sort buffer. */
+/******************************************************//**
+Insert a data tuple into a sort buffer.
+@return TRUE if added, FALSE if out of space */
static
ibool
row_merge_buf_add(
/*==============*/
- /* out: TRUE if added,
- FALSE if out of space */
- row_merge_buf_t* buf, /* in/out: sort buffer */
- const dtuple_t* row, /* in: row in clustered index */
- const row_ext_t* ext) /* in: cache of externally stored
+ row_merge_buf_t* buf, /*!< in/out: sort buffer */
+ const dtuple_t* row, /*!< in: row in clustered index */
+ const row_ext_t* ext) /*!< in: cache of externally stored
column prefixes, or NULL */
{
ulint i;
@@ -389,23 +405,24 @@ row_merge_buf_add(
return(TRUE);
}
-/* Structure for reporting duplicate records. */
+/** Structure for reporting duplicate records. */
struct row_merge_dup_struct {
- const dict_index_t* index; /* index being sorted */
- TABLE* table; /* MySQL table object */
- ulint n_dup; /* number of duplicates */
+ const dict_index_t* index; /*!< index being sorted */
+ TABLE* table; /*!< MySQL table object */
+ ulint n_dup; /*!< number of duplicates */
};
+/** Structure for reporting duplicate records. */
typedef struct row_merge_dup_struct row_merge_dup_t;
-/*****************************************************************
+/*************************************************************//**
Report a duplicate key. */
static
void
row_merge_dup_report(
/*=================*/
- row_merge_dup_t* dup, /* in/out: for reporting duplicates */
- const dfield_t* entry) /* in: duplicate index entry */
+ row_merge_dup_t* dup, /*!< in/out: for reporting duplicates */
+ const dfield_t* entry) /*!< in: duplicate index entry */
{
mrec_buf_t buf;
const dtuple_t* tuple;
@@ -442,18 +459,17 @@ row_merge_dup_report(
}
}
-/*****************************************************************
-Compare two tuples. */
+/*************************************************************//**
+Compare two tuples.
+@return 1, 0, -1 if a is greater, equal, less, respectively, than b */
static
int
row_merge_tuple_cmp(
/*================*/
- /* out: 1, 0, -1 if a is greater,
- equal, less, respectively, than b */
- ulint n_field,/* in: number of fields */
- const dfield_t* a, /* in: first tuple to be compared */
- const dfield_t* b, /* in: second tuple to be compared */
- row_merge_dup_t* dup) /* in/out: for reporting duplicates */
+ ulint n_field,/*!< in: number of fields */
+ const dfield_t* a, /*!< in: first tuple to be compared */
+ const dfield_t* b, /*!< in: second tuple to be compared */
+ row_merge_dup_t* dup) /*!< in/out: for reporting duplicates */
{
int cmp;
const dfield_t* field = a;
@@ -484,53 +500,64 @@ func_exit:
return(cmp);
}
-/**************************************************************************
+/** Wrapper for row_merge_tuple_sort() to inject some more context to
+UT_SORT_FUNCTION_BODY().
+@param a array of tuples that being sorted
+@param b aux (work area), same size as tuples[]
+@param c lower bound of the sorting area, inclusive
+@param d upper bound of the sorting area, inclusive */
+#define row_merge_tuple_sort_ctx(a,b,c,d) \
+ row_merge_tuple_sort(n_field, dup, a, b, c, d)
+/** Wrapper for row_merge_tuple_cmp() to inject some more context to
+UT_SORT_FUNCTION_BODY().
+@param a first tuple to be compared
+@param b second tuple to be compared
+@return 1, 0, -1 if a is greater, equal, less, respectively, than b */
+#define row_merge_tuple_cmp_ctx(a,b) row_merge_tuple_cmp(n_field, a, b, dup)
+
+/**********************************************************************//**
Merge sort the tuple buffer in main memory. */
static
void
row_merge_tuple_sort(
/*=================*/
- ulint n_field,/* in: number of fields */
- row_merge_dup_t* dup, /* in/out: for reporting duplicates */
- const dfield_t** tuples, /* in/out: tuples */
- const dfield_t** aux, /* in/out: work area */
- ulint low, /* in: lower bound of the
+ ulint n_field,/*!< in: number of fields */
+ row_merge_dup_t* dup, /*!< in/out: for reporting duplicates */
+ const dfield_t** tuples, /*!< in/out: tuples */
+ const dfield_t** aux, /*!< in/out: work area */
+ ulint low, /*!< in: lower bound of the
sorting area, inclusive */
- ulint high) /* in: upper bound of the
+ ulint high) /*!< in: upper bound of the
sorting area, exclusive */
{
-#define row_merge_tuple_sort_ctx(a,b,c,d) \
- row_merge_tuple_sort(n_field, dup, a, b, c, d)
-#define row_merge_tuple_cmp_ctx(a,b) row_merge_tuple_cmp(n_field, a, b, dup)
-
UT_SORT_FUNCTION_BODY(row_merge_tuple_sort_ctx,
tuples, aux, low, high, row_merge_tuple_cmp_ctx);
}
-/**********************************************************
+/******************************************************//**
Sort a buffer. */
static
void
row_merge_buf_sort(
/*===============*/
- row_merge_buf_t* buf, /* in/out: sort buffer */
- row_merge_dup_t* dup) /* in/out: for reporting duplicates */
+ row_merge_buf_t* buf, /*!< in/out: sort buffer */
+ row_merge_dup_t* dup) /*!< in/out: for reporting duplicates */
{
row_merge_tuple_sort(dict_index_get_n_unique(buf->index), dup,
buf->tuples, buf->tmp_tuples, 0, buf->n_tuples);
}
-/**********************************************************
+/******************************************************//**
Write a buffer to a block. */
static
void
row_merge_buf_write(
/*================*/
- const row_merge_buf_t* buf, /* in: sorted buffer */
+ const row_merge_buf_t* buf, /*!< in: sorted buffer */
#ifdef UNIV_DEBUG
- const merge_file_t* of, /* in: output file */
+ const merge_file_t* of, /*!< in: output file */
#endif /* UNIV_DEBUG */
- row_merge_block_t* block) /* out: buffer for writing to file */
+ row_merge_block_t* block) /*!< out: buffer for writing to file */
#ifndef UNIV_DEBUG
# define row_merge_buf_write(buf, of, block) row_merge_buf_write(buf, block)
#endif /* !UNIV_DEBUG */
@@ -599,16 +626,16 @@ row_merge_buf_write(
#endif /* UNIV_DEBUG */
}
-/**********************************************************
-Create a memory heap and allocate space for row_merge_rec_offsets(). */
+/******************************************************//**
+Create a memory heap and allocate space for row_merge_rec_offsets().
+@return memory heap */
static
mem_heap_t*
row_merge_heap_create(
/*==================*/
- /* out: memory heap */
- const dict_index_t* index, /* in: record descriptor */
- ulint** offsets1, /* out: offsets */
- ulint** offsets2) /* out: offsets */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint** offsets1, /*!< out: offsets */
+ ulint** offsets2) /*!< out: offsets */
{
ulint i = 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index);
@@ -623,17 +650,16 @@ row_merge_heap_create(
return(heap);
}
-/**************************************************************************
+/**********************************************************************//**
Search an index object by name and column names. If several indexes match,
-return the index with the max id. */
+return the index with the max id.
+@return matching index, NULL if not found */
static
dict_index_t*
row_merge_dict_table_get_index(
/*===========================*/
- /* out: matching index,
- NULL if not found */
- dict_table_t* table, /* in: table */
- const merge_index_def_t*index_def) /* in: index definition */
+ dict_table_t* table, /*!< in: table */
+ const merge_index_def_t*index_def) /*!< in: index definition */
{
ulint i;
dict_index_t* index;
@@ -653,21 +679,27 @@ row_merge_dict_table_get_index(
return(index);
}
-/************************************************************************
-Read a merge block from the file system. */
+/********************************************************************//**
+Read a merge block from the file system.
+@return TRUE if request was successful, FALSE if fail */
static
ibool
row_merge_read(
/*===========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- int fd, /* in: file descriptor */
- ulint offset, /* in: offset where to read */
- row_merge_block_t* buf) /* out: data */
+ int fd, /*!< in: file descriptor */
+ ulint offset, /*!< in: offset where to read */
+ row_merge_block_t* buf) /*!< out: data */
{
ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof *buf;
ibool success;
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block_read) {
+ fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n",
+ fd, (ulong) offset);
+ }
+#endif /* UNIV_DEBUG */
+
success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
@@ -681,46 +713,50 @@ row_merge_read(
return(UNIV_LIKELY(success));
}
-/************************************************************************
-Read a merge block from the file system. */
+/********************************************************************//**
+Read a merge block from the file system.
+@return TRUE if request was successful, FALSE if fail */
static
ibool
row_merge_write(
/*============*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- int fd, /* in: file descriptor */
- ulint offset, /* in: offset where to write */
- const void* buf) /* in: data */
+ int fd, /*!< in: file descriptor */
+ ulint offset, /*!< in: offset where to write */
+ const void* buf) /*!< in: data */
{
ib_uint64_t ofs = ((ib_uint64_t) offset)
* sizeof(row_merge_block_t);
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block_write) {
+ fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n",
+ fd, (ulong) offset);
+ }
+#endif /* UNIV_DEBUG */
+
return(UNIV_LIKELY(os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
sizeof(row_merge_block_t))));
}
-/************************************************************************
-Read a merge record. */
-static
+/********************************************************************//**
+Read a merge record.
+@return pointer to next record, or NULL on I/O error or end of list */
+static __attribute__((nonnull))
const byte*
row_merge_read_rec(
/*===============*/
- /* out: pointer to next record,
- or NULL on I/O error
- or end of list */
- row_merge_block_t* block, /* in/out: file buffer */
- mrec_buf_t* buf, /* in/out: secondary buffer */
- const byte* b, /* in: pointer to record */
- const dict_index_t* index, /* in: index of the record */
- int fd, /* in: file descriptor */
- ulint* foffs, /* in/out: file offset */
- const mrec_t** mrec, /* out: pointer to merge record,
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ mrec_buf_t* buf, /*!< in/out: secondary buffer */
+ const byte* b, /*!< in: pointer to record */
+ const dict_index_t* index, /*!< in: index of the record */
+ int fd, /*!< in: file descriptor */
+ ulint* foffs, /*!< in/out: file offset */
+ 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 */
+ ulint* offsets)/*!< out: offsets of mrec */
{
ulint extra_size;
ulint data_size;
@@ -838,7 +874,14 @@ err_exit:
avail_size = block[1] - b;
memcpy(*buf, b, avail_size);
*mrec = *buf + extra_size;
- rec_offs_make_valid(*mrec, index, offsets);
+#ifdef UNIV_DEBUG
+ /* 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(). */
+ offsets[2] = (ulint) *mrec;
+ offsets[3] = (ulint) index;
+#endif /* UNIV_DEBUG */
if (!row_merge_read(fd, ++(*foffs), block)) {
@@ -866,21 +909,21 @@ func_exit:
return(b);
}
-/************************************************************************
+/********************************************************************//**
Write a merge record. */
static
void
row_merge_write_rec_low(
/*====================*/
- byte* b, /* out: buffer */
- ulint e, /* in: encoded extra_size */
+ byte* b, /*!< out: buffer */
+ ulint e, /*!< in: encoded extra_size */
#ifdef UNIV_DEBUG
- ulint size, /* in: total size to write */
- int fd, /* in: file descriptor */
- ulint foffs, /* in: file offset */
+ ulint size, /*!< in: total size to write */
+ int fd, /*!< in: file descriptor */
+ ulint foffs, /*!< in: file offset */
#endif /* UNIV_DEBUG */
- const mrec_t* mrec, /* in: record to write */
- const ulint* offsets)/* in: offsets of mrec */
+ const mrec_t* mrec, /*!< in: record to write */
+ const ulint* offsets)/*!< in: offsets of mrec */
#ifndef UNIV_DEBUG
# define row_merge_write_rec_low(b, e, size, fd, foffs, mrec, offsets) \
row_merge_write_rec_low(b, e, mrec, offsets)
@@ -909,21 +952,20 @@ row_merge_write_rec_low(
ut_ad(b + rec_offs_size(offsets) == end);
}
-/************************************************************************
-Write a merge record. */
+/********************************************************************//**
+Write a merge record.
+@return pointer to end of block, or NULL on error */
static
byte*
row_merge_write_rec(
/*================*/
- /* out: pointer to end of block,
- or NULL on error */
- row_merge_block_t* block, /* in/out: file buffer */
- mrec_buf_t* buf, /* in/out: secondary buffer */
- byte* b, /* in: pointer to end of block */
- 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 */
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ mrec_buf_t* buf, /*!< in/out: secondary buffer */
+ byte* b, /*!< in: pointer to end of block */
+ 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 */
{
ulint extra_size;
ulint size;
@@ -977,18 +1019,17 @@ row_merge_write_rec(
return(b);
}
-/************************************************************************
-Write an end-of-list marker. */
+/********************************************************************//**
+Write an end-of-list marker.
+@return pointer to end of block, or NULL on error */
static
byte*
row_merge_write_eof(
/*================*/
- /* out: pointer to end of block,
- or NULL on error */
- row_merge_block_t* block, /* in/out: file buffer */
- byte* b, /* in: pointer to end of block */
- int fd, /* in: file descriptor */
- ulint* foffs) /* in/out: file offset */
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ byte* b, /*!< in: pointer to end of block */
+ int fd, /*!< in: file descriptor */
+ ulint* foffs) /*!< in/out: file offset */
{
ut_ad(block);
ut_ad(b >= block[0]);
@@ -1018,22 +1059,20 @@ row_merge_write_eof(
return(block[0]);
}
-/*****************************************************************
-Compare two merge records. */
+/*************************************************************//**
+Compare two merge records.
+@return 1, 0, -1 if mrec1 is greater, equal, less, respectively, than mrec2 */
static
int
row_merge_cmp(
/*==========*/
- /* out: 1, 0, -1 if
- mrec1 is greater, equal, less,
- respectively, than mrec2 */
- const mrec_t* mrec1, /* in: first merge
+ const mrec_t* mrec1, /*!< in: first merge
record to be compared */
- const mrec_t* mrec2, /* in: second merge
+ const mrec_t* mrec2, /*!< in: second merge
record to be compared */
- const ulint* offsets1, /* in: first record offsets */
- const ulint* offsets2, /* in: second record offsets */
- const dict_index_t* index) /* in: index */
+ const ulint* offsets1, /*!< in: first record offsets */
+ const ulint* offsets2, /*!< in: second record offsets */
+ const dict_index_t* index) /*!< in: index */
{
int cmp;
@@ -1052,26 +1091,26 @@ row_merge_cmp(
return(cmp);
}
-/************************************************************************
+/********************************************************************//**
Reads clustered index of the table and create temporary files
-containing the index entries for the indexes to be built. */
-static
+containing the index entries for the indexes to be built.
+@return DB_SUCCESS or error */
+static __attribute__((nonnull))
ulint
row_merge_read_clustered_index(
/*===========================*/
- /* out: DB_SUCCESS or error */
- trx_t* trx, /* in: transaction */
- TABLE* table, /* in/out: MySQL table object,
+ trx_t* trx, /*!< in: transaction */
+ TABLE* table, /*!< in/out: MySQL table object,
for reporting erroneous records */
- const dict_table_t* old_table,/* in: table where rows are
+ const dict_table_t* old_table,/*!< in: table where rows are
read from */
- const dict_table_t* new_table,/* in: table where indexes are
+ const dict_table_t* new_table,/*!< in: table where indexes are
created; identical to old_table
unless creating a PRIMARY KEY */
- dict_index_t** index, /* in: indexes to be created */
- merge_file_t* files, /* in: temporary files */
- ulint n_index,/* in: number of indexes to create */
- row_merge_block_t* block) /* in/out: file buffer */
+ dict_index_t** index, /*!< in: indexes to be created */
+ merge_file_t* files, /*!< in: temporary files */
+ ulint n_index,/*!< in: number of indexes to create */
+ row_merge_block_t* block) /*!< in/out: file buffer */
{
dict_index_t* clust_index; /* Clustered index */
mem_heap_t* row_heap; /* Heap memory to create
@@ -1161,6 +1200,12 @@ row_merge_read_clustered_index(
in order to release the latch on the old page. */
if (btr_pcur_is_after_last_on_page(&pcur)) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ i = 0;
+ err = DB_INTERRUPTED;
+ goto err_exit;
+ }
+
btr_pcur_store_position(&pcur, &mtr);
mtr_commit(&mtr);
mtr_start(&mtr);
@@ -1219,6 +1264,7 @@ row_merge_read_clustered_index(
if (UNIV_LIKELY
(row && row_merge_buf_add(buf, row, ext))) {
+ file->n_rec++;
continue;
}
@@ -1260,14 +1306,19 @@ err_exit:
UNIV_MEM_INVALID(block[0], sizeof block[0]);
merge_buf[i] = row_merge_buf_empty(buf);
- /* Try writing the record again, now that
- the buffer has been written out and emptied. */
+ if (UNIV_LIKELY(row != NULL)) {
+ /* Try writing the record again, now
+ that the buffer has been written out
+ and emptied. */
- if (UNIV_UNLIKELY
- (row && !row_merge_buf_add(buf, row, ext))) {
- /* An empty buffer should have enough
- room for at least one record. */
- ut_error;
+ if (UNIV_UNLIKELY
+ (!row_merge_buf_add(buf, row, ext))) {
+ /* An empty buffer should have enough
+ room for at least one record. */
+ ut_error;
+ }
+
+ file->n_rec++;
}
}
@@ -1298,47 +1349,15 @@ func_exit:
return(err);
}
-/*****************************************************************
-Merge two blocks of linked lists on disk and write a bigger block. */
-static
-ulint
-row_merge_blocks(
-/*=============*/
- /* out: DB_SUCCESS or error code */
- const dict_index_t* index, /* in: index being created */
- merge_file_t* file, /* in/out: file containing
- index entries */
- row_merge_block_t* block, /* in/out: 3 buffers */
- ulint* foffs0, /* in/out: offset of first
- source list in the file */
- ulint* foffs1, /* in/out: offset of second
- source list in the file */
- merge_file_t* of, /* in/out: output file */
- TABLE* table) /* in/out: MySQL table, for
- reporting erroneous key value
- if applicable */
-{
- mem_heap_t* heap; /* memory heap for offsets0, offsets1 */
-
- mrec_buf_t buf[3]; /* buffer for handling split mrec in block[] */
- const byte* b0; /* pointer to block[0] */
- const byte* b1; /* pointer to block[1] */
- byte* b2; /* pointer to block[2] */
- const mrec_t* mrec0; /* merge rec, points to block[0] or buf[0] */
- const mrec_t* mrec1; /* merge rec, points to block[1] or buf[1] */
- ulint* offsets0;/* offsets of mrec0 */
- ulint* offsets1;/* offsets of mrec1 */
-
- heap = row_merge_heap_create(index, &offsets0, &offsets1);
-
- /* Write a record and read the next record. Split the output
- file in two halves, which can be merged on the following pass. */
+/** Write a record via buffer 2 and read the next record to buffer N.
+@param N number of the buffer (0 or 1)
+@param AT_END statement to execute at end of input */
#define ROW_MERGE_WRITE_GET_NEXT(N, AT_END) \
do { \
b2 = row_merge_write_rec(&block[2], &buf[2], b2, \
of->fd, &of->offset, \
mrec##N, offsets##N); \
- if (UNIV_UNLIKELY(!b2)) { \
+ if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
goto corrupt; \
} \
b##N = row_merge_read_rec(&block[N], &buf[N], \
@@ -1353,6 +1372,53 @@ row_merge_blocks(
} \
} while (0)
+/*************************************************************//**
+Merge two blocks of records on disk and write a bigger block.
+@return DB_SUCCESS or error code */
+static
+ulint
+row_merge_blocks(
+/*=============*/
+ const dict_index_t* index, /*!< in: index being created */
+ const merge_file_t* file, /*!< in: file containing
+ index entries */
+ row_merge_block_t* block, /*!< in/out: 3 buffers */
+ ulint* foffs0, /*!< in/out: offset of first
+ source list in the file */
+ ulint* foffs1, /*!< in/out: offset of second
+ source list in the file */
+ merge_file_t* of, /*!< in/out: output file */
+ TABLE* table) /*!< in/out: MySQL table, for
+ reporting erroneous key value
+ if applicable */
+{
+ mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
+
+ mrec_buf_t buf[3]; /*!< buffer for handling split mrec in block[] */
+ const byte* b0; /*!< pointer to block[0] */
+ const byte* b1; /*!< pointer to block[1] */
+ byte* b2; /*!< pointer to block[2] */
+ const mrec_t* mrec0; /*!< merge rec, points to block[0] or buf[0] */
+ const mrec_t* mrec1; /*!< merge rec, points to block[1] or buf[1] */
+ ulint* offsets0;/* offsets of mrec0 */
+ ulint* offsets1;/* offsets of mrec1 */
+
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block) {
+ fprintf(stderr,
+ "row_merge_blocks fd=%d ofs=%lu + fd=%d ofs=%lu"
+ " = fd=%d ofs=%lu\n",
+ file->fd, (ulong) *foffs0,
+ file->fd, (ulong) *foffs1,
+ of->fd, (ulong) of->offset);
+ }
+#endif /* UNIV_DEBUG */
+
+ heap = row_merge_heap_create(index, &offsets0, &offsets1);
+
+ /* Write a record and read the next record. Split the output
+ file in two halves, which can be merged on the following pass. */
+
if (!row_merge_read(file->fd, *foffs0, &block[0])
|| !row_merge_read(file->fd, *foffs1, &block[1])) {
corrupt:
@@ -1419,115 +1485,238 @@ done1:
return(b2 ? DB_SUCCESS : DB_CORRUPTION);
}
-/*****************************************************************
-Merge disk files. */
-static
+/*************************************************************//**
+Copy a block of index entries.
+@return TRUE on success, FALSE on failure */
+static __attribute__((nonnull))
+ibool
+row_merge_blocks_copy(
+/*==================*/
+ const dict_index_t* index, /*!< in: index being created */
+ const merge_file_t* file, /*!< in: input file */
+ row_merge_block_t* block, /*!< in/out: 3 buffers */
+ ulint* foffs0, /*!< in/out: input file offset */
+ merge_file_t* of) /*!< in/out: output file */
+{
+ mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
+
+ mrec_buf_t buf[3]; /*!< buffer for handling
+ split mrec in block[] */
+ const byte* b0; /*!< pointer to block[0] */
+ byte* b2; /*!< pointer to block[2] */
+ const mrec_t* mrec0; /*!< merge rec, points to block[0] */
+ ulint* offsets0;/* offsets of mrec0 */
+ ulint* offsets1;/* dummy offsets */
+
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block) {
+ fprintf(stderr,
+ "row_merge_blocks_copy fd=%d ofs=%lu"
+ " = fd=%d ofs=%lu\n",
+ file->fd, (ulong) foffs0,
+ of->fd, (ulong) of->offset);
+ }
+#endif /* UNIV_DEBUG */
+
+ heap = row_merge_heap_create(index, &offsets0, &offsets1);
+
+ /* Write a record and read the next record. Split the output
+ file in two halves, which can be merged on the following pass. */
+
+ if (!row_merge_read(file->fd, *foffs0, &block[0])) {
+corrupt:
+ mem_heap_free(heap);
+ return(FALSE);
+ }
+
+ b0 = block[0];
+ b2 = block[2];
+
+ b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
+ foffs0, &mrec0, offsets0);
+ if (UNIV_UNLIKELY(!b0 && mrec0)) {
+
+ goto corrupt;
+ }
+
+ if (mrec0) {
+ /* append all mrec0 to output */
+ for (;;) {
+ ROW_MERGE_WRITE_GET_NEXT(0, goto done0);
+ }
+ }
+done0:
+
+ /* The file offset points to the beginning of the last page
+ that has been read. Update it to point to the next block. */
+ (*foffs0)++;
+
+ mem_heap_free(heap);
+ return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset)
+ != NULL);
+}
+
+/*************************************************************//**
+Merge disk files.
+@return DB_SUCCESS or error code */
+static __attribute__((nonnull))
ulint
row_merge(
/*======*/
- /* out: DB_SUCCESS or error code */
- const dict_index_t* index, /* in: index being created */
- merge_file_t* file, /* in/out: file containing
+ trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index, /*!< in: index being created */
+ merge_file_t* file, /*!< in/out: file containing
index entries */
- ulint half, /* in: half the file */
- row_merge_block_t* block, /* in/out: 3 buffers */
- int* tmpfd, /* in/out: temporary file handle */
- TABLE* table) /* in/out: MySQL table, for
+ ulint* half, /*!< in/out: half the file */
+ row_merge_block_t* block, /*!< in/out: 3 buffers */
+ int* tmpfd, /*!< in/out: temporary file handle */
+ TABLE* table) /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
{
- ulint foffs0; /* first input offset */
- ulint foffs1; /* second input offset */
- ulint error; /* error code */
- merge_file_t of; /* output file */
+ ulint foffs0; /*!< first input offset */
+ ulint foffs1; /*!< second input offset */
+ ulint error; /*!< error code */
+ merge_file_t of; /*!< output file */
+ const ulint ihalf = *half;
+ /*!< half the input file */
+ ulint ohalf; /*!< half the output file */
UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
- ut_ad(half > 0);
+ ut_ad(ihalf < file->offset);
of.fd = *tmpfd;
of.offset = 0;
+ of.n_rec = 0;
/* Merge blocks to the output file. */
+ ohalf = 0;
foffs0 = 0;
- foffs1 = half;
+ foffs1 = ihalf;
+
+ for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
+ ulint ahalf; /*!< arithmetic half the input file */
+
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
- for (; foffs0 < half && foffs1 < file->offset; foffs0++, foffs1++) {
error = row_merge_blocks(index, file, block,
&foffs0, &foffs1, &of, table);
if (error != DB_SUCCESS) {
return(error);
}
+
+ /* Record the offset of the output file when
+ approximately half the output has been generated. In
+ this way, the next invocation of row_merge() will
+ spend most of the time in this loop. The initial
+ estimate is ohalf==0. */
+ ahalf = file->offset / 2;
+ ut_ad(ohalf <= of.offset);
+
+ /* Improve the estimate until reaching half the input
+ file size, or we can not get any closer to it. All
+ comparands should be non-negative when !(ohalf < ahalf)
+ because ohalf <= of.offset. */
+ if (ohalf < ahalf || of.offset - ahalf < ohalf - ahalf) {
+ ohalf = of.offset;
+ }
}
- /* Copy the last block, if there is one. */
- while (foffs0 < half) {
- if (!row_merge_read(file->fd, foffs0++, block)
- || !row_merge_write(of.fd, of.offset++, block)) {
+ /* Copy the last blocks, if there are any. */
+
+ while (foffs0 < ihalf) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
+
+ if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
return(DB_CORRUPTION);
}
}
+
+ ut_ad(foffs0 == ihalf);
+
while (foffs1 < file->offset) {
- if (!row_merge_read(file->fd, foffs1++, block)
- || !row_merge_write(of.fd, of.offset++, block)) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
+
+ if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
return(DB_CORRUPTION);
}
}
+ ut_ad(foffs1 == file->offset);
+
+ if (UNIV_UNLIKELY(of.n_rec != file->n_rec)) {
+ return(DB_CORRUPTION);
+ }
+
/* Swap file descriptors for the next pass. */
*tmpfd = file->fd;
*file = of;
+ *half = ohalf;
UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]);
return(DB_SUCCESS);
}
-/*****************************************************************
-Merge disk files. */
+/*************************************************************//**
+Merge disk files.
+@return DB_SUCCESS or error code */
static
ulint
row_merge_sort(
/*===========*/
- /* out: DB_SUCCESS or error code */
- const dict_index_t* index, /* in: index being created */
- merge_file_t* file, /* in/out: file containing
+ trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index, /*!< in: index being created */
+ merge_file_t* file, /*!< in/out: file containing
index entries */
- row_merge_block_t* block, /* in/out: 3 buffers */
- int* tmpfd, /* in/out: temporary file handle */
- TABLE* table) /* in/out: MySQL table, for
+ row_merge_block_t* block, /*!< in/out: 3 buffers */
+ int* tmpfd, /*!< in/out: temporary file handle */
+ TABLE* table) /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
{
- ulint blksz; /* block size */
+ ulint half = file->offset / 2;
- for (blksz = 1; blksz < file->offset; blksz *= 2) {
- ulint half;
+ /* The file should always contain at least one byte (the end
+ of file marker). Thus, it must be at least one block. */
+ ut_ad(file->offset > 0);
+
+ do {
ulint error;
- ut_ad(ut_is_2pow(blksz));
- half = ut_2pow_round((file->offset + (blksz - 1)) / 2, blksz);
- error = row_merge(index, file, half, block, tmpfd, table);
+ error = row_merge(trx, index, file, &half,
+ block, tmpfd, table);
if (error != DB_SUCCESS) {
return(error);
}
- }
+
+ /* half > 0 should hold except when the file consists
+ of one block. No need to merge further then. */
+ ut_ad(half > 0 || file->offset == 1);
+ } while (half < file->offset && half > 0);
return(DB_SUCCESS);
}
-/*****************************************************************
+/*************************************************************//**
Copy externally stored columns to the data tuple. */
static
void
row_merge_copy_blobs(
/*=================*/
- const mrec_t* mrec, /* in: merge record */
- const ulint* offsets,/* in: offsets of mrec */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- dtuple_t* tuple, /* in/out: data tuple */
- mem_heap_t* heap) /* in/out: memory heap */
+ const mrec_t* mrec, /*!< in: merge record */
+ const ulint* offsets,/*!< in: offsets of mrec */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ mem_heap_t* heap) /*!< in/out: memory heap */
{
ulint i;
ulint n_fields = dtuple_get_n_fields(tuple);
@@ -1555,21 +1744,21 @@ row_merge_copy_blobs(
}
}
-/************************************************************************
+/********************************************************************//**
Read sorted file containing index data tuples and insert these data
-tuples to the index */
+tuples to the index
+@return DB_SUCCESS or error number */
static
ulint
row_merge_insert_index_tuples(
/*==========================*/
- /* out: DB_SUCCESS or error number */
- trx_t* trx, /* in: transaction */
- dict_index_t* index, /* in: index */
- dict_table_t* table, /* in: new table */
- ulint zip_size,/* in: compressed page size of
+ trx_t* trx, /*!< in: transaction */
+ dict_index_t* index, /*!< in: index */
+ dict_table_t* table, /*!< in: new table */
+ ulint zip_size,/*!< in: compressed page size of
the old table, or 0 if uncompressed */
- int fd, /* in: file descriptor */
- row_merge_block_t* block) /* in/out: file buffer */
+ int fd, /*!< in: file descriptor */
+ row_merge_block_t* block) /*!< in/out: file buffer */
{
mrec_buf_t buf;
const byte* b;
@@ -1677,16 +1866,16 @@ err_exit:
return(error);
}
-/*************************************************************************
-Sets an exclusive lock on a table, for the duration of creating indexes. */
+/*********************************************************************//**
+Sets an exclusive lock on a table, for the duration of creating indexes.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_merge_lock_table(
/*=================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in/out: transaction */
- dict_table_t* table, /* in: table to lock */
- enum lock_mode mode) /* in: LOCK_X or LOCK_S */
+ trx_t* trx, /*!< in/out: transaction */
+ dict_table_t* table, /*!< in: table to lock */
+ enum lock_mode mode) /*!< in: LOCK_X or LOCK_S */
{
mem_heap_t* heap;
que_thr_t* thr;
@@ -1756,7 +1945,7 @@ run_again:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Drop an index from the InnoDB system tables. The data dictionary must
have been locked exclusively by the caller, because the transaction
will not be committed. */
@@ -1764,9 +1953,9 @@ UNIV_INTERN
void
row_merge_drop_index(
/*=================*/
- dict_index_t* index, /* in: index to be removed */
- dict_table_t* table, /* in: table */
- trx_t* trx) /* in: transaction handle */
+ dict_index_t* index, /*!< in: index to be removed */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint err;
pars_info_t* info = pars_info_create();
@@ -1779,7 +1968,15 @@ row_merge_drop_index(
static const char str1[] =
"PROCEDURE DROP_INDEX_PROC () IS\n"
"BEGIN\n"
+ /* Rename the index, so that it will be dropped by
+ row_merge_drop_temp_indexes() at crash recovery
+ if the server crashes before this trx is committed. */
+ "UPDATE SYS_INDEXES SET NAME=CONCAT('"
+ TEMP_INDEX_PREFIX_STR "', NAME) WHERE ID = :indexid;\n"
+ "COMMIT WORK;\n"
+ /* Drop the field definitions of the index. */
"DELETE FROM SYS_FIELDS WHERE INDEX_ID = :indexid;\n"
+ /* Drop the index definition and the B-tree. */
"DELETE FROM SYS_INDEXES WHERE ID = :indexid\n"
" AND TABLE_ID = :tableid;\n"
"END;\n";
@@ -1807,7 +2004,7 @@ row_merge_drop_index(
trx->op_info = "";
}
-/*************************************************************************
+/*********************************************************************//**
Drop those indexes which were created before an error occurred when
building an index. The data dictionary must have been locked
exclusively by the caller, because the transaction will not be
@@ -1816,10 +2013,10 @@ UNIV_INTERN
void
row_merge_drop_indexes(
/*===================*/
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table containing the indexes */
- dict_index_t** index, /* in: indexes to drop */
- ulint num_created) /* in: number of elements in index[] */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table containing the indexes */
+ dict_index_t** index, /*!< in: indexes to drop */
+ ulint num_created) /*!< in: number of elements in index[] */
{
ulint key_num;
@@ -1828,7 +2025,7 @@ row_merge_drop_indexes(
}
}
-/*************************************************************************
+/*********************************************************************//**
Drop all partially created indexes during crash recovery. */
UNIV_INTERN
void
@@ -1842,14 +2039,11 @@ row_merge_drop_temp_indexes(void)
query graphs needed in deleting the dictionary data from system
tables in Innobase. Deleting a row from SYS_INDEXES table also
frees the file segments of the B-tree associated with the index. */
-#if TEMP_INDEX_PREFIX != '\377'
-# error "TEMP_INDEX_PREFIX != '\377'"
-#endif
static const char drop_temp_indexes[] =
"PROCEDURE DROP_TEMP_INDEXES_PROC () IS\n"
"indexid CHAR;\n"
"DECLARE CURSOR c IS SELECT ID FROM SYS_INDEXES\n"
- "WHERE SUBSTR(NAME,0,1)='\377';\n"
+ "WHERE SUBSTR(NAME,0,1)='" TEMP_INDEX_PREFIX_STR "';\n"
"BEGIN\n"
"\tOPEN c;\n"
"\tWHILE 1=1 LOOP\n"
@@ -1884,25 +2078,26 @@ row_merge_drop_temp_indexes(void)
trx_free_for_background(trx);
}
-/*************************************************************************
+/*********************************************************************//**
Create a merge file. */
static
void
row_merge_file_create(
/*==================*/
- merge_file_t* merge_file) /* out: merge file structure */
+ merge_file_t* merge_file) /*!< out: merge file structure */
{
merge_file->fd = innobase_mysql_tmpfile();
merge_file->offset = 0;
+ merge_file->n_rec = 0;
}
-/*************************************************************************
+/*********************************************************************//**
Destroy a merge file. */
static
void
row_merge_file_destroy(
/*===================*/
- merge_file_t* merge_file) /* out: merge file structure */
+ merge_file_t* merge_file) /*!< out: merge file structure */
{
if (merge_file->fd != -1) {
close(merge_file->fd);
@@ -1910,18 +2105,17 @@ row_merge_file_destroy(
}
}
-/*************************************************************************
+/*********************************************************************//**
Determine the precise type of a column that is added to a tem
-if a column must be constrained NOT NULL. */
+if a column must be constrained NOT NULL.
+@return col->prtype, possibly ORed with DATA_NOT_NULL */
UNIV_INLINE
ulint
row_merge_col_prtype(
/*=================*/
- /* out: col->prtype, possibly
- ORed with DATA_NOT_NULL */
- const dict_col_t* col, /* in: column */
- const char* col_name, /* in: name of the column */
- const merge_index_def_t*index_def) /* in: the index definition
+ const dict_col_t* col, /*!< in: column */
+ const char* col_name, /*!< in: name of the column */
+ const merge_index_def_t*index_def) /*!< in: the index definition
of the primary key */
{
ulint prtype = col->prtype;
@@ -1946,20 +2140,19 @@ row_merge_col_prtype(
return(prtype);
}
-/*************************************************************************
+/*********************************************************************//**
Create a temporary table for creating a primary key, using the definition
-of an existing table. */
+of an existing table.
+@return table, or NULL on error */
UNIV_INTERN
dict_table_t*
row_merge_create_temporary_table(
/*=============================*/
- /* out: table,
- or NULL on error */
- const char* table_name, /* in: new table name */
- const merge_index_def_t*index_def, /* in: the index definition
+ const char* table_name, /*!< in: new table name */
+ const merge_index_def_t*index_def, /*!< in: the index definition
of the primary key */
- const dict_table_t* table, /* in: old table definition */
- trx_t* trx) /* in/out: transaction
+ const dict_table_t* table, /*!< in: old table definition */
+ trx_t* trx) /*!< in/out: transaction
(sets error_state) */
{
ulint i;
@@ -1999,17 +2192,17 @@ row_merge_create_temporary_table(
return(new_table);
}
-/*************************************************************************
+/*********************************************************************//**
Rename the temporary indexes in the dictionary to permanent ones. The
data dictionary must have been locked exclusively by the caller,
-because the transaction will not be committed. */
+because the transaction will not be committed.
+@return DB_SUCCESS if all OK */
UNIV_INTERN
ulint
row_merge_rename_indexes(
/*=====================*/
- /* out: DB_SUCCESS if all OK */
- trx_t* trx, /* in/out: transaction */
- dict_table_t* table) /* in/out: table with new indexes */
+ trx_t* trx, /*!< in/out: transaction */
+ dict_table_t* table) /*!< in/out: table with new indexes */
{
ulint err = DB_SUCCESS;
pars_info_t* info = pars_info_create();
@@ -2017,15 +2210,12 @@ row_merge_rename_indexes(
/* We use the private SQL parser of Innobase to generate the
query graphs needed in renaming indexes. */
-#if TEMP_INDEX_PREFIX != '\377'
-# error "TEMP_INDEX_PREFIX != '\377'"
-#endif
-
static const char rename_indexes[] =
"PROCEDURE RENAME_INDEXES_PROC () IS\n"
"BEGIN\n"
"UPDATE SYS_INDEXES SET NAME=SUBSTR(NAME,1,LENGTH(NAME)-1)\n"
- "WHERE TABLE_ID = :tableid AND SUBSTR(NAME,0,1)='\377';\n"
+ "WHERE TABLE_ID = :tableid AND SUBSTR(NAME,0,1)='"
+ TEMP_INDEX_PREFIX_STR "';\n"
"END;\n";
ut_ad(table);
@@ -2053,21 +2243,21 @@ row_merge_rename_indexes(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
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. */
+will not be committed.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_merge_rename_tables(
/*====================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* old_table, /* in/out: old table, renamed to
+ dict_table_t* old_table, /*!< in/out: old table, renamed to
tmp_name */
- dict_table_t* new_table, /* in/out: new table, renamed to
+ dict_table_t* new_table, /*!< in/out: new table, renamed to
old_table->name */
- const char* tmp_name, /* in: new name for old_table */
- trx_t* trx) /* in: transaction handle */
+ const char* tmp_name, /*!< in: new name for old_table */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint err = DB_ERROR;
pars_info_t* info;
@@ -2119,7 +2309,7 @@ row_merge_rename_tables(
if (err != DB_SUCCESS) {
err_exit:
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
}
@@ -2128,20 +2318,20 @@ err_exit:
return(err);
}
-/*************************************************************************
-Create and execute a query graph for creating an index. */
+/*********************************************************************//**
+Create and execute a query graph for creating an index.
+@return DB_SUCCESS or error code */
static
ulint
row_merge_create_index_graph(
/*=========================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: trx */
- dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: index */
+ trx_t* trx, /*!< in: trx */
+ dict_table_t* table, /*!< in: table */
+ dict_index_t* index) /*!< in: index */
{
- ind_node_t* node; /* Index creation node */
- mem_heap_t* heap; /* Memory heap */
- que_thr_t* thr; /* Query thread */
+ ind_node_t* node; /*!< Index creation node */
+ mem_heap_t* heap; /*!< Memory heap */
+ que_thr_t* thr; /*!< Query thread */
ulint err;
ut_ad(trx);
@@ -2165,17 +2355,17 @@ row_merge_create_index_graph(
return(err);
}
-/*************************************************************************
-Create the index and load in to the dictionary. */
+/*********************************************************************//**
+Create the index and load in to the dictionary.
+@return index, or NULL on error */
UNIV_INTERN
dict_index_t*
row_merge_create_index(
/*===================*/
- /* out: index, or NULL on error */
- trx_t* trx, /* in/out: trx (sets error_state) */
- dict_table_t* table, /* in: the index is on this table */
- const merge_index_def_t* /* in: the index definition */
- index_def)
+ trx_t* trx, /*!< in/out: trx (sets error_state) */
+ dict_table_t* table, /*!< in: the index is on this table */
+ const merge_index_def_t*index_def)
+ /*!< in: the index definition */
{
dict_index_t* index;
ulint err;
@@ -2208,12 +2398,11 @@ row_merge_create_index(
ut_a(index);
-#ifdef ROW_MERGE_IS_INDEX_USABLE
/* Note the id of the transaction that created this
index, we use it to restrict readers from accessing
this index, to ensure read consistency. */
- index->trx_id = trx->id;
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
+ index->trx_id = (ib_uint64_t)
+ ut_conv_dulint_to_longlong(trx->id);
} else {
index = NULL;
}
@@ -2221,33 +2410,30 @@ row_merge_create_index(
return(index);
}
-#ifdef ROW_MERGE_IS_INDEX_USABLE
-/*************************************************************************
+/*********************************************************************//**
Check if a transaction can use an index. */
UNIV_INTERN
ibool
row_merge_is_index_usable(
/*======================*/
- const trx_t* trx, /* in: transaction */
- const dict_index_t* index) /* in: index to check */
+ const trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index) /*!< in: index to check */
{
- if (!trx->read_view) {
- return(TRUE);
- }
-
- return(ut_dulint_cmp(index->trx_id, trx->read_view->low_limit_id) < 0);
+ return(!trx->read_view || read_view_sees_trx_id(
+ trx->read_view,
+ ut_dulint_create((ulint) (index->trx_id >> 32),
+ (ulint) index->trx_id & 0xFFFFFFFF)));
}
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
-/*************************************************************************
-Drop the old table. */
+/*********************************************************************//**
+Drop the old table.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_merge_drop_table(
/*=================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: transaction */
- dict_table_t* table) /* in: table to drop */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table) /*!< in: table to drop */
{
/* There must be no open transactions on the table. */
ut_a(table->n_mysql_handles_opened == 0);
@@ -2255,24 +2441,24 @@ row_merge_drop_table(
return(row_drop_table_for_mysql(table->name, trx, FALSE));
}
-/*************************************************************************
+/*********************************************************************//**
Build indexes on a table by reading a clustered index,
creating a temporary file containing index entries, merge sorting
-these index entries and inserting sorted index entries to indexes. */
+these index entries and inserting sorted index entries to indexes.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_merge_build_indexes(
/*====================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: transaction */
- dict_table_t* old_table, /* in: table where rows are
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* old_table, /*!< in: table where rows are
read from */
- dict_table_t* new_table, /* in: table where indexes are
+ dict_table_t* new_table, /*!< in: table where indexes are
created; identical to old_table
unless creating a PRIMARY KEY */
- dict_index_t** indexes, /* in: indexes to be created */
- ulint n_indexes, /* in: size of indexes[] */
- TABLE* table) /* in/out: MySQL table, for
+ dict_index_t** indexes, /*!< in: indexes to be created */
+ ulint n_indexes, /*!< in: size of indexes[] */
+ TABLE* table) /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
{
@@ -2325,7 +2511,7 @@ row_merge_build_indexes(
sorting and inserting. */
for (i = 0; i < n_indexes; i++) {
- error = row_merge_sort(indexes[i], &merge_files[i],
+ error = row_merge_sort(trx, indexes[i], &merge_files[i],
block, &tmpfd, table);
if (error == DB_SUCCESS) {
diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c
index 3a9e1de0125..8585b816911 100644
--- a/storage/xtradb/row/row0mysql.c
+++ b/storage/xtradb/row/row0mysql.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0mysql.c
Interface between Innobase row operations and MySQL.
Contains also create table and other data dictionary operations.
@@ -30,6 +31,7 @@ Created 9/17/2000 Heikki Tuuri
#endif
#include "row0ins.h"
+#include "row0merge.h"
#include "row0sel.h"
#include "row0upd.h"
#include "row0row.h"
@@ -50,43 +52,54 @@ Created 9/17/2000 Heikki Tuuri
#include "fil0fil.h"
#include "ibuf0ibuf.h"
-/* Provide optional 4.x backwards compatibility for 5.0 and above */
+/** Provide optional 4.x backwards compatibility for 5.0 and above */
UNIV_INTERN ibool row_rollback_on_timeout = FALSE;
-/* List of tables we should drop in background. ALTER TABLE in MySQL requires
-that the table handler can drop the table in background when there are no
-queries to it any more. Protected by the kernel mutex. */
+/** Chain node of the list of tables to drop in the background. */
typedef struct row_mysql_drop_struct row_mysql_drop_t;
+
+/** Chain node of the list of tables to drop in the background. */
struct row_mysql_drop_struct{
- char* table_name;
- UT_LIST_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
+ char* table_name; /*!< table name */
+ UT_LIST_NODE_T(row_mysql_drop_t)row_mysql_drop_list;
+ /*!< list chain node */
};
+/** @brief List of tables we should drop in background.
+
+ALTER TABLE in MySQL requires that the table handler can drop the
+table in background when there are no queries to it any
+more. Protected by kernel_mutex. */
static UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
+/** Flag: has row_mysql_drop_list been initialized? */
static ibool row_mysql_drop_list_inited = FALSE;
-/* Magic table names for invoking various monitor threads */
+/** Magic table names for invoking various monitor threads */
+/* @{ */
static const char S_innodb_monitor[] = "innodb_monitor";
static const char S_innodb_lock_monitor[] = "innodb_lock_monitor";
static const char S_innodb_tablespace_monitor[] = "innodb_tablespace_monitor";
static const char S_innodb_table_monitor[] = "innodb_table_monitor";
static const char S_innodb_mem_validate[] = "innodb_mem_validate";
-
-/* Evaluates to true if str1 equals str2_onstack, used for comparing
-the above strings. */
+/* @} */
+
+/** Evaluates to true if str1 equals str2_onstack, used for comparing
+the magic table names.
+@param str1 in: string to compare
+@param str1_len in: length of str1, in bytes, including terminating NUL
+@param str2_onstack in: char[] array containing a NUL terminated string
+@return TRUE if str1 equals str2_onstack */
#define STR_EQ(str1, str1_len, str2_onstack) \
((str1_len) == sizeof(str2_onstack) \
&& memcmp(str1, str2_onstack, sizeof(str2_onstack)) == 0)
-#ifndef UNIV_HOTBACKUP
-/***********************************************************************
-Determine if the given name is a name reserved for MySQL system tables. */
+/*******************************************************************//**
+Determine if the given name is a name reserved for MySQL system tables.
+@return TRUE if name is a MySQL system table name */
static
ibool
row_mysql_is_system_table(
/*======================*/
- /* out: TRUE if name is a MySQL
- system table name */
const char* name)
{
if (strncmp(name, "mysql/", 6) != 0) {
@@ -98,23 +111,21 @@ row_mysql_is_system_table(
|| 0 == strcmp(name + 6, "user")
|| 0 == strcmp(name + 6, "db"));
}
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
If a table is not yet in the drop list, adds the table to the list of tables
which the master thread drops in background. We need this on Unix because in
ALTER TABLE MySQL may call drop table even if the table has running queries on
it. Also, if there are running foreign key checks on the table, we drop the
-table lazily. */
+table lazily.
+@return TRUE if the table was not yet in the drop list, and was added there */
static
ibool
row_add_table_to_background_drop_list(
/*==================================*/
- /* out: TRUE if the table was not yet in the
- drop list, and was added there */
- const char* name); /* in: table name */
+ const char* name); /*!< in: table name */
-/***********************************************************************
+/*******************************************************************//**
Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */
static
void
@@ -126,31 +137,31 @@ row_mysql_delay_if_needed(void)
}
}
-/***********************************************************************
+/*******************************************************************//**
Frees the blob heap in prebuilt when no longer needed. */
UNIV_INTERN
void
row_mysql_prebuilt_free_blob_heap(
/*==============================*/
- row_prebuilt_t* prebuilt) /* in: prebuilt struct of a
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct of a
ha_innobase:: table handle */
{
mem_heap_free(prebuilt->blob_heap);
prebuilt->blob_heap = NULL;
}
-/***********************************************************************
+/*******************************************************************//**
Stores a >= 5.0.3 format true VARCHAR length to dest, in the MySQL row
-format. */
+format.
+@return pointer to the data, we skip the 1 or 2 bytes at the start
+that are used to store the len */
UNIV_INTERN
byte*
row_mysql_store_true_var_len(
/*=========================*/
- /* out: pointer to the data, we skip the 1 or 2 bytes
- at the start that are used to store the len */
- byte* dest, /* in: where to store */
- ulint len, /* in: length, must fit in two bytes */
- ulint lenlen) /* in: storage length of len: either 1 or 2 bytes */
+ byte* dest, /*!< in: where to store */
+ ulint len, /*!< in: length, must fit in two bytes */
+ ulint lenlen) /*!< in: storage length of len: either 1 or 2 bytes */
{
if (lenlen == 2) {
ut_a(len < 256 * 256);
@@ -168,19 +179,18 @@ row_mysql_store_true_var_len(
return(dest + 1);
}
-/***********************************************************************
+/*******************************************************************//**
Reads a >= 5.0.3 format true VARCHAR length, in the MySQL row format, and
-returns a pointer to the data. */
+returns a pointer to the data.
+@return pointer to the data, we skip the 1 or 2 bytes at the start
+that are used to store the len */
UNIV_INTERN
const byte*
row_mysql_read_true_varchar(
/*========================*/
- /* out: pointer to the data, we skip
- the 1 or 2 bytes at the start that are
- used to store the len */
- ulint* len, /* out: variable-length field length */
- const byte* field, /* in: field in the MySQL format */
- ulint lenlen) /* in: storage length of len: either 1
+ ulint* len, /*!< out: variable-length field length */
+ const byte* field, /*!< in: field in the MySQL format */
+ ulint lenlen) /*!< in: storage length of len: either 1
or 2 bytes */
{
if (lenlen == 2) {
@@ -196,20 +206,20 @@ row_mysql_read_true_varchar(
return(field + 1);
}
-/***********************************************************************
+/*******************************************************************//**
Stores a reference to a BLOB in the MySQL format. */
UNIV_INTERN
void
row_mysql_store_blob_ref(
/*=====================*/
- byte* dest, /* in: where to store */
- ulint col_len,/* in: dest buffer size: determines into
+ byte* dest, /*!< in: where to store */
+ ulint col_len,/*!< in: dest buffer size: determines into
how many bytes the BLOB length is stored,
the space for the length may vary from 1
to 4 bytes */
- const void* data, /* in: BLOB data; if the value to store
+ const void* data, /*!< in: BLOB data; if the value to store
is SQL NULL this should be NULL pointer */
- ulint len) /* in: BLOB length; if the value to store
+ ulint len) /*!< in: BLOB length; if the value to store
is SQL NULL this should be 0; remember
also to set the NULL bit in the MySQL record
header! */
@@ -233,17 +243,17 @@ row_mysql_store_blob_ref(
memcpy(dest + col_len - 8, &data, sizeof data);
}
-/***********************************************************************
-Reads a reference to a BLOB in the MySQL format. */
+/*******************************************************************//**
+Reads a reference to a BLOB in the MySQL format.
+@return pointer to BLOB data */
UNIV_INTERN
const byte*
row_mysql_read_blob_ref(
/*====================*/
- /* out: pointer to BLOB data */
- ulint* len, /* out: BLOB length */
- const byte* ref, /* in: BLOB reference in the
+ ulint* len, /*!< out: BLOB length */
+ const byte* ref, /*!< in: BLOB reference in the
MySQL format */
- ulint col_len) /* in: BLOB reference length
+ ulint col_len) /*!< in: BLOB reference length
(not BLOB length) */
{
byte* data;
@@ -255,41 +265,40 @@ row_mysql_read_blob_ref(
return(data);
}
-/******************************************************************
+/**************************************************************//**
Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
The counterpart of this function is row_sel_field_store_in_mysql_format() in
-row0sel.c. */
+row0sel.c.
+@return up to which byte we used buf in the conversion */
UNIV_INTERN
byte*
row_mysql_store_col_in_innobase_format(
/*===================================*/
- /* out: up to which byte we used
- buf in the conversion */
- dfield_t* dfield, /* in/out: dfield where dtype
+ dfield_t* dfield, /*!< in/out: dfield where dtype
information must be already set when
this function is called! */
- byte* buf, /* in/out: buffer for a converted
+ byte* buf, /*!< in/out: buffer for a converted
integer value; this must be at least
col_len long then! */
- ibool row_format_col, /* TRUE if the mysql_data is from
+ ibool row_format_col, /*!< TRUE if the mysql_data is from
a MySQL row, FALSE if from a MySQL
key value;
in MySQL, a true VARCHAR storage
format differs in a row and in a
key value: in a key value the length
is always stored in 2 bytes! */
- const byte* mysql_data, /* in: MySQL column value, not
+ const byte* mysql_data, /*!< in: MySQL column value, not
SQL NULL; NOTE that dfield may also
get a pointer to mysql_data,
therefore do not discard this as long
as dfield is used! */
- ulint col_len, /* in: MySQL column length; NOTE that
+ ulint col_len, /*!< in: MySQL column length; NOTE that
this is the storage length of the
column in the MySQL format row, not
necessarily the length of the actual
payload data; if the column is a true
VARCHAR then this is irrelevant */
- ulint comp) /* in: nonzero=compact format */
+ ulint comp) /*!< in: nonzero=compact format */
{
const byte* ptr = mysql_data;
const dtype_t* dtype;
@@ -417,7 +426,7 @@ row_mysql_store_col_in_innobase_format(
return(buf);
}
-/******************************************************************
+/**************************************************************//**
Convert a row in the MySQL format to a row in the Innobase format. Note that
the function to convert a MySQL format key value to an InnoDB dtuple is
row_sel_convert_mysql_key_to_innobase() in row0sel.c. */
@@ -425,12 +434,12 @@ static
void
row_mysql_convert_row_to_innobase(
/*==============================*/
- dtuple_t* row, /* in/out: Innobase row where the
+ dtuple_t* row, /*!< in/out: Innobase row where the
field type information is already
copied there! */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct where template
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct where template
must be of type ROW_MYSQL_WHOLE_ROW */
- byte* mysql_rec) /* in: row in the MySQL format;
+ byte* mysql_rec) /*!< in: row in the MySQL format;
NOTE: do not discard as long as
row is used, as row may contain
pointers to this record! */
@@ -473,23 +482,22 @@ next_column:
}
}
-/********************************************************************
-Handles user errors and lock waits detected by the database engine. */
+/****************************************************************//**
+Handles user errors and lock waits detected by the database engine.
+@return TRUE if it was a lock wait and we should continue running the
+query thread */
UNIV_INTERN
ibool
row_mysql_handle_errors(
/*====================*/
- /* out: TRUE if it was a lock wait and
- we should continue running the query thread */
- ulint* new_err,/* out: possible new error encountered in
+ ulint* new_err,/*!< out: possible new error encountered in
lock wait, or if no new error, the value
of trx->error_state at the entry of this
function */
- trx_t* trx, /* in: transaction */
- que_thr_t* thr, /* in: query thread */
- trx_savept_t* savept) /* in: savepoint or NULL */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t* thr, /*!< in: query thread */
+ trx_savept_t* savept) /*!< in: savepoint or NULL */
{
-#ifndef UNIV_HOTBACKUP
ulint err;
handle_new_error:
@@ -502,7 +510,7 @@ handle_new_error:
switch (err) {
case DB_LOCK_WAIT_TIMEOUT:
if (row_rollback_on_timeout) {
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
break;
}
/* fall through */
@@ -518,7 +526,7 @@ handle_new_error:
/* Roll back the latest, possibly incomplete
insertion or update */
- trx_general_rollback_for_mysql(trx, TRUE, savept);
+ trx_general_rollback_for_mysql(trx, savept);
}
/* MySQL will roll back the latest SQL statement */
break;
@@ -540,7 +548,7 @@ handle_new_error:
/* Roll back the whole transaction; this resolution was added
to version 3.23.43 */
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
break;
case DB_MUST_GET_MORE_FILE_SPACE:
@@ -564,8 +572,7 @@ handle_new_error:
"InnoDB: If the mysqld server crashes"
" after the startup or when\n"
"InnoDB: you dump the tables, look at\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html"
+ "InnoDB: " REFMAN "forcing-recovery.html"
" for help.\n", stderr);
break;
default:
@@ -583,23 +590,16 @@ handle_new_error:
trx->error_state = DB_SUCCESS;
return(FALSE);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(FALSE);
-#endif /* UNIV_HOTBACKUP */
}
-/************************************************************************
-Create a prebuilt struct for a MySQL table handle. */
+/********************************************************************//**
+Create a prebuilt struct for a MySQL table handle.
+@return own: a prebuilt struct */
UNIV_INTERN
row_prebuilt_t*
row_create_prebuilt(
/*================*/
- /* out, own: a prebuilt struct */
- dict_table_t* table) /* in: Innobase table handle */
+ dict_table_t* table) /*!< in: Innobase table handle */
{
row_prebuilt_t* prebuilt;
mem_heap_t* heap;
@@ -653,14 +653,14 @@ row_create_prebuilt(
return(prebuilt);
}
-/************************************************************************
+/********************************************************************//**
Free a prebuilt struct for a MySQL table handle. */
UNIV_INTERN
void
row_prebuilt_free(
/*==============*/
- row_prebuilt_t* prebuilt, /* in, own: prebuilt struct */
- ibool dict_locked) /* in: TRUE=data dictionary locked */
+ row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */
+ ibool dict_locked) /*!< in: TRUE=data dictionary locked */
{
ulint i;
@@ -738,17 +738,16 @@ row_prebuilt_free(
mem_heap_free(prebuilt->heap);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the transaction pointers in query graphs stored in the prebuilt
struct. */
UNIV_INTERN
void
row_update_prebuilt_trx(
/*====================*/
- /* out: prebuilt dtuple */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
- handle */
- trx_t* trx) /* in: transaction handle */
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
+ in MySQL handle */
+ trx_t* trx) /*!< in: transaction handle */
{
if (trx->magic_n != TRX_MAGIC_N) {
fprintf(stderr,
@@ -789,17 +788,16 @@ row_update_prebuilt_trx(
}
}
-/*************************************************************************
+/*********************************************************************//**
Gets pointer to a prebuilt dtuple used in insertions. If the insert graph
has not yet been built in the prebuilt struct, then this function first
-builds it. */
+builds it.
+@return prebuilt dtuple; the column type information is also set in it */
static
dtuple_t*
row_get_prebuilt_insert_row(
/*========================*/
- /* out: prebuilt dtuple; the column
- type information is also set in it */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
ins_node_t* node;
@@ -839,14 +837,14 @@ row_get_prebuilt_insert_row(
return(prebuilt->ins_node->row);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the table modification counter and calculates new estimates
for table and index statistics if necessary. */
UNIV_INLINE
void
row_update_statistics_if_needed(
/*============================*/
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
ulint counter;
@@ -870,33 +868,37 @@ row_update_statistics_if_needed(
}
}
-/*************************************************************************
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+/*********************************************************************//**
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
/*===============================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
- mutex_enter(&kernel_mutex);
+ if (lock_trx_holds_autoinc_locks(trx)) {
+ mutex_enter(&kernel_mutex);
- lock_release_autoinc_locks(trx);
+ lock_release_autoinc_locks(trx);
- mutex_exit(&kernel_mutex);
+ mutex_exit(&kernel_mutex);
+ }
}
-/*************************************************************************
+/*********************************************************************//**
Sets an AUTO_INC type lock on the table mentioned in prebuilt. The
AUTO_INC lock gives exclusive access to the auto-inc counter of the
table. The lock is reserved only for the duration of an SQL statement.
It is not compatible with another AUTO_INC or exclusive lock on the
-table. */
+table.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_lock_table_autoinc_for_mysql(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in the MySQL
table handle */
{
trx_t* trx = prebuilt->trx;
@@ -965,20 +967,20 @@ run_again:
return((int) err);
}
-/*************************************************************************
-Sets a table lock on the table mentioned in prebuilt. */
+/*********************************************************************//**
+Sets a table lock on the table mentioned in prebuilt.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_lock_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in the MySQL
table handle */
- dict_table_t* table, /* in: table to lock, or NULL
+ dict_table_t* table, /*!< in: table to lock, or NULL
if prebuilt->table should be
locked as
prebuilt->select_lock_type */
- ulint mode) /* in: lock mode of table
+ ulint mode) /*!< in: lock mode of table
(ignored if table==NULL) */
{
trx_t* trx = prebuilt->trx;
@@ -1042,15 +1044,15 @@ run_again:
return((int) err);
}
-/*************************************************************************
-Does an insert for MySQL. */
+/*********************************************************************//**
+Does an insert for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_insert_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- byte* mysql_rec, /* in: row in the MySQL format */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ byte* mysql_rec, /*!< in: row in the MySQL format */
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
trx_savept_t savept;
@@ -1074,8 +1076,7 @@ row_insert_for_mysql(
"InnoDB: the MySQL datadir, or have you"
" used DISCARD TABLESPACE?\n"
"InnoDB: Look from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
return(DB_ERROR);
@@ -1175,13 +1176,13 @@ run_again:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Builds a dummy query graph used in selects. */
UNIV_INTERN
void
row_prebuild_sel_graph(
/*===================*/
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
sel_node_t* node;
@@ -1201,16 +1202,16 @@ row_prebuild_sel_graph(
}
}
-/*************************************************************************
+/*********************************************************************//**
Creates an query graph node of 'update' type to be used in the MySQL
-interface. */
+interface.
+@return own: update node */
UNIV_INTERN
upd_node_t*
row_create_update_node_for_mysql(
/*=============================*/
- /* out, own: update node */
- dict_table_t* table, /* in: table to update */
- mem_heap_t* heap) /* in: mem heap from which allocated */
+ dict_table_t* table, /*!< in: table to update */
+ mem_heap_t* heap) /*!< in: mem heap from which allocated */
{
upd_node_t* node;
@@ -1237,16 +1238,16 @@ row_create_update_node_for_mysql(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Gets pointer to a prebuilt update vector used in updates. If the update
graph has not yet been built in the prebuilt struct, then this function
-first builds it. */
+first builds it.
+@return prebuilt update vector */
UNIV_INTERN
upd_t*
row_get_prebuilt_update_vector(
/*===========================*/
- /* out: prebuilt update vector */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
dict_table_t* table = prebuilt->table;
@@ -1273,16 +1274,16 @@ row_get_prebuilt_update_vector(
return(prebuilt->upd_node->update);
}
-/*************************************************************************
-Does an update or delete of a row for MySQL. */
+/*********************************************************************//**
+Does an update or delete of a row for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_update_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- byte* mysql_rec, /* in: the row to be updated, in
+ byte* mysql_rec, /*!< in: the row to be updated, in
the MySQL format */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
trx_savept_t savept;
@@ -1310,8 +1311,7 @@ row_update_for_mysql(
"InnoDB: the MySQL datadir, or have you"
" used DISCARD TABLESPACE?\n"
"InnoDB: Look from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
return(DB_ERROR);
@@ -1429,7 +1429,7 @@ run_again:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
This can only be used when srv_locks_unsafe_for_binlog is TRUE or
this session is using a READ COMMITTED isolation level. Before
calling this function we must use trx_reset_new_rec_lock_info() and
@@ -1439,15 +1439,15 @@ and also under prebuilt->clust_pcur. Currently, this is only used and tested
in the case of an UPDATE or a DELETE statement, where the row lock is of the
LOCK_X type.
Thus, this implements a 'mini-rollback' that releases the latest record
-locks we set. */
+locks we set.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_unlock_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
handle */
- ibool has_latches_on_recs)/* TRUE if called so that we have
+ ibool has_latches_on_recs)/*!< TRUE if called so that we have
the latches on the records under pcur
and clust_pcur, and we do not need to
reposition the cursors. */
@@ -1476,9 +1476,9 @@ row_unlock_for_mysql(
if (prebuilt->new_rec_locks >= 1) {
- rec_t* rec;
+ const rec_t* rec;
dict_index_t* index;
- dulint rec_trx_id;
+ trx_id_t rec_trx_id;
mtr_t mtr;
mtr_start(&mtr);
@@ -1505,7 +1505,7 @@ row_unlock_for_mysql(
index = btr_pcur_get_btr_cur(clust_pcur)->index;
}
- if (UNIV_UNLIKELY(!(dict_index_is_clust(index)))) {
+ if (UNIV_UNLIKELY(!dict_index_is_clust(index))) {
/* This is not a clustered index record. We
do not know how to unlock the record. */
goto no_unlock;
@@ -1522,7 +1522,7 @@ row_unlock_for_mysql(
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
- *offsets_ = (sizeof offsets_) / sizeof *offsets_;
+ rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
@@ -1546,11 +1546,12 @@ row_unlock_for_mysql(
rec = btr_pcur_get_rec(clust_pcur);
index = btr_pcur_get_btr_cur(clust_pcur)->index;
- lock_rec_unlock(trx, btr_pcur_get_block(clust_pcur),
- rec, prebuilt->select_lock_type);
+ lock_rec_unlock(trx,
+ btr_pcur_get_block(clust_pcur),
+ rec,
+ prebuilt->select_lock_type);
}
}
-
no_unlock:
mtr_commit(&mtr);
}
@@ -1560,17 +1561,17 @@ no_unlock:
return(DB_SUCCESS);
}
-/**************************************************************************
-Does a cascaded delete or set null in a foreign key operation. */
+/**********************************************************************//**
+Does a cascaded delete or set null in a foreign key operation.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_update_cascade_for_mysql(
/*=========================*/
- /* out: error code or DB_SUCCESS */
- que_thr_t* thr, /* in: query thread */
- upd_node_t* node, /* in: update node used in the cascade
+ que_thr_t* thr, /*!< in: query thread */
+ upd_node_t* node, /*!< in: update node used in the cascade
or set null operation */
- dict_table_t* table) /* in: table where we do the operation */
+ dict_table_t* table) /*!< in: table where we do the operation */
{
ulint err;
trx_t* trx;
@@ -1629,14 +1630,15 @@ run_again:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a table is such that we automatically created a clustered
-index on it (on row id). */
+index on it (on row id).
+@return TRUE if the clustered index was generated automatically */
UNIV_INTERN
ibool
row_table_got_default_clust_index(
/*==============================*/
- const dict_table_t* table)
+ const dict_table_t* table) /*!< in: table */
{
const dict_index_t* clust_index;
@@ -1645,14 +1647,15 @@ row_table_got_default_clust_index(
return(dict_index_get_nth_col(clust_index, 0)->mtype == DATA_SYS);
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the key number used inside MySQL for an Innobase index. We have
-to take into account if we generated a default clustered index for the table */
+to take into account if we generated a default clustered index for the table
+@return the key number used inside MySQL */
UNIV_INTERN
ulint
row_get_mysql_key_number_for_index(
/*===============================*/
- const dict_index_t* index)
+ const dict_index_t* index) /*!< in: index */
{
const dict_index_t* ind;
ulint i;
@@ -1675,16 +1678,16 @@ row_get_mysql_key_number_for_index(
return(i);
}
-/*************************************************************************
+/*********************************************************************//**
Locks the data dictionary in shared mode from modifications, for performing
foreign key check, rollback, or other operation invisible to MySQL. */
UNIV_INTERN
void
row_mysql_freeze_data_dictionary_func(
/*==================================*/
- trx_t* trx, /* in/out: transaction */
- const char* file, /* in: file name */
- ulint line) /* in: line number */
+ trx_t* trx, /*!< in/out: transaction */
+ const char* file, /*!< in: file name */
+ ulint line) /*!< in: line number */
{
ut_a(trx->dict_operation_lock_mode == 0);
@@ -1693,13 +1696,13 @@ row_mysql_freeze_data_dictionary_func(
trx->dict_operation_lock_mode = RW_S_LATCH;
}
-/*************************************************************************
+/*********************************************************************//**
Unlocks the data dictionary shared lock. */
UNIV_INTERN
void
row_mysql_unfreeze_data_dictionary(
/*===============================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
ut_a(trx->dict_operation_lock_mode == RW_S_LATCH);
@@ -1708,16 +1711,16 @@ row_mysql_unfreeze_data_dictionary(
trx->dict_operation_lock_mode = 0;
}
-/*************************************************************************
+/*********************************************************************//**
Locks the data dictionary exclusively for performing a table create or other
data dictionary modification operation. */
UNIV_INTERN
void
row_mysql_lock_data_dictionary_func(
/*================================*/
- trx_t* trx, /* in/out: transaction */
- const char* file, /* in: file name */
- ulint line) /* in: line number */
+ trx_t* trx, /*!< in/out: transaction */
+ const char* file, /*!< in: file name */
+ ulint line) /*!< in: line number */
{
ut_a(trx->dict_operation_lock_mode == 0
|| trx->dict_operation_lock_mode == RW_X_LATCH);
@@ -1731,13 +1734,13 @@ row_mysql_lock_data_dictionary_func(
mutex_enter(&(dict_sys->mutex));
}
-/*************************************************************************
+/*********************************************************************//**
Unlocks the data dictionary exclusive lock. */
UNIV_INTERN
void
row_mysql_unlock_data_dictionary(
/*=============================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
@@ -1750,21 +1753,20 @@ row_mysql_unlock_data_dictionary(
trx->dict_operation_lock_mode = 0;
}
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+/*********************************************************************//**
Creates a table for MySQL. If the name of the table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also start the printing of monitor
output by the master thread. If the table name ends in "innodb_mem_validate",
-InnoDB will try to invoke mem_validate(). */
+InnoDB will try to invoke mem_validate().
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_create_table_for_mysql(
/*=======================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* table, /* in, own: table definition
+ dict_table_t* table, /*!< in, own: table definition
(will be freed) */
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
tab_node_t* node;
mem_heap_t* heap;
@@ -1772,7 +1774,6 @@ row_create_table_for_mysql(
const char* table_name;
ulint table_name_len;
ulint err;
- ulint i;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
#ifdef UNIV_SYNC_DEBUG
@@ -1807,15 +1808,6 @@ err_exit:
goto err_exit;
}
- /* Check that no reserved column names are used. */
- for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
- if (dict_col_name_is_reserved(
- dict_table_get_col_name(table, i))) {
-
- goto err_exit;
- }
- }
-
trx_start_if_not_started(trx);
/* The table name is prefixed with the database name and a '/'.
@@ -1890,7 +1882,9 @@ err_exit:
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
+ /* TO DO: free table? The code below will dereference
+ table->name, though. */
}
switch (err) {
@@ -1909,32 +1903,6 @@ err_exit:
break;
case DB_DUPLICATE_KEY:
- ut_print_timestamp(stderr);
- fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, TRUE, table->name);
- fputs(" already exists in InnoDB internal\n"
- "InnoDB: data dictionary. Have you deleted"
- " the .frm file\n"
- "InnoDB: and not used DROP TABLE?"
- " Have you used DROP DATABASE\n"
- "InnoDB: for InnoDB tables in"
- " MySQL version <= 3.23.43?\n"
- "InnoDB: See the Restrictions section"
- " of the InnoDB manual.\n"
- "InnoDB: You can drop the orphaned table"
- " inside InnoDB by\n"
- "InnoDB: creating an InnoDB table with"
- " the same name in another\n"
- "InnoDB: database and copying the .frm file"
- " to the current database.\n"
- "InnoDB: Then MySQL thinks the table exists,"
- " and DROP TABLE will\n"
- "InnoDB: succeed.\n"
- "InnoDB: You can look for further help from\n"
- "InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n", stderr);
-
/* We may also get err == DB_ERROR if the .ibd file for the
table already exists */
@@ -1948,19 +1916,19 @@ err_exit:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Does an index creation operation for MySQL. TODO: currently failure
to create an index results in dropping the whole table! This is no problem
-currently as all indexes must be created at the same time as the table. */
+currently as all indexes must be created at the same time as the table.
+@return error number or DB_SUCCESS */
UNIV_INTERN
int
row_create_index_for_mysql(
/*=======================*/
- /* out: error number or DB_SUCCESS */
- dict_index_t* index, /* in, own: index definition
+ dict_index_t* index, /*!< in, own: index definition
(will be freed) */
- trx_t* trx, /* in: transaction handle */
- const ulint* field_lengths) /* in: if not NULL, must contain
+ trx_t* trx, /*!< in: transaction handle */
+ const ulint* field_lengths) /*!< in: if not NULL, must contain
dict_index_get_n_fields(index)
actual field lengths for the
index columns, which are
@@ -2059,7 +2027,7 @@ error_handling:
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
row_drop_table_for_mysql(table_name, trx, FALSE);
@@ -2075,29 +2043,29 @@ error_handling:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
Each foreign key constraint must be accompanied with indexes in
-bot participating tables. The indexes are allowed to contain more
+both participating tables. The indexes are allowed to contain more
fields than mentioned in the constraint. Check also that foreign key
-constraints which reference this table are ok. */
+constraints which reference this table are ok.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_table_add_foreign_constraints(
/*==============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- const char* sql_string, /* in: table create statement where
+ trx_t* trx, /*!< in: transaction */
+ const char* sql_string, /*!< in: table create statement where
foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the
database name before it: test.table2 */
- const char* name, /* in: table full name in the
+ const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
- ibool reject_fks) /* in: if TRUE, fail with error
+ ibool reject_fks) /*!< in: if TRUE, fail with error
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
{
@@ -2117,18 +2085,17 @@ row_table_add_foreign_constraints(
err = dict_create_foreign_constraints(trx, sql_string, name,
reject_fks);
-#ifndef UNIV_HOTBACKUP
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
err = dict_load_foreigns(name, TRUE);
}
-#endif /* !UNIV_HOTBACKUP */
+
if (err != DB_SUCCESS) {
/* We have special error handling here */
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
row_drop_table_for_mysql(name, trx, FALSE);
@@ -2140,19 +2107,19 @@ row_table_add_foreign_constraints(
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Drops a table for MySQL as a background operation. MySQL relies on Unix
in ALTER TABLE to the fact that the table handler does not remove the
table before all handles to it has been removed. Furhermore, the MySQL's
call to drop table must be non-blocking. Therefore we do the drop table
as a background operation, which is taken care of by the master thread
-in srv0srv.c. */
+in srv0srv.c.
+@return error code or DB_SUCCESS */
static
int
row_drop_table_for_mysql_in_background(
/*===================================*/
- /* out: error code or DB_SUCCESS */
- const char* name) /* in: table name */
+ const char* name) /*!< in: table name */
{
ulint error;
trx_t* trx;
@@ -2186,16 +2153,15 @@ row_drop_table_for_mysql_in_background(
return((int) error);
}
-/*************************************************************************
+/*********************************************************************//**
The master thread in srv0srv.c calls this regularly to drop tables which
we must drop in background after queries to them have ended. Such lazy
-dropping of tables is needed in ALTER TABLE on Unix. */
+dropping of tables is needed in ALTER TABLE on Unix.
+@return how many tables dropped + remaining tables in list */
UNIV_INTERN
ulint
row_drop_tables_for_mysql_in_background(void)
/*=========================================*/
- /* out: how many tables dropped
- + remaining tables in list */
{
row_mysql_drop_t* drop;
dict_table_t* table;
@@ -2262,14 +2228,14 @@ already_dropped:
goto loop;
}
-/*************************************************************************
+/*********************************************************************//**
Get the background drop list length. NOTE: the caller must own the kernel
-mutex! */
+mutex!
+@return how many tables in list */
UNIV_INTERN
ulint
row_get_background_drop_list_len_low(void)
/*======================================*/
- /* out: how many tables in list */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -2282,19 +2248,18 @@ row_get_background_drop_list_len_low(void)
return(UT_LIST_GET_LEN(row_mysql_drop_list));
}
-/*************************************************************************
+/*********************************************************************//**
If a table is not yet in the drop list, adds the table to the list of tables
which the master thread drops in background. We need this on Unix because in
ALTER TABLE MySQL may call drop table even if the table has running queries on
it. Also, if there are running foreign key checks on the table, we drop the
-table lazily. */
+table lazily.
+@return TRUE if the table was not yet in the drop list, and was added there */
static
ibool
row_add_table_to_background_drop_list(
/*==================================*/
- /* out: TRUE if the table was not yet in the
- drop list, and was added there */
- const char* name) /* in: table name */
+ const char* name) /*!< in: table name */
{
row_mysql_drop_t* drop;
@@ -2336,17 +2301,17 @@ row_add_table_to_background_drop_list(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Discards the tablespace of a table which stored in an .ibd file. Discarding
means that this function deletes the .ibd file and assigns a new table id for
-the table. Also the flag table->ibd_file_missing is set TRUE. */
+the table. Also the flag table->ibd_file_missing is set TRUE.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_discard_tablespace_for_mysql(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx) /* in: transaction handle */
+ const char* name, /*!< in: table name */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_foreign_t* foreign;
dulint new_id;
@@ -2497,7 +2462,7 @@ row_discard_tablespace_for_mysql(
if (err != DB_SUCCESS) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
} else {
dict_table_change_id_in_cache(table, new_id);
@@ -2506,7 +2471,7 @@ row_discard_tablespace_for_mysql(
if (!success) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
err = DB_ERROR;
@@ -2528,16 +2493,16 @@ funct_exit:
return((int) err);
}
-/*********************************************************************
+/*****************************************************************//**
Imports a tablespace. The space id in the .ibd file must match the space id
-of the table in the data dictionary. */
+of the table in the data dictionary.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_import_tablespace_for_mysql(
/*============================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx) /* in: transaction handle */
+ const char* name, /*!< in: table name */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_table_t* table;
ibool success;
@@ -2666,15 +2631,15 @@ funct_exit:
return((int) err);
}
-/*************************************************************************
-Truncates a table for MySQL. */
+/*********************************************************************//**
+Truncates a table for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_truncate_table_for_mysql(
/*=========================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* table, /* in: table handle */
- trx_t* trx) /* in: transaction handle */
+ dict_table_t* table, /*!< in: table handle */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_foreign_t* foreign;
ulint err;
@@ -2958,7 +2923,7 @@ next_rec:
if (err != DB_SUCCESS) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
ut_print_timestamp(stderr);
fputs(" InnoDB: Unable to assign a new identifier to table ",
@@ -2992,21 +2957,21 @@ funct_exit:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Drops a table for MySQL. If the name of the dropped table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also stop the printing of monitor
output by the master thread. If the data dictionary was not already locked
by the transaction, the transaction will be committed. Otherwise, the
-data dictionary will remain locked. */
+data dictionary will remain locked.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_drop_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx, /* in: transaction handle */
- ibool drop_db)/* in: TRUE=dropping whole database */
+ const char* name, /*!< in: table name */
+ trx_t* trx, /*!< in: transaction handle */
+ ibool drop_db)/*!< in: TRUE=dropping whole database */
{
dict_foreign_t* foreign;
dict_table_t* table;
@@ -3101,8 +3066,7 @@ row_drop_table_for_mysql(
"InnoDB: MySQL database directory"
" from another database?\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n",
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
stderr);
goto funct_exit;
}
@@ -3382,23 +3346,21 @@ funct_exit:
trx->op_info = "";
-#ifndef UNIV_HOTBACKUP
srv_wake_master_thread();
-#endif /* !UNIV_HOTBACKUP */
return((int) err);
}
-/***********************************************************************
+/*******************************************************************//**
Drop all foreign keys in a database, see Bug#18942.
-Called at the end of row_drop_database_for_mysql(). */
+Called at the end of row_drop_database_for_mysql().
+@return error code or DB_SUCCESS */
static
ulint
drop_all_foreign_keys_in_db(
/*========================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: database name which ends to '/' */
- trx_t* trx) /* in: transaction handle */
+ const char* name, /*!< in: database name which ends to '/' */
+ trx_t* trx) /*!< in: transaction handle */
{
pars_info_t* pinfo;
ulint err;
@@ -3409,7 +3371,7 @@ drop_all_foreign_keys_in_db(
pars_info_add_str_literal(pinfo, "dbname", name);
-/* true if for_name is not prefixed with dbname */
+/** true if for_name is not prefixed with dbname */
#define TABLE_NOT_IN_THIS_DB \
"SUBSTR(for_name, 0, LENGTH(:dbname)) <> :dbname"
@@ -3449,15 +3411,15 @@ drop_all_foreign_keys_in_db(
return(err);
}
-/*************************************************************************
-Drops a database for MySQL. */
+/*********************************************************************//**
+Drops a database for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_drop_database_for_mysql(
/*========================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: database name which ends to '/' */
- trx_t* trx) /* in: transaction handle */
+ const char* name, /*!< in: database name which ends to '/' */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_table_t* table;
char* table_name;
@@ -3543,30 +3505,30 @@ loop:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a table name contains the string "/#sql" which denotes temporary
-tables in MySQL. */
+tables in MySQL.
+@return TRUE if temporary table */
static
ibool
row_is_mysql_tmp_table_name(
/*========================*/
- /* out: TRUE if temporary table */
- const char* name) /* in: table name in the form
+ const char* name) /*!< in: table name in the form
'database/tablename' */
{
return(strstr(name, "/#sql") != NULL);
/* return(strstr(name, "/@0023sql") != NULL); */
}
-/********************************************************************
-Delete a single constraint. */
+/****************************************************************//**
+Delete a single constraint.
+@return error code or DB_SUCCESS */
static
int
row_delete_constraint_low(
/*======================*/
- /* out: error code or DB_SUCCESS */
- const char* id, /* in: constraint id */
- trx_t* trx) /* in: transaction handle */
+ const char* id, /*!< in: constraint id */
+ trx_t* trx) /*!< in: transaction handle */
{
pars_info_t* info = pars_info_create();
@@ -3581,18 +3543,18 @@ row_delete_constraint_low(
, FALSE, trx));
}
-/********************************************************************
-Delete a single constraint. */
+/****************************************************************//**
+Delete a single constraint.
+@return error code or DB_SUCCESS */
static
int
row_delete_constraint(
/*==================*/
- /* out: error code or DB_SUCCESS */
- const char* id, /* in: constraint id */
- const char* database_name, /* in: database name, with the
+ const char* id, /*!< in: constraint id */
+ const char* database_name, /*!< in: database name, with the
trailing '/' */
- mem_heap_t* heap, /* in: memory heap */
- trx_t* trx) /* in: transaction handle */
+ mem_heap_t* heap, /*!< in: memory heap */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint err;
@@ -3602,7 +3564,7 @@ row_delete_constraint(
if ((err == DB_SUCCESS) && !strchr(id, '/')) {
/* Old format < 4.0.18 constraints have constraint ids
- <number>_<number>. We only try deleting them if the
+ NUMBER_NUMBER. We only try deleting them if the
constraint name does not contain a '/' character, otherwise
deleting a new format constraint named 'foo/bar' from
database 'baz' would remove constraint 'bar' from database
@@ -3614,17 +3576,17 @@ row_delete_constraint(
return((int) err);
}
-/*************************************************************************
-Renames a table for MySQL. */
+/*********************************************************************//**
+Renames a table for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_rename_table_for_mysql(
/*=======================*/
- /* out: error code or DB_SUCCESS */
- const char* old_name, /* in: old table name */
- const char* new_name, /* in: new table name */
- trx_t* trx, /* in: transaction handle */
- ibool commit) /* in: if TRUE then commit trx */
+ const char* old_name, /*!< in: old table name */
+ const char* new_name, /*!< in: new table name */
+ trx_t* trx, /*!< in: transaction handle */
+ ibool commit) /*!< in: if TRUE then commit trx */
{
dict_table_t* table;
ulint err = DB_ERROR;
@@ -3682,8 +3644,7 @@ row_rename_table_for_mysql(
"InnoDB: MySQL database directory"
" from another database?\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n",
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
stderr);
goto funct_exit;
} else if (table->ibd_file_missing) {
@@ -3695,8 +3656,7 @@ row_rename_table_for_mysql(
fputs(" does not have an .ibd file"
" in the database directory.\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n",
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
stderr);
goto funct_exit;
} else if (new_is_tmp) {
@@ -3848,8 +3808,7 @@ end:
"InnoDB: Have you deleted the .frm file"
" and not used DROP TABLE?\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: If table ", stderr);
ut_print_name(stderr, trx, TRUE, new_name);
fputs(" is a temporary table #sql..., then"
@@ -3869,7 +3828,7 @@ end:
"InnoDB: succeed.\n", stderr);
}
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
} else {
/* The following call will also rename the .ibd data file if
@@ -3878,7 +3837,7 @@ end:
if (!dict_table_rename_in_cache(table, new_name,
!new_is_tmp)) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
goto funct_exit;
}
@@ -3918,7 +3877,7 @@ end:
ut_a(dict_table_rename_in_cache(table,
old_name, FALSE));
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
}
}
@@ -3938,18 +3897,18 @@ funct_exit:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks that the index contains entries in an ascending order, unique
constraint is not broken, and calculates the number of index entries
-in the read view of the current transaction. */
+in the read view of the current transaction.
+@return TRUE if ok */
static
ibool
row_scan_and_check_index(
/*=====================*/
- /* out: TRUE if ok */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL */
- dict_index_t* index, /* in: index */
- ulint* n_rows) /* out: number of entries seen in the
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL */
+ dict_index_t* index, /*!< in: index */
+ ulint* n_rows) /*!< out: number of entries seen in the
current consistent read */
{
dtuple_t* prev_entry = NULL;
@@ -3971,6 +3930,14 @@ row_scan_and_check_index(
*n_rows = 0;
+ if (!row_merge_is_index_usable(prebuilt->trx, index)) {
+ /* A newly created index may lack some delete-marked
+ records that may exist in the read view of
+ prebuilt->trx. Thus, such indexes must not be
+ accessed by consistent read. */
+ return(is_ok);
+ }
+
buf = mem_alloc(UNIV_PAGE_SIZE);
heap = mem_heap_create(100);
@@ -3978,6 +3945,8 @@ row_scan_and_check_index(
in scanning the index entries */
prebuilt->index = index;
+ /* row_merge_is_index_usable() was already checked above. */
+ prebuilt->index_usable = TRUE;
prebuilt->sql_stat_start = TRUE;
prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
prebuilt->n_template = 0;
@@ -3997,7 +3966,17 @@ loop:
}
cnt = 1000;
}
- if (ret != DB_SUCCESS) {
+
+ switch (ret) {
+ case DB_SUCCESS:
+ break;
+ default:
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: Warning: CHECK TABLE on ", stderr);
+ dict_index_name_print(stderr, prebuilt->trx, index);
+ fprintf(stderr, " returned %lu\n", ret);
+ /* fall through (this error is ignored by CHECK TABLE) */
+ case DB_END_OF_INDEX:
func_exit:
mem_free(buf);
mem_heap_free(heap);
@@ -4093,14 +4072,14 @@ not_ok:
goto loop;
}
-/*************************************************************************
-Checks a table for corruption. */
+/*********************************************************************//**
+Checks a table for corruption.
+@return DB_ERROR or DB_SUCCESS */
UNIV_INTERN
ulint
row_check_table_for_mysql(
/*======================*/
- /* out: DB_ERROR or DB_SUCCESS */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
dict_table_t* table = prebuilt->table;
@@ -4121,8 +4100,7 @@ row_check_table_for_mysql(
"InnoDB: the MySQL datadir, or have you"
" used DISCARD TABLESPACE?\n"
"InnoDB: Look from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
table->name);
return(DB_ERROR);
@@ -4159,6 +4137,7 @@ row_check_table_for_mysql(
}
if (trx_is_interrupted(prebuilt->trx)) {
+ ret = DB_INTERRUPTED;
break;
}
@@ -4205,16 +4184,15 @@ row_check_table_for_mysql(
return(ret);
}
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Determines if a table is a magic monitor table. */
+/*********************************************************************//**
+Determines if a table is a magic monitor table.
+@return TRUE if monitor table */
UNIV_INTERN
ibool
row_is_magic_monitor_table(
/*=======================*/
- /* out: TRUE if monitor table */
- const char* table_name) /* in: name of the table, in the
+ const char* table_name) /*!< in: name of the table, in the
form database/table_name */
{
const char* name; /* table_name without database/ */
diff --git a/storage/xtradb/row/row0purge.c b/storage/xtradb/row/row0purge.c
index 8c3f9b993ba..500ebe571ab 100644
--- a/storage/xtradb/row/row0purge.c
+++ b/storage/xtradb/row/row0purge.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0purge.c
Purge obsolete records
Created 3/14/1997 Heikki Tuuri
@@ -43,15 +44,15 @@ Created 3/14/1997 Heikki Tuuri
#include "row0mysql.h"
#include "log0log.h"
-/************************************************************************
-Creates a purge node to a query graph. */
+/********************************************************************//**
+Creates a purge node to a query graph.
+@return own: purge node */
UNIV_INTERN
purge_node_t*
row_purge_node_create(
/*==================*/
- /* out, own: purge node */
- que_thr_t* parent, /* in: parent node, i.e., a thr node */
- mem_heap_t* heap) /* in: memory heap where created */
+ que_thr_t* parent, /*!< in: parent node, i.e., a thr node */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
purge_node_t* node;
@@ -67,17 +68,17 @@ row_purge_node_create(
return(node);
}
-/***************************************************************
+/***********************************************************//**
Repositions the pcur in the purge node on the clustered index record,
-if found. */
+if found.
+@return TRUE if the record was found */
static
ibool
row_purge_reposition_pcur(
/*======================*/
- /* out: TRUE if the record was found */
- ulint mode, /* in: latching mode */
- purge_node_t* node, /* in: row purge node */
- mtr_t* mtr) /* in: mtr */
+ ulint mode, /*!< in: latching mode */
+ purge_node_t* node, /*!< in: row purge node */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool found;
@@ -98,16 +99,16 @@ row_purge_reposition_pcur(
return(found);
}
-/***************************************************************
-Removes a delete marked clustered index record if possible. */
+/***********************************************************//**
+Removes a delete marked clustered index record if possible.
+@return TRUE if success, or if not found, or if modified after the
+delete marking */
static
ibool
row_purge_remove_clust_if_poss_low(
/*===============================*/
- /* out: TRUE if success, or if not found, or
- if modified after the delete marking */
- purge_node_t* node, /* in: row purge node */
- ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
+ purge_node_t* node, /*!< in: row purge node */
+ ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
dict_index_t* index;
btr_pcur_t* pcur;
@@ -177,14 +178,14 @@ row_purge_remove_clust_if_poss_low(
return(success);
}
-/***************************************************************
+/***********************************************************//**
Removes a clustered index record if it has not been modified after the delete
marking. */
static
void
row_purge_remove_clust_if_poss(
/*===========================*/
- purge_node_t* node) /* in: row purge node */
+ purge_node_t* node) /*!< in: row purge node */
{
ibool success;
ulint n_tries = 0;
@@ -213,17 +214,17 @@ retry:
ut_a(success);
}
-/***************************************************************
-Removes a secondary index entry if possible. */
+/***********************************************************//**
+Removes a secondary index entry if possible.
+@return TRUE if success or if not found */
static
ibool
row_purge_remove_sec_if_poss_low(
/*=============================*/
- /* out: TRUE if success or if not found */
- purge_node_t* node, /* in: row purge node */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: index entry */
- ulint mode) /* in: latch mode BTR_MODIFY_LEAF or
+ purge_node_t* node, /*!< in: row purge node */
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: index entry */
+ ulint mode) /*!< in: latch mode BTR_MODIFY_LEAF or
BTR_MODIFY_TREE */
{
btr_pcur_t pcur;
@@ -298,15 +299,15 @@ row_purge_remove_sec_if_poss_low(
return(success);
}
-/***************************************************************
+/***********************************************************//**
Removes a secondary index entry if possible. */
UNIV_INLINE
void
row_purge_remove_sec_if_poss(
/*=========================*/
- purge_node_t* node, /* in: row purge node */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry */
+ purge_node_t* node, /*!< in: row purge node */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry */
{
ibool success;
ulint n_tries = 0;
@@ -338,13 +339,13 @@ retry:
ut_a(success);
}
-/***************************************************************
+/***********************************************************//**
Purges a delete marking of a record. */
static
void
row_purge_del_mark(
/*===============*/
- purge_node_t* node) /* in: row purge node */
+ purge_node_t* node) /*!< in: row purge node */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -370,14 +371,14 @@ row_purge_del_mark(
row_purge_remove_clust_if_poss(node);
}
-/***************************************************************
+/***********************************************************//**
Purges an update of an existing record. Also purges an update of a delete
marked record if that record contained an externally stored field. */
static
void
row_purge_upd_exist_or_extern(
/*==========================*/
- purge_node_t* node) /* in: row purge node */
+ purge_node_t* node) /*!< in: row purge node */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -484,28 +485,27 @@ skip_secondaries:
}
}
-/***************************************************************
-Parses the row reference and other info in a modify undo log record. */
+/***********************************************************//**
+Parses the row reference and other info in a modify undo log record.
+@return TRUE if purge operation required: NOTE that then the CALLER
+must unfreeze data dictionary! */
static
ibool
row_purge_parse_undo_rec(
/*=====================*/
- /* out: TRUE if purge operation required:
- NOTE that then the CALLER must unfreeze
- data dictionary! */
- purge_node_t* node, /* in: row undo node */
+ purge_node_t* node, /*!< in: row undo node */
ibool* updated_extern,
- /* out: TRUE if an externally stored field
+ /*!< out: TRUE if an externally stored field
was updated */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_index_t* clust_index;
byte* ptr;
trx_t* trx;
- dulint undo_no;
+ undo_no_t undo_no;
dulint table_id;
- dulint trx_id;
- dulint roll_ptr;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
ulint info_bits;
ulint type;
ulint cmpl_info;
@@ -588,23 +588,22 @@ err_exit:
return(TRUE);
}
-/***************************************************************
+/***********************************************************//**
Fetches an undo log record and does the purge for the recorded operation.
If none left, or the current purge completed, returns the control to the
-parent node, which is always a query thread node. */
+parent node, which is always a query thread node.
+@return DB_SUCCESS if operation successfully completed, else error code */
static
ulint
row_purge(
/*======*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code */
- purge_node_t* node, /* in: row purge node */
- que_thr_t* thr) /* in: query thread */
+ purge_node_t* node, /*!< in: row purge node */
+ que_thr_t* thr) /*!< in: query thread */
{
- dulint roll_ptr;
- ibool purge_needed;
- ibool updated_extern;
- trx_t* trx;
+ roll_ptr_t roll_ptr;
+ ibool purge_needed;
+ ibool updated_extern;
+ trx_t* trx;
ut_ad(node && thr);
@@ -663,15 +662,15 @@ row_purge(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Does the purge operation for a single undo log record. This is a high-level
-function used in an SQL execution graph. */
+function used in an SQL execution graph.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_purge_step(
/*===========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
purge_node_t* node;
ulint err;
diff --git a/storage/xtradb/row/row0row.c b/storage/xtradb/row/row0row.c
index 4343ee2b009..128ac3ba3e8 100644
--- a/storage/xtradb/row/row0row.c
+++ b/storage/xtradb/row/row0row.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0row.c
General row routines
Created 4/20/1996 Heikki Tuuri
@@ -46,18 +47,18 @@ Created 4/20/1996 Heikki Tuuri
#include "read0read.h"
#include "ut0mem.h"
-/*************************************************************************
+/*********************************************************************//**
Gets the offset of trx id field, in bytes relative to the origin of
-a clustered index record. */
+a clustered index record.
+@return offset of DATA_TRX_ID */
UNIV_INTERN
ulint
row_get_trx_id_offset(
/*==================*/
- /* out: offset of DATA_TRX_ID */
const rec_t* rec __attribute__((unused)),
- /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint pos;
ulint offset;
@@ -75,24 +76,22 @@ row_get_trx_id_offset(
return(offset);
}
-/*********************************************************************
+/*****************************************************************//**
When an insert or purge to a table is performed, this function builds
-the entry to be inserted into or purged from an index on the table. */
+the entry to be inserted into or purged from an index on the table.
+@return index entry which should be inserted or purged, or NULL if the
+externally stored columns in the clustered index record are
+unavailable and ext != NULL */
UNIV_INTERN
dtuple_t*
row_build_index_entry(
/*==================*/
- /* out: index entry which should be
- inserted or purged, or NULL if the
- externally stored columns in the
- clustered index record are unavailable
- and ext != NULL */
- const dtuple_t* row, /* in: row which should be
+ const dtuple_t* row, /*!< in: row which should be
inserted or purged */
- row_ext_t* ext, /* in: externally stored column prefixes,
+ row_ext_t* ext, /*!< in: externally stored column prefixes,
or NULL */
- dict_index_t* index, /* in: index on the table */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_index_t* index, /*!< in: index on the table */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the index entry is allocated */
{
dtuple_t* entry;
@@ -167,24 +166,23 @@ row_build_index_entry(
return(entry);
}
-/***********************************************************************
+/*******************************************************************//**
An inverse function to row_build_index_entry. Builds a row from a
-record in a clustered index. */
+record in a clustered index.
+@return own: row built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_build(
/*======*/
- /* out, own: row built;
- see the NOTE below! */
- ulint type, /* in: ROW_COPY_POINTERS or
+ ulint type, /*!< in: ROW_COPY_POINTERS or
ROW_COPY_DATA; the latter
copies also the data fields to
heap while the first only
places pointers to data fields
on the index page, and thus is
more efficient */
- const dict_index_t* index, /* in: clustered index */
- const rec_t* rec, /* in: record in the clustered
+ const dict_index_t* index, /*!< in: clustered index */
+ const rec_t* rec, /*!< in: record in the clustered
index; NOTE: in the case
ROW_COPY_POINTERS the data
fields in the row will point
@@ -193,20 +191,20 @@ 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 ulint* 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,
- /* in: table, to check which
+ /*!< in: table, to check which
externally stored columns
occur in the ordering columns
of an index, or NULL if
index->table should be
consulted instead */
- row_ext_t** ext, /* out, own: cache of
+ row_ext_t** ext, /*!< out, own: cache of
externally stored column
prefixes, or NULL */
- mem_heap_t* heap) /* in: memory heap from which
+ mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
{
dtuple_t* row;
@@ -311,21 +309,20 @@ row_build(
return(row);
}
-/***********************************************************************
-Converts an index record to a typed data tuple. */
+/*******************************************************************//**
+Converts an index record to a typed data tuple.
+@return index entry built; does not set info_bits, and the data fields
+in the entry will point directly to rec */
UNIV_INTERN
dtuple_t*
row_rec_to_index_entry_low(
/*=======================*/
- /* out: index entry built; does not
- set info_bits, and the data fields in
- the entry will point directly to rec */
- 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
+ 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 */
- mem_heap_t* heap) /* in: memory heap from which
+ mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
{
dtuple_t* entry;
@@ -370,22 +367,21 @@ row_rec_to_index_entry_low(
return(entry);
}
-/***********************************************************************
+/*******************************************************************//**
Converts an index record to a typed data tuple. NOTE that externally
-stored (often big) fields are NOT copied to heap. */
+stored (often big) fields are NOT copied to heap.
+@return own: index entry built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_rec_to_index_entry(
/*===================*/
- /* out, own: index entry
- built; see the NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or
+ ulint type, /*!< in: ROW_COPY_DATA, or
ROW_COPY_POINTERS: the former
copies also the data fields to
heap as the latter only places
pointers to data fields on the
index page */
- const rec_t* rec, /* in: record in the index;
+ const rec_t* rec, /*!< in: record in the index;
NOTE: in the case
ROW_COPY_POINTERS the data
fields in the row will point
@@ -394,11 +390,11 @@ row_rec_to_index_entry(
this record must be at least
s-latched and the latch held
as long as the dtuple is used! */
- const dict_index_t* index, /* in: index */
- ulint* offsets,/* in/out: rec_get_offsets(rec) */
- ulint* n_ext, /* out: number of externally
+ const dict_index_t* index, /*!< in: index */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec) */
+ ulint* n_ext, /*!< out: number of externally
stored columns */
- mem_heap_t* heap) /* in: memory heap from which
+ mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
{
dtuple_t* entry;
@@ -423,28 +419,27 @@ row_rec_to_index_entry(
return(entry);
}
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
-search the clustered index record. */
+search the clustered index record.
+@return own: row reference built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_build_row_ref(
/*==============*/
- /* out, own: row reference built; see the
- NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
+ ulint type, /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
the former copies also the data fields to
heap, whereas the latter only places pointers
to data fields on the index page */
- dict_index_t* index, /* in: secondary index */
- const rec_t* rec, /* in: record in the index;
+ dict_index_t* index, /*!< in: secondary index */
+ const rec_t* rec, /*!< in: record in the index;
NOTE: in the case ROW_COPY_POINTERS
the data fields in the row will point
directly into this record, therefore,
the buffer page of this record must be
at least s-latched and the latch held
as long as the row reference is used! */
- mem_heap_t* heap) /* in: memory heap from which the memory
+ mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
{
dict_table_t* table;
@@ -535,16 +530,16 @@ row_build_row_ref(
return(ref);
}
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INTERN
void
row_build_row_ref_in_tuple(
/*=======================*/
- dtuple_t* ref, /* in/out: row reference built;
+ dtuple_t* ref, /*!< in/out: row reference built;
see the NOTE below! */
- const rec_t* rec, /* in: record in the index;
+ const rec_t* rec, /*!< in: record in the index;
NOTE: the data fields in ref
will point directly into this
record, therefore, the buffer
@@ -552,10 +547,10 @@ row_build_row_ref_in_tuple(
least s-latched and the latch
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)
+ const dict_index_t* index, /*!< in: secondary index */
+ ulint* offsets,/*!< in: rec_get_offsets(rec, index)
or NULL */
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
const dict_index_t* clust_index;
dfield_t* dfield;
@@ -648,80 +643,19 @@ notfound:
}
}
-/***********************************************************************
-From a row build a row reference with which we can search the clustered
-index record. */
-UNIV_INTERN
-void
-row_build_row_ref_from_row(
-/*=======================*/
- dtuple_t* ref, /* in/out: row reference built;
- see the NOTE below!
- ref must have the right number
- of fields! */
- const dict_table_t* table, /* in: table */
- const dtuple_t* row) /* in: row
- NOTE: the data fields in ref will point
- directly into data of this row */
-{
- const dict_index_t* clust_index;
- ulint ref_len;
- ulint i;
-
- ut_ad(ref && table && row);
-
- clust_index = dict_table_get_first_index(table);
-
- ref_len = dict_index_get_n_unique(clust_index);
-
- ut_ad(ref_len == dtuple_get_n_fields(ref));
-
- for (i = 0; i < ref_len; i++) {
- const dict_col_t* col;
- const dict_field_t* field;
- dfield_t* dfield;
- const dfield_t* dfield2;
-
- dfield = dtuple_get_nth_field(ref, i);
-
- field = dict_index_get_nth_field(clust_index, i);
-
- col = dict_field_get_col(field);
-
- dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col));
-
- dfield_copy(dfield, dfield2);
- ut_ad(!dfield_is_ext(dfield));
-
- if (field->prefix_len > 0 && !dfield_is_null(dfield)) {
-
- ulint len = dfield_get_len(dfield);
-
- len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminlen, col->mbmaxlen,
- field->prefix_len,
- len, dfield_get_data(dfield));
-
- dfield_set_len(dfield, len);
- }
- }
-
- ut_ad(dtuple_check_typed(ref));
-}
-
-/*******************************************************************
-Searches the clustered index record for a row, if we have the row reference. */
+/***************************************************************//**
+Searches the clustered index record for a row, if we have the row reference.
+@return TRUE if found */
UNIV_INTERN
ibool
row_search_on_row_ref(
/*==================*/
- /* out: TRUE if found */
- btr_pcur_t* pcur, /* out: persistent cursor, which must
+ btr_pcur_t* pcur, /*!< out: persistent cursor, which must
be closed by the caller */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- const dict_table_t* table, /* in: table */
- const dtuple_t* ref, /* in: row reference */
- mtr_t* mtr) /* in/out: mtr */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ const dict_table_t* table, /*!< in: table */
+ const dtuple_t* ref, /*!< in: row reference */
+ mtr_t* mtr) /*!< in/out: mtr */
{
ulint low_match;
rec_t* rec;
@@ -752,19 +686,19 @@ row_search_on_row_ref(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Fetches the clustered index record for a secondary index record. The latches
-on the secondary index record are preserved. */
+on the secondary index record are preserved.
+@return record or NULL, if no record found */
UNIV_INTERN
rec_t*
row_get_clust_rec(
/*==============*/
- /* out: record or NULL, if no record found */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- const rec_t* rec, /* in: record in a secondary index */
- dict_index_t* index, /* in: secondary index */
- dict_index_t** clust_index,/* out: clustered index */
- mtr_t* mtr) /* in: mtr */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ const rec_t* rec, /*!< in: record in a secondary index */
+ dict_index_t* index, /*!< in: secondary index */
+ dict_index_t** clust_index,/*!< out: clustered index */
+ mtr_t* mtr) /*!< in: mtr */
{
mem_heap_t* heap;
dtuple_t* ref;
@@ -794,19 +728,19 @@ row_get_clust_rec(
return(clust_rec);
}
-/*******************************************************************
-Searches an index record. */
+/***************************************************************//**
+Searches an index record.
+@return TRUE if found */
UNIV_INTERN
ibool
row_search_index_entry(
/*===================*/
- /* out: TRUE if found */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: index entry */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- btr_pcur_t* pcur, /* in/out: persistent cursor, which must
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: index entry */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ btr_pcur_t* pcur, /*!< in/out: persistent cursor, which must
be closed by the caller */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint n_fields;
ulint low_match;
@@ -824,11 +758,9 @@ row_search_index_entry(
return(!page_rec_is_infimum(rec) && low_match == n_fields);
}
-#ifndef UNIV_HOTBACKUP
-
#include <my_sys.h>
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_INT using "prtype" and writes the result to "buf".
If the data is in unknown format, then nothing is written to "buf",
@@ -837,21 +769,20 @@ If the data is in unknown format, then nothing is written to "buf",
Not more than "buf_size" bytes are written to "buf".
The result is always '\0'-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating '\0').
+@return number of bytes that were written */
static
ulint
row_raw_format_int(
/*===============*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- ulint prtype, /* in: precise type */
- char* buf, /* out: output buffer */
- ulint buf_size, /* in: output buffer size
+ ulint prtype, /*!< in: precise type */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size, /*!< in: output buffer size
in bytes */
- ibool* format_in_hex) /* out: should the data be
+ ibool* format_in_hex) /*!< out: should the data be
formated in hex */
{
ulint ret;
@@ -883,7 +814,7 @@ row_raw_format_int(
return(ut_min(ret, buf_size));
}
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "prtype" and writes the
result to "buf".
@@ -893,21 +824,20 @@ If the data is in binary format, then nothing is written to "buf",
Not more than "buf_size" bytes are written to "buf".
The result is always '\0'-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating '\0').
+@return number of bytes that were written */
static
ulint
row_raw_format_str(
/*===============*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- ulint prtype, /* in: precise type */
- char* buf, /* out: output buffer */
- ulint buf_size, /* in: output buffer size
+ ulint prtype, /*!< in: precise type */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size, /*!< in: output buffer size
in bytes */
- ibool* format_in_hex) /* out: should the data be
+ ibool* format_in_hex) /*!< out: should the data be
formated in hex */
{
ulint charset_coll;
@@ -938,25 +868,24 @@ row_raw_format_str(
buf, buf_size));
}
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) using
"dict_field" and writes the result to "buf".
Not more than "buf_size" bytes are written to "buf".
-The result is always '\0'-terminated (provided buf_size > 0) and the
+The result is always NUL-terminated (provided buf_size is positive) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating NUL).
+@return number of bytes that were written */
UNIV_INTERN
ulint
row_raw_format(
/*===========*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- const dict_field_t* dict_field, /* in: index field */
- char* buf, /* out: output buffer */
- ulint buf_size) /* in: output buffer size
+ const dict_field_t* dict_field, /*!< in: index field */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size) /*!< in: output buffer size
in bytes */
{
ulint mtype;
@@ -1020,8 +949,6 @@ row_raw_format(
return(ret);
}
-#endif /* !UNIV_HOTBACKUP */
-
#ifdef UNIV_COMPILE_TEST_FUNCS
#include "ut0dbg.h"
diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c
index ff3171a3df8..4a6a3ed878d 100644
--- a/storage/xtradb/row/row0sel.c
+++ b/storage/xtradb/row/row0sel.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*******************************************************
+/***************************************************//**
+@file row/row0sel.c
Select
Created 12/19/1997 Heikki Tuuri
@@ -74,34 +75,33 @@ to que_run_threads: this is to allow canceling runaway queries */
#define SEL_EXHAUSTED 1
#define SEL_RETRY 2
-/************************************************************************
+/********************************************************************//**
Returns TRUE if the user-defined column in a secondary index record
is alphabetically the same as the corresponding BLOB column in the clustered
index record.
NOTE: the comparison is NOT done as a binary comparison, but character
-fields are compared with collation! */
+fields are compared with collation!
+@return TRUE if the columns are equal */
static
ibool
row_sel_sec_rec_is_for_blob(
/*========================*/
- /* out: TRUE if the columns
- are equal */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint mbminlen, /* in: minimum length of a
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint mbminlen, /*!< in: minimum length of a
multi-byte character */
- ulint mbmaxlen, /* in: maximum length of a
+ ulint mbmaxlen, /*!< in: maximum length of a
multi-byte character */
- const byte* clust_field, /* in: the locally stored part of
+ const byte* clust_field, /*!< in: the locally stored part of
the clustered index column, including
the BLOB pointer; the clustered
index record must be covered by
a lock or a page latch to protect it
against deletion (rollback or purge) */
- ulint clust_len, /* in: length of clust_field */
- const byte* sec_field, /* in: column in secondary index */
- ulint sec_len, /* in: length of sec_field */
- ulint zip_size) /* in: compressed page size, or 0 */
+ ulint clust_len, /*!< in: length of clust_field */
+ const byte* sec_field, /*!< in: column in secondary index */
+ ulint sec_len, /*!< in: length of sec_field */
+ ulint zip_size) /*!< in: compressed page size, or 0 */
{
ulint len;
byte buf[DICT_MAX_INDEX_COL_LEN];
@@ -125,27 +125,25 @@ row_sel_sec_rec_is_for_blob(
return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
}
-/************************************************************************
+/********************************************************************//**
Returns TRUE if the user-defined column values in a secondary index record
are alphabetically the same as the corresponding columns in the clustered
index record.
NOTE: the comparison is NOT done as a binary comparison, but character
-fields are compared with collation! */
+fields are compared with collation!
+@return TRUE if the secondary record is equal to the corresponding
+fields in the clustered record, when compared with collation */
static
ibool
row_sel_sec_rec_is_for_clust_rec(
/*=============================*/
- /* out: TRUE if the secondary
- record is equal to the corresponding
- fields in the clustered record,
- when compared with collation */
- const rec_t* sec_rec, /* in: secondary index record */
- dict_index_t* sec_index, /* in: secondary index */
- const rec_t* clust_rec, /* in: clustered index record;
+ const rec_t* sec_rec, /*!< in: secondary index record */
+ dict_index_t* sec_index, /*!< in: secondary index */
+ const rec_t* clust_rec, /*!< in: clustered index record;
must be protected by a lock or
a page latch against deletion
in rollback or purge */
- dict_index_t* clust_index) /* in: clustered index */
+ dict_index_t* clust_index) /*!< in: clustered index */
{
const byte* sec_field;
ulint sec_len;
@@ -238,14 +236,14 @@ func_exit:
return(is_equal);
}
-/*************************************************************************
-Creates a select node struct. */
+/*********************************************************************//**
+Creates a select node struct.
+@return own: select node struct */
UNIV_INTERN
sel_node_t*
sel_node_create(
/*============*/
- /* out, own: select node struct */
- mem_heap_t* heap) /* in: memory heap where created */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
sel_node_t* node;
@@ -258,14 +256,14 @@ sel_node_create(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Frees the memory private to a select node when a query graph is freed,
does not free the heap where the node was originally created. */
UNIV_INTERN
void
sel_node_free_private(
/*==================*/
- sel_node_t* node) /* in: select node struct */
+ sel_node_t* node) /*!< in: select node struct */
{
ulint i;
plan_t* plan;
@@ -284,14 +282,14 @@ sel_node_free_private(
}
}
-/*************************************************************************
+/*********************************************************************//**
Evaluates the values in a select list. If there are aggregate functions,
their argument value is added to the aggregate total. */
UNIV_INLINE
void
sel_eval_select_list(
/*=================*/
- sel_node_t* node) /* in: select node */
+ sel_node_t* node) /*!< in: select node */
{
que_node_t* exp;
@@ -304,15 +302,15 @@ sel_eval_select_list(
}
}
-/*************************************************************************
+/*********************************************************************//**
Assigns the values in the select list to the possible into-variables in
SELECT ... INTO ... */
UNIV_INLINE
void
sel_assign_into_var_values(
/*=======================*/
- sym_node_t* var, /* in: first variable in a list of variables */
- sel_node_t* node) /* in: select node */
+ sym_node_t* var, /*!< in: first variable in a list of variables */
+ sel_node_t* node) /*!< in: select node */
{
que_node_t* exp;
@@ -333,14 +331,14 @@ sel_assign_into_var_values(
}
}
-/*************************************************************************
+/*********************************************************************//**
Resets the aggregate value totals in the select list of an aggregate type
query. */
UNIV_INLINE
void
sel_reset_aggregate_vals(
/*=====================*/
- sel_node_t* node) /* in: select node */
+ sel_node_t* node) /*!< in: select node */
{
func_node_t* func_node;
@@ -357,13 +355,13 @@ sel_reset_aggregate_vals(
node->aggregate_already_fetched = FALSE;
}
-/*************************************************************************
+/*********************************************************************//**
Copies the input variable values when an explicit cursor is opened. */
UNIV_INLINE
void
row_sel_copy_input_variable_vals(
/*=============================*/
- sel_node_t* node) /* in: select node */
+ sel_node_t* node) /*!< in: select node */
{
sym_node_t* var;
@@ -378,17 +376,17 @@ row_sel_copy_input_variable_vals(
}
}
-/*************************************************************************
+/*********************************************************************//**
Fetches the column values from a record. */
static
void
row_sel_fetch_columns(
/*==================*/
- dict_index_t* index, /* in: record index */
- const rec_t* rec, /* in: record in a clustered or non-clustered
+ 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) */
- sym_node_t* column) /* in: first column in a column list, or
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ sym_node_t* column) /*!< in: first column in a column list, or
NULL */
{
dfield_t* val;
@@ -457,13 +455,13 @@ row_sel_fetch_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Allocates a prefetch buffer for a column when prefetch is first time done. */
static
void
sel_col_prefetch_buf_alloc(
/*=======================*/
- sym_node_t* column) /* in: symbol table node for a column */
+ sym_node_t* column) /*!< in: symbol table node for a column */
{
sel_buf_t* sel_buf;
ulint i;
@@ -481,14 +479,14 @@ sel_col_prefetch_buf_alloc(
}
}
-/*************************************************************************
+/*********************************************************************//**
Frees a prefetch buffer for a column, including the dynamically allocated
memory for data stored there. */
UNIV_INTERN
void
sel_col_prefetch_buf_free(
/*======================*/
- sel_buf_t* prefetch_buf) /* in, own: prefetch buffer */
+ sel_buf_t* prefetch_buf) /*!< in, own: prefetch buffer */
{
sel_buf_t* sel_buf;
ulint i;
@@ -503,14 +501,14 @@ sel_col_prefetch_buf_free(
}
}
-/*************************************************************************
+/*********************************************************************//**
Pops the column values for a prefetched, cached row from the column prefetch
buffers and places them to the val fields in the column nodes. */
static
void
sel_pop_prefetched_row(
/*===================*/
- plan_t* plan) /* in: plan node for a table */
+ plan_t* plan) /*!< in: plan node for a table */
{
sym_node_t* column;
sel_buf_t* sel_buf;
@@ -565,14 +563,14 @@ next_col:
plan->first_prefetched++;
}
-/*************************************************************************
+/*********************************************************************//**
Pushes the column values for a prefetched, cached row to the column prefetch
buffers from the val fields in the column nodes. */
UNIV_INLINE
void
sel_push_prefetched_row(
/*====================*/
- plan_t* plan) /* in: plan node for a table */
+ plan_t* plan) /*!< in: plan node for a table */
{
sym_node_t* column;
sel_buf_t* sel_buf;
@@ -637,26 +635,26 @@ next_col:
}
}
-/*************************************************************************
-Builds a previous version of a clustered index record for a consistent read */
+/*********************************************************************//**
+Builds a previous version of a clustered index record for a consistent read
+@return DB_SUCCESS or error code */
static
ulint
row_sel_build_prev_vers(
/*====================*/
- /* out: DB_SUCCESS or error code */
- read_view_t* 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
+ read_view_t* 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_get_offsets(rec, plan->index) */
- mem_heap_t** offset_heap, /* in/out: memory heap from which
+ mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t** old_vers_heap, /* out: old version heap to use */
- rec_t** old_vers, /* out: old version, or NULL if the
+ mem_heap_t** old_vers_heap, /*!< out: old version heap to use */
+ rec_t** old_vers, /*!< out: old version, or NULL if the
record does not exist in the view:
i.e., it was freshly inserted
afterwards */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint err;
@@ -672,26 +670,26 @@ row_sel_build_prev_vers(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Builds the last committed version of a clustered index record for a
-semi-consistent read. */
+semi-consistent read.
+@return DB_SUCCESS or error code */
static
ulint
row_sel_build_committed_vers_for_mysql(
/*===================================*/
- /* out: DB_SUCCESS or error code */
- 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
+ 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_get_offsets(rec, clust_index) */
- mem_heap_t** offset_heap, /* in/out: memory heap from which
+ mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
- const rec_t** old_vers, /* out: old version, or NULL if the
+ const rec_t** old_vers, /*!< out: old version, or NULL if the
record does not exist in the view:
i.e., it was freshly inserted
afterwards */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint err;
@@ -707,15 +705,15 @@ row_sel_build_committed_vers_for_mysql(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Tests the conditions which determine when the index segment we are searching
-through has been exhausted. */
+through has been exhausted.
+@return TRUE if row passed the tests */
UNIV_INLINE
ibool
row_sel_test_end_conds(
/*===================*/
- /* out: TRUE if row passed the tests */
- plan_t* plan) /* in: plan for the table; the column values must
+ plan_t* plan) /*!< in: plan for the table; the column values must
already have been retrieved and the right sides of
comparisons evaluated */
{
@@ -745,14 +743,14 @@ row_sel_test_end_conds(
return(TRUE);
}
-/*************************************************************************
-Tests the other conditions. */
+/*********************************************************************//**
+Tests the other conditions.
+@return TRUE if row passed the tests */
UNIV_INLINE
ibool
row_sel_test_other_conds(
/*=====================*/
- /* out: TRUE if row passed the tests */
- plan_t* plan) /* in: plan for the table; the column values must
+ plan_t* plan) /*!< in: plan for the table; the column values must
already have been retrieved */
{
func_node_t* cond;
@@ -773,23 +771,23 @@ row_sel_test_other_conds(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Retrieves the clustered index record corresponding to a record in a
-non-clustered index. Does the necessary locking. */
+non-clustered index. Does the necessary locking.
+@return DB_SUCCESS or error code */
static
ulint
row_sel_get_clust_rec(
/*==================*/
- /* out: DB_SUCCESS or error code */
- sel_node_t* node, /* in: select_node */
- plan_t* plan, /* in: plan node for table */
- rec_t* rec, /* in: record in a non-clustered index */
- que_thr_t* thr, /* in: query thread */
- rec_t** out_rec,/* out: clustered record or an old version of
+ sel_node_t* node, /*!< in: select_node */
+ plan_t* plan, /*!< in: plan node for table */
+ rec_t* rec, /*!< in: record in a non-clustered index */
+ que_thr_t* thr, /*!< in: query thread */
+ rec_t** out_rec,/*!< out: clustered record or an old version of
it, NULL if the old version did not exist
in the read view, i.e., it was a fresh
inserted version */
- mtr_t* mtr) /* in: mtr used to get access to the
+ mtr_t* mtr) /*!< in: mtr used to get access to the
non-clustered record; the same mtr is used to
access the clustered index */
{
@@ -937,21 +935,21 @@ err_exit:
return(err);
}
-/*************************************************************************
-Sets a lock on a record. */
+/*********************************************************************//**
+Sets a lock on a record.
+@return DB_SUCCESS or error code */
UNIV_INLINE
ulint
sel_set_rec_lock(
/*=============*/
- /* out: DB_SUCCESS or error code */
- 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) */
- ulint mode, /* in: lock mode */
- ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
+ 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) */
+ ulint mode, /*!< in: lock mode */
+ ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOC_REC_NOT_GAP */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
ulint err;
@@ -976,18 +974,18 @@ sel_set_rec_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Opens a pcur to a table index. */
static
void
row_sel_open_pcur(
/*==============*/
- plan_t* plan, /* in: table plan */
+ plan_t* plan, /*!< in: table plan */
ibool search_latch_locked,
- /* in: TRUE if the thread currently
+ /*!< in: TRUE if the thread currently
has the search latch locked in
s-mode */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
func_node_t* cond;
@@ -1051,19 +1049,18 @@ row_sel_open_pcur(
plan->pcur_is_open = TRUE;
}
-/*************************************************************************
-Restores a stored pcur position to a table index. */
+/*********************************************************************//**
+Restores a stored pcur position to a table index.
+@return TRUE if the cursor should be moved to the next record after we
+return from this function (moved to the previous, in the case of a
+descending cursor) without processing again the current cursor
+record */
static
ibool
row_sel_restore_pcur_pos(
/*=====================*/
- /* out: TRUE if the cursor should be moved to
- the next record after we return from this
- function (moved to the previous, in the case
- of a descending cursor) without processing
- again the current cursor record */
- plan_t* plan, /* in: table plan */
- mtr_t* mtr) /* in: mtr */
+ plan_t* plan, /*!< in: table plan */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool equal_position;
ulint relative_position;
@@ -1147,13 +1144,13 @@ row_sel_restore_pcur_pos(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Resets a plan cursor to a closed state. */
UNIV_INLINE
void
plan_reset_cursor(
/*==============*/
- plan_t* plan) /* in: plan */
+ plan_t* plan) /*!< in: plan */
{
plan->pcur_is_open = FALSE;
plan->cursor_at_end = FALSE;
@@ -1161,18 +1158,18 @@ plan_reset_cursor(
plan->n_rows_prefetched = 0;
}
-/*************************************************************************
+/*********************************************************************//**
Tries to do a shortcut to fetch a clustered index record with a unique key,
-using the hash index if possible (not always). */
+using the hash index if possible (not always).
+@return SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
static
ulint
row_sel_try_search_shortcut(
/*========================*/
- /* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
- sel_node_t* node, /* in: select node for a consistent read */
- plan_t* plan, /* in: plan for a unique search in clustered
+ sel_node_t* node, /*!< in: select node for a consistent read */
+ plan_t* plan, /*!< in: plan for a unique search in clustered
index */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
rec_t* rec;
@@ -1263,15 +1260,15 @@ func_exit:
return(ret);
}
-/*************************************************************************
-Performs a select step. */
+/*********************************************************************//**
+Performs a select step.
+@return DB_SUCCESS or error code */
static
ulint
row_sel(
/*====*/
- /* out: DB_SUCCESS or error code */
- sel_node_t* node, /* in: select node */
- que_thr_t* thr) /* in: query thread */
+ sel_node_t* node, /*!< in: select node */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_index_t* index;
plan_t* plan;
@@ -1964,15 +1961,15 @@ func_exit:
return(err);
}
-/**************************************************************************
+/**********************************************************************//**
Performs a select step. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_sel_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint i_lock_mode;
sym_node_t* table_node;
@@ -2066,14 +2063,14 @@ row_sel_step(
return(thr);
}
-/**************************************************************************
-Performs a fetch for a cursor. */
+/**********************************************************************//**
+Performs a fetch for a cursor.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
fetch_step(
/*=======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
sel_node_t* sel_node;
fetch_node_t* node;
@@ -2129,15 +2126,15 @@ fetch_step(
return(thr);
}
-/********************************************************************
-Sample callback function for fetch that prints each row.*/
+/****************************************************************//**
+Sample callback function for fetch that prints each row.
+@return always returns non-NULL */
UNIV_INTERN
void*
row_fetch_print(
/*============*/
- /* out: always returns non-NULL */
- void* row, /* in: sel_node_t* */
- void* user_arg) /* in: not used */
+ void* row, /*!< in: sel_node_t* */
+ void* user_arg) /*!< in: not used */
{
sel_node_t* node = row;
que_node_t* exp;
@@ -2173,17 +2170,17 @@ row_fetch_print(
return((void*)42);
}
-/********************************************************************
+/****************************************************************//**
Callback function for fetch that stores an unsigned 4 byte integer to the
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
-= 4. */
+= 4.
+@return always returns NULL */
UNIV_INTERN
void*
row_fetch_store_uint4(
/*==================*/
- /* out: always returns NULL */
- void* row, /* in: sel_node_t* */
- void* user_arg) /* in: data pointer */
+ void* row, /*!< in: sel_node_t* */
+ void* user_arg) /*!< in: data pointer */
{
sel_node_t* node = row;
ib_uint32_t* val = user_arg;
@@ -2203,14 +2200,14 @@ row_fetch_store_uint4(
return(NULL);
}
-/***************************************************************
-Prints a row in a select result. */
+/***********************************************************//**
+Prints a row in a select result.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_printf_step(
/*============*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
row_printf_node_t* node;
sel_node_t* sel_node;
@@ -2266,7 +2263,7 @@ row_printf_step(
return(thr);
}
-/********************************************************************
+/****************************************************************//**
Converts a key value stored in MySQL format to an Innobase dtuple. The last
field of the key value may be just a prefix of a fixed length field: hence
the parameter key_len. But currently we do not allow search keys where the
@@ -2277,17 +2274,17 @@ UNIV_INTERN
void
row_sel_convert_mysql_key_to_innobase(
/*==================================*/
- dtuple_t* tuple, /* in/out: tuple where to build;
+ dtuple_t* tuple, /*!< in/out: tuple where to build;
NOTE: we assume that the type info
in the tuple is already according
to index! */
- byte* buf, /* in: buffer to use in field
+ byte* buf, /*!< in: buffer to use in field
conversions */
- ulint buf_len, /* in: buffer length */
- dict_index_t* index, /* in: index of the key value */
- const byte* key_ptr, /* in: MySQL key value */
- ulint key_len, /* in: MySQL key value length */
- trx_t* trx) /* in: transaction */
+ ulint buf_len, /*!< in: buffer length */
+ dict_index_t* index, /*!< in: index of the key value */
+ const byte* key_ptr, /*!< in: MySQL key value */
+ ulint key_len, /*!< in: MySQL key value length */
+ trx_t* trx) /*!< in: transaction */
{
byte* original_buf = buf;
const byte* original_key_ptr = key_ptr;
@@ -2470,16 +2467,16 @@ row_sel_convert_mysql_key_to_innobase(
dtuple_set_n_fields(tuple, n_fields);
}
-/******************************************************************
+/**************************************************************//**
Stores the row id to the prebuilt struct. */
static
void
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
+ 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
(index_rec, index) */
{
const byte* data;
@@ -2508,26 +2505,26 @@ row_sel_store_row_id_to_prebuilt(
ut_memcpy(prebuilt->row_id, data, len);
}
-/******************************************************************
+/**************************************************************//**
Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
function is row_mysql_store_col_in_innobase_format() in row0mysql.c. */
static
void
row_sel_field_store_in_mysql_format(
/*================================*/
- byte* dest, /* in/out: buffer where to store; NOTE
+ byte* dest, /*!< in/out: buffer where to store; NOTE
that BLOBs are not in themselves
stored here: the caller must allocate
and copy the BLOB into buffer before,
and pass the pointer to the BLOB in
'data' */
const mysql_row_templ_t* templ,
- /* in: MySQL column template.
+ /*!< in: MySQL column template.
Its following fields are referenced:
type, is_unsigned, mysql_col_len,
mbminlen, mbmaxlen */
- const byte* data, /* in: data to store */
- ulint len) /* in: length of the data */
+ const byte* data, /*!< in: data to store */
+ ulint len) /*!< in: length of the data */
{
byte* ptr;
byte* field_end;
@@ -2663,22 +2660,20 @@ row_sel_field_store_in_mysql_format(
}
}
-/******************************************************************
+/**************************************************************//**
Convert a row in the Innobase format to a row in the MySQL format.
Note that the template in prebuilt may advise us to copy only a few
columns to mysql_rec, other columns are left blank. All columns may not
-be needed in the query. */
+be needed in the query.
+@return TRUE if success, FALSE if could not allocate memory for a BLOB
+(though we may also assert in that case) */
static
ibool
row_sel_store_mysql_rec(
/*====================*/
- /* out: TRUE if success, FALSE if
- could not allocate memory for a BLOB
- (though we may also assert in that
- case) */
- byte* mysql_rec, /* out: row in the MySQL format */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct */
- const rec_t* rec, /* in: Innobase record in the index
+ byte* mysql_rec, /*!< out: row in the MySQL format */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
+ const rec_t* rec, /*!< in: Innobase record in the index
which was described in prebuilt's
template; must be protected by
a page latch */
@@ -2789,7 +2784,8 @@ row_sel_store_mysql_rec(
mysql_rec[templ->mysql_null_byte_offset]
|= (byte) templ->mysql_null_bit_mask;
memcpy(mysql_rec + templ->mysql_col_offset,
- prebuilt->default_rec + templ->mysql_col_offset,
+ (const byte*) prebuilt->default_rec
+ + templ->mysql_col_offset,
templ->mysql_col_len);
}
}
@@ -2797,26 +2793,26 @@ row_sel_store_mysql_rec(
return(TRUE);
}
-/*************************************************************************
-Builds a previous version of a clustered index record for a consistent read */
+/*********************************************************************//**
+Builds a previous version of a clustered index record for a consistent read
+@return DB_SUCCESS or error code */
static
ulint
row_sel_build_prev_vers_for_mysql(
/*==============================*/
- /* out: DB_SUCCESS or error code */
- read_view_t* read_view, /* in: read view */
- 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
+ read_view_t* read_view, /*!< in: read view */
+ 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_get_offsets(rec, clust_index) */
- mem_heap_t** offset_heap, /* in/out: memory heap from which
+ mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
- rec_t** old_vers, /* out: old version, or NULL if the
+ rec_t** old_vers, /*!< out: old version, or NULL if the
record does not exist in the view:
i.e., it was freshly inserted
afterwards */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint err;
@@ -2832,33 +2828,33 @@ row_sel_build_prev_vers_for_mysql(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Retrieves the clustered index record corresponding to a record in a
non-clustered index. Does the necessary locking. Used in the MySQL
-interface. */
+interface.
+@return DB_SUCCESS or error code */
static
ulint
row_sel_get_clust_rec_for_mysql(
/*============================*/
- /* out: DB_SUCCESS or error code */
- row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */
- dict_index_t* sec_index,/* in: secondary index where rec resides */
- const rec_t* rec, /* in: record in a non-clustered index; if
+ row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */
+ dict_index_t* sec_index,/*!< in: secondary index where rec resides */
+ const rec_t* rec, /*!< in: record in a non-clustered index; if
this is a locking read, then rec is not
allowed to be delete-marked, and that would
not make sense either */
- que_thr_t* thr, /* in: query thread */
- const rec_t** out_rec,/* out: clustered record or an old version of
+ que_thr_t* thr, /*!< in: query thread */
+ const rec_t** out_rec,/*!< out: clustered record or an old version of
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
+ ulint** offsets,/*!< in: offsets returned by
rec_get_offsets(rec, sec_index);
out: offsets returned by
rec_get_offsets(out_rec, clust_index) */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mtr_t* mtr) /* in: mtr used to get access to the
+ mtr_t* mtr) /*!< in: mtr used to get access to the
non-clustered record; the same mtr is used to
access the clustered index */
{
@@ -3016,29 +3012,27 @@ err_exit:
return(err);
}
-/************************************************************************
+/********************************************************************//**
Restores cursor position after it has been stored. We have to take into
account that the record cursor was positioned on may have been deleted.
-Then we may have to move the cursor one step up or down. */
+Then we may have to move the cursor one step up or down.
+@return TRUE if we may need to process the record the cursor is now
+positioned on (i.e. we should not go to the next record yet) */
static
ibool
sel_restore_position_for_mysql(
/*===========================*/
- /* out: TRUE if we may need to
- process the record the cursor is
- now positioned on (i.e. we should
- not go to the next record yet) */
- ibool* same_user_rec, /* out: TRUE if we were able to restore
+ ibool* same_user_rec, /*!< out: TRUE if we were able to restore
the cursor on a user record with the
same ordering prefix in in the
B-tree index */
- ulint latch_mode, /* in: latch mode wished in
+ ulint latch_mode, /*!< in: latch mode wished in
restoration */
- btr_pcur_t* pcur, /* in: cursor whose position
+ btr_pcur_t* pcur, /*!< in: cursor whose position
has been stored */
- ibool moves_up, /* in: TRUE if the cursor moves up
+ ibool moves_up, /*!< in: TRUE if the cursor moves up
in the index */
- mtr_t* mtr) /* in: mtr; CAUTION: may commit
+ mtr_t* mtr) /*!< in: mtr; CAUTION: may commit
mtr temporarily! */
{
ibool success;
@@ -3086,15 +3080,15 @@ sel_restore_position_for_mysql(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Pops a cached row for MySQL from the fetch cache. */
UNIV_INLINE
void
row_sel_pop_cached_row_for_mysql(
/*=============================*/
- byte* buf, /* in/out: buffer where to copy the
+ byte* buf, /*!< in/out: buffer where to copy the
row */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct */
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct */
{
ulint i;
mysql_row_templ_t* templ;
@@ -3140,14 +3134,14 @@ row_sel_pop_cached_row_for_mysql(
}
}
-/************************************************************************
+/********************************************************************//**
Pushes a row for MySQL to the fetch cache. */
UNIV_INLINE
void
row_sel_push_cache_row_for_mysql(
/*=============================*/
- row_prebuilt_t* prebuilt, /* in: prebuilt struct */
- const rec_t* rec, /* in: record to push; must
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
+ const rec_t* rec, /*!< in: record to push; must
be protected by a page latch */
const ulint* offsets, /* in: rec_get_offsets() */
ulint start_field_no, /* in: start from this field */
@@ -3223,21 +3217,21 @@ row_sel_push_cache_row_for_mysql(
prebuilt->n_fetch_cached++;
}
-/*************************************************************************
+/*********************************************************************//**
Tries to do a shortcut to fetch a clustered index record with a unique key,
using the hash index if possible (not always). We assume that the search
mode is PAGE_CUR_GE, it is a consistent read, there is a read view in trx,
-btr search latch has been locked in S-mode. */
+btr search latch has been locked in S-mode.
+@return SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
static
ulint
row_sel_try_search_shortcut_for_mysql(
/*==================================*/
- /* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
- 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) */
- mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */
- mtr_t* mtr) /* in: started mtr */
+ 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) */
+ mem_heap_t** heap, /*!< in/out: heap for rec_get_offsets() */
+ mtr_t* mtr) /*!< in: started mtr */
{
dict_index_t* index = prebuilt->index;
const dtuple_t* search_tuple = prebuilt->search_tuple;
@@ -3294,34 +3288,31 @@ row_sel_try_search_shortcut_for_mysql(
return(SEL_FOUND);
}
-/************************************************************************
+/********************************************************************//**
Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next
and fetch prev. NOTE that if we do a search with a full key value
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
-position and fetch next or fetch prev must not be tried to the cursor! */
+position and fetch next or fetch prev must not be tried to the cursor!
+@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK,
+DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */
UNIV_INTERN
ulint
row_search_for_mysql(
/*=================*/
- /* out: DB_SUCCESS,
- DB_RECORD_NOT_FOUND,
- DB_END_OF_INDEX, DB_DEADLOCK,
- DB_LOCK_TABLE_FULL, DB_CORRUPTION,
- or DB_TOO_BIG_RECORD */
- byte* buf, /* in/out: buffer for the fetched
+ byte* buf, /*!< in/out: buffer for the fetched
row in the MySQL format */
- ulint mode, /* in: search mode PAGE_CUR_L, ... */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct for the
+ ulint mode, /*!< in: search mode PAGE_CUR_L, ... */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct for the
table handle; this contains the info
of search_tuple, index; if search
tuple contains 0 fields then we
position the cursor at the start or
the end of the index, depending on
'mode' */
- ulint match_mode, /* in: 0 or ROW_SEL_EXACT or
+ ulint match_mode, /*!< in: 0 or ROW_SEL_EXACT or
ROW_SEL_EXACT_PREFIX */
- ulint direction) /* in: 0 or ROW_SEL_NEXT or
+ ulint direction) /*!< in: 0 or ROW_SEL_NEXT or
ROW_SEL_PREV; NOTE: if this is != 0,
then prebuilt must have a pcur
with stored position! In opening of a
@@ -3377,14 +3368,18 @@ row_search_for_mysql(
"InnoDB: the MySQL datadir, or have you used"
" DISCARD TABLESPACE?\n"
"InnoDB: Look from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
return(DB_ERROR);
}
+ if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
+
+ return(DB_MISSING_HISTORY);
+ }
+
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
fprintf(stderr,
"InnoDB: Error: trying to free a corrupt\n"
@@ -4624,17 +4619,16 @@ func_exit:
return(err);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if MySQL at the moment is allowed for this table to retrieve a
-consistent read result, or store it to the query cache. */
+consistent read result, or store it to the query cache.
+@return TRUE if storing or retrieving from the query cache is permitted */
UNIV_INTERN
ibool
row_search_check_if_query_cache_permitted(
/*======================================*/
- /* out: TRUE if storing or retrieving
- from the query cache is permitted */
- trx_t* trx, /* in: transaction object */
- const char* norm_name) /* in: concatenation of database name,
+ trx_t* trx, /*!< in: transaction object */
+ const char* norm_name) /*!< in: concatenation of database name,
'/' char, table name */
{
dict_table_t* table;
@@ -4681,18 +4675,19 @@ row_search_check_if_query_cache_permitted(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Read the AUTOINC column from the current row. If the value is less than
-0 and the type is not unsigned then we reset the value to 0. */
+0 and the type is not unsigned then we reset the value to 0.
+@return value read from the column */
static
ib_uint64_t
row_search_autoinc_read_column(
/*===========================*/
- /* out: value read from the column */
- dict_index_t* index, /* in: index to read from */
- const rec_t* rec, /* in: current rec */
- ulint col_no, /* in: column number */
- ibool unsigned_type) /* in: signed or unsigned flag */
+ dict_index_t* index, /*!< in: index to read from */
+ const rec_t* rec, /*!< in: current rec */
+ ulint col_no, /*!< in: column number */
+ ulint mtype, /*!< in: column main type */
+ ibool unsigned_type) /*!< in: signed or unsigned flag */
{
ulint len;
const byte* data;
@@ -4708,10 +4703,27 @@ row_search_autoinc_read_column(
data = rec_get_nth_field(rec, offsets, col_no, &len);
ut_a(len != UNIV_SQL_NULL);
- ut_a(len <= sizeof value);
/* we assume AUTOINC value cannot be negative */
- value = mach_read_int_type(data, len, unsigned_type);
+ switch (mtype) {
+ case DATA_INT:
+ ut_a(len <= sizeof value);
+ value = mach_read_int_type(data, len, unsigned_type);
+ break;
+
+ case DATA_FLOAT:
+ ut_a(len == sizeof(float));
+ value = mach_float_read(data);
+ break;
+
+ case DATA_DOUBLE:
+ ut_a(len == sizeof(double));
+ value = mach_double_read(data);
+ break;
+
+ default:
+ ut_error;
+ }
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@@ -4724,15 +4736,15 @@ row_search_autoinc_read_column(
return(value);
}
-/***********************************************************************
-Get the last row. */
+/*******************************************************************//**
+Get the last row.
+@return current rec or NULL */
static
const rec_t*
row_search_autoinc_get_rec(
/*=======================*/
- /* out: current rec or NULL */
- btr_pcur_t* pcur, /* in: the current cursor */
- mtr_t* mtr) /* in: mini transaction */
+ btr_pcur_t* pcur, /*!< in: the current cursor */
+ mtr_t* mtr) /*!< in: mini transaction */
{
do {
const rec_t* rec = btr_pcur_get_rec(pcur);
@@ -4745,18 +4757,17 @@ row_search_autoinc_get_rec(
return(NULL);
}
-/***********************************************************************
-Read the max AUTOINC value from an index. */
+/*******************************************************************//**
+Read the max AUTOINC value from an index.
+@return DB_SUCCESS if all OK else error code, DB_RECORD_NOT_FOUND if
+column name can't be found in index */
UNIV_INTERN
ulint
row_search_max_autoinc(
/*===================*/
- /* out: DB_SUCCESS if all OK else
- error code, DB_RECORD_NOT_FOUND if
- column name can't be found in index */
- dict_index_t* index, /* in: index to search */
- const char* col_name, /* in: name of autoinc column */
- ib_uint64_t* value) /* out: AUTOINC value read */
+ dict_index_t* index, /*!< in: index to search */
+ const char* col_name, /*!< in: name of autoinc column */
+ ib_uint64_t* value) /*!< out: AUTOINC value read */
{
ulint i;
ulint n_cols;
@@ -4798,7 +4809,8 @@ row_search_max_autoinc(
dfield->col->prtype & DATA_UNSIGNED);
*value = row_search_autoinc_read_column(
- index, rec, i, unsigned_type);
+ index, rec, i,
+ dfield->col->mtype, unsigned_type);
}
}
diff --git a/storage/xtradb/row/row0uins.c b/storage/xtradb/row/row0uins.c
index 69d6b2e6c2a..9f9c814f1a5 100644
--- a/storage/xtradb/row/row0uins.c
+++ b/storage/xtradb/row/row0uins.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0uins.c
Fresh insert undo
Created 2/25/1997 Heikki Tuuri
@@ -45,15 +46,15 @@ Created 2/25/1997 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "log0log.h"
-/*******************************************************************
+/***************************************************************//**
Removes a clustered index record. The pcur in node was positioned on the
-record, now it is detached. */
+record, now it is detached.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_ins_remove_clust_rec(
/*==========================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node) /* in: undo node */
+ undo_node_t* node) /*!< in: undo node */
{
btr_cur_t* btr_cur;
ibool success;
@@ -131,19 +132,18 @@ retry:
return(err);
}
-/*******************************************************************
-Removes a secondary index entry if found. */
+/***************************************************************//**
+Removes a secondary index entry if found.
+@return DB_SUCCESS, DB_FAIL, or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_ins_remove_sec_low(
/*========================*/
- /* out: DB_SUCCESS, DB_FAIL, or
- DB_OUT_OF_FILE_SPACE */
- ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether we wish optimistic or
pessimistic descent down the index tree */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry to remove */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry to remove */
{
btr_pcur_t pcur;
btr_cur_t* btr_cur;
@@ -195,16 +195,16 @@ row_undo_ins_remove_sec_low(
return(err);
}
-/*******************************************************************
+/***************************************************************//**
Removes a secondary index entry from the index if found. Tries first
-optimistic, then pessimistic descent down the tree. */
+optimistic, then pessimistic descent down the tree.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_ins_remove_sec(
/*====================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry to insert */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry to insert */
{
ulint err;
ulint n_tries = 0;
@@ -238,17 +238,17 @@ retry:
return(err);
}
-/***************************************************************
+/***********************************************************//**
Parses the row reference and other info in a fresh insert undo record. */
static
void
row_undo_ins_parse_undo_rec(
/*========================*/
- undo_node_t* node) /* in/out: row undo node */
+ undo_node_t* node) /*!< in/out: row undo node */
{
dict_index_t* clust_index;
byte* ptr;
- dulint undo_no;
+ undo_no_t undo_no;
dulint table_id;
ulint type;
ulint dummy;
@@ -287,18 +287,18 @@ row_undo_ins_parse_undo_rec(
}
}
-/***************************************************************
+/***********************************************************//**
Undoes a fresh insert of a row to a table. A fresh insert means that
the same clustered index unique key did not have any record, even delete
marked, at the time of the insert. InnoDB is eager in a rollback:
if it figures out that an index record will be removed in the purge
-anyway, it will remove it in the rollback. */
+anyway, it will remove it in the rollback.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN
ulint
row_undo_ins(
/*=========*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node) /* in: row undo node */
+ undo_node_t* node) /*!< in: row undo node */
{
ut_ad(node);
ut_ad(node->state == UNDO_NODE_INSERT);
diff --git a/storage/xtradb/row/row0umod.c b/storage/xtradb/row/row0umod.c
index 835f357fc8d..6be475d8c78 100644
--- a/storage/xtradb/row/row0umod.c
+++ b/storage/xtradb/row/row0umod.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0umod.c
Undo modify of a row
Created 2/27/1997 Heikki Tuuri
@@ -57,18 +58,17 @@ delete marked clustered index record was delete unmarked and possibly also
some of its fields were changed. Now, it is possible that the delete marked
version has become obsolete at the time the undo is started. */
-/***************************************************************
+/***********************************************************//**
Checks if also the previous version of the clustered index record was
modified or inserted by the same transaction, and its undo number is such
-that it should be undone in the same rollback. */
+that it should be undone in the same rollback.
+@return TRUE if also previous modify or insert of this row should be undone */
UNIV_INLINE
ibool
row_undo_mod_undo_also_prev_vers(
/*=============================*/
- /* out: TRUE if also previous modify or
- insert of this row should be undone */
- undo_node_t* node, /* in: row undo node */
- dulint* undo_no)/* out: the undo number */
+ undo_node_t* node, /*!< in: row undo node */
+ undo_no_t* undo_no)/*!< out: the undo number */
{
trx_undo_rec_t* undo_rec;
trx_t* trx;
@@ -88,19 +88,18 @@ row_undo_mod_undo_also_prev_vers(
return(ut_dulint_cmp(trx->roll_limit, *undo_no) <= 0);
}
-/***************************************************************
-Undoes a modify in a clustered index record. */
+/***********************************************************//**
+Undoes a modify in a clustered index record.
+@return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */
static
ulint
row_undo_mod_clust_low(
/*===================*/
- /* out: DB_SUCCESS, DB_FAIL, or error code:
- we may run out of file space */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr, /* in: mtr; must be committed before
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr, /*!< in: mtr; must be committed before
latching any further pages */
- ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
+ ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
@@ -143,18 +142,17 @@ row_undo_mod_clust_low(
return(err);
}
-/***************************************************************
-Removes a clustered index record after undo if possible. */
+/***********************************************************//**
+Removes a clustered index record after undo if possible.
+@return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */
static
ulint
row_undo_mod_remove_clust_low(
/*==========================*/
- /* out: DB_SUCCESS, DB_FAIL, or error code:
- we may run out of file space */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr __attribute__((unused)), /* in: query thread */
- mtr_t* mtr, /* in: mtr */
- ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr __attribute__((unused)), /*!< in: query thread */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
@@ -206,24 +204,23 @@ row_undo_mod_remove_clust_low(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Undoes a modify in a clustered index record. Sets also the node state for the
-next round of undo. */
+next round of undo.
+@return DB_SUCCESS or error code: we may run out of file space */
static
ulint
row_undo_mod_clust(
/*===============*/
- /* out: DB_SUCCESS or error code: we may run
- out of file space */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
btr_pcur_t* pcur;
mtr_t mtr;
ulint err;
ibool success;
ibool more_vers;
- dulint new_undo_no;
+ undo_no_t new_undo_no;
ut_ad(node && thr);
@@ -296,19 +293,18 @@ row_undo_mod_clust(
return(err);
}
-/***************************************************************
-Delete marks or removes a secondary index entry if found. */
+/***********************************************************//**
+Delete marks or removes a secondary index entry if found.
+@return DB_SUCCESS, DB_FAIL, or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_del_mark_or_remove_sec_low(
/*====================================*/
- /* out: DB_SUCCESS, DB_FAIL, or
- DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry */
- ulint mode) /* in: latch mode BTR_MODIFY_LEAF or
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry */
+ ulint mode) /*!< in: latch mode BTR_MODIFY_LEAF or
BTR_MODIFY_TREE */
{
ibool found;
@@ -396,23 +392,23 @@ row_undo_mod_del_mark_or_remove_sec_low(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Delete marks or removes a secondary index entry if found.
NOTE that if we updated the fields of a delete-marked secondary index record
so that alphabetically they stayed the same, e.g., 'abc' -> 'aBc', we cannot
return to the original values because we do not know them. But this should
not cause problems because in row0sel.c, in queries we always retrieve the
clustered index record or an earlier version of it, if the secondary index
-record through which we do the search is delete-marked. */
+record through which we do the search is delete-marked.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_del_mark_or_remove_sec(
/*================================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry */
{
ulint err;
@@ -428,22 +424,21 @@ row_undo_mod_del_mark_or_remove_sec(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Delete unmarks a secondary index entry which must be found. It might not be
delete-marked at the moment, but it does not harm to unmark it anyway. We also
need to update the fields of the secondary index record if we updated its
-fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. */
+fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'.
+@return DB_FAIL or DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_del_unmark_sec_and_undo_update(
/*========================================*/
- /* out: DB_FAIL or DB_SUCCESS or
- DB_OUT_OF_FILE_SPACE */
- ulint mode, /* in: search mode: BTR_MODIFY_LEAF or
+ ulint mode, /*!< in: search mode: BTR_MODIFY_LEAF or
BTR_MODIFY_TREE */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry */
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry */
{
mem_heap_t* heap;
btr_pcur_t pcur;
@@ -523,15 +518,15 @@ row_undo_mod_del_unmark_sec_and_undo_update(
return(err);
}
-/***************************************************************
-Undoes a modify in secondary indexes when undo record type is UPD_DEL. */
+/***********************************************************//**
+Undoes a modify in secondary indexes when undo record type is UPD_DEL.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_upd_del_sec(
/*=====================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -576,15 +571,15 @@ row_undo_mod_upd_del_sec(
return(err);
}
-/***************************************************************
-Undoes a modify in secondary indexes when undo record type is DEL_MARK. */
+/***********************************************************//**
+Undoes a modify in secondary indexes when undo record type is DEL_MARK.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_del_mark_sec(
/*======================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -621,15 +616,15 @@ row_undo_mod_del_mark_sec(
return(DB_SUCCESS);
}
-/***************************************************************
-Undoes a modify in secondary indexes when undo record type is UPD_EXIST. */
+/***********************************************************//**
+Undoes a modify in secondary indexes when undo record type is UPD_EXIST.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_upd_exist_sec(
/*=======================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -707,21 +702,21 @@ row_undo_mod_upd_exist_sec(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Parses the row reference and other info in a modify undo log record. */
static
void
row_undo_mod_parse_undo_rec(
/*========================*/
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_index_t* clust_index;
byte* ptr;
- dulint undo_no;
+ undo_no_t undo_no;
dulint table_id;
- dulint trx_id;
- dulint roll_ptr;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
ulint info_bits;
ulint type;
ulint cmpl_info;
@@ -767,15 +762,15 @@ row_undo_mod_parse_undo_rec(
node->cmpl_info = cmpl_info;
}
-/***************************************************************
-Undoes a modify operation on a row of a table. */
+/***********************************************************//**
+Undoes a modify operation on a row of a table.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_undo_mod(
/*=========*/
- /* out: DB_SUCCESS or error code */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
diff --git a/storage/xtradb/row/row0undo.c b/storage/xtradb/row/row0undo.c
index d372f88e207..3d739c9689a 100644
--- a/storage/xtradb/row/row0undo.c
+++ b/storage/xtradb/row/row0undo.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0undo.c
Row undo
Created 1/8/1997 Heikki Tuuri
@@ -119,16 +120,16 @@ doing the purge. Similarly, during a rollback, a record can be removed
if the stored roll ptr in the undo log points to a trx already (being) purged,
or if the roll ptr is NULL, i.e., it was a fresh insert. */
-/************************************************************************
-Creates a row undo node to a query graph. */
+/********************************************************************//**
+Creates a row undo node to a query graph.
+@return own: undo node */
UNIV_INTERN
undo_node_t*
row_undo_node_create(
/*=================*/
- /* out, own: undo node */
- trx_t* trx, /* in: transaction */
- que_thr_t* parent, /* in: parent node, i.e., a thr node */
- mem_heap_t* heap) /* in: memory heap where created */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t* parent, /*!< in: parent node, i.e., a thr node */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
undo_node_t* undo;
@@ -149,19 +150,18 @@ row_undo_node_create(
return(undo);
}
-/***************************************************************
+/***********************************************************//**
Looks for the clustered index record when node has the row reference.
The pcur in node is used in the search. If found, stores the row to node,
and stores the position of pcur, and detaches it. The pcur must be closed
-by the caller in any case. */
+by the caller in any case.
+@return TRUE if found; NOTE the node->pcur must be closed by the
+caller, regardless of the return value */
UNIV_INTERN
ibool
row_undo_search_clust_to_pcur(
/*==========================*/
- /* out: TRUE if found; NOTE the node->pcur
- must be closed by the caller, regardless of
- the return value */
- undo_node_t* node) /* in: row undo node */
+ undo_node_t* node) /*!< in: row undo node */
{
dict_index_t* clust_index;
ibool found;
@@ -223,23 +223,22 @@ row_undo_search_clust_to_pcur(
return(ret);
}
-/***************************************************************
+/***********************************************************//**
Fetches an undo log record and does the undo for the recorded operation.
If none left, or a partial rollback completed, returns control to the
-parent node, which is always a query thread node. */
+parent node, which is always a query thread node.
+@return DB_SUCCESS if operation successfully completed, else error code */
static
ulint
row_undo(
/*=====*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
- trx_t* trx;
- dulint roll_ptr;
- ibool locked_data_dict;
+ ulint err;
+ trx_t* trx;
+ roll_ptr_t roll_ptr;
+ ibool locked_data_dict;
ut_ad(node && thr);
@@ -326,15 +325,15 @@ row_undo(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Undoes a row operation in a table. This is a high-level function used
-in SQL execution graphs. */
+in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_undo_step(
/*==========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
undo_node_t* node;
diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c
index 740f1ee593d..58dfd43ead9 100644
--- a/storage/xtradb/row/row0upd.c
+++ b/storage/xtradb/row/row0upd.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0upd.c
Update of a row
Created 12/27/1996 Heikki Tuuri
@@ -29,10 +30,12 @@ Created 12/27/1996 Heikki Tuuri
#endif
#include "dict0dict.h"
+#include "trx0undo.h"
+#include "rem0rec.h"
+#ifndef UNIV_HOTBACKUP
#include "dict0boot.h"
#include "dict0crea.h"
#include "mach0data.h"
-#include "trx0undo.h"
#include "btr0btr.h"
#include "btr0cur.h"
#include "que0que.h"
@@ -89,36 +92,36 @@ the x-latch freed? The most efficient way for performing a
searched delete is obviously to keep the x-latch for several
steps of query graph execution. */
-/***************************************************************
+/***********************************************************//**
Checks if an update vector changes some of the first ordering fields of an
index record. This is only used in foreign key checks and we can assume
-that index does not contain column prefixes. */
+that index does not contain column prefixes.
+@return TRUE if changes */
static
ibool
row_upd_changes_first_fields_binary(
/*================================*/
- /* out: TRUE if changes */
- dtuple_t* entry, /* in: old value of index entry */
- dict_index_t* index, /* in: index of entry */
- const upd_t* update, /* in: update vector for the row */
- ulint n); /* in: how many first fields to check */
+ dtuple_t* entry, /*!< in: old value of index entry */
+ dict_index_t* index, /*!< in: index of entry */
+ const upd_t* update, /*!< in: update vector for the row */
+ ulint n); /*!< in: how many first fields to check */
-/*************************************************************************
+/*********************************************************************//**
Checks if index currently is mentioned as a referenced index in a foreign
-key constraint. */
+key constraint.
+
+NOTE that since we do not hold dict_operation_lock when leaving the
+function, it may be that the referencing table has been dropped when
+we leave this function: this function is only for heuristic use!
+
+@return TRUE if referenced */
static
ibool
row_upd_index_is_referenced(
/*========================*/
- /* out: TRUE if referenced; NOTE that since
- we do not hold dict_operation_lock
- when leaving the function, it may be that
- the referencing table has been dropped when
- we leave this function: this function is only
- for heuristic use! */
- dict_index_t* index, /* in: index */
- trx_t* trx) /* in: transaction */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx) /*!< in: transaction */
{
dict_table_t* table = index->table;
dict_foreign_t* foreign;
@@ -155,23 +158,26 @@ func_exit:
return(is_referenced);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if possible foreign key constraints hold after a delete of the record
-under pcur. NOTE that this function will temporarily commit mtr and lose the
-pcur position! */
+under pcur.
+
+NOTE that this function will temporarily commit mtr and lose the
+pcur position!
+
+@return DB_SUCCESS or an error code */
static
ulint
row_upd_check_references_constraints(
/*=================================*/
- /* out: DB_SUCCESS or an error code */
- upd_node_t* node, /* in: row update node */
- btr_pcur_t* pcur, /* in: cursor positioned on a record; NOTE: the
+ upd_node_t* node, /*!< in: row update node */
+ btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
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) */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
+ 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) */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_foreign_t* foreign;
mem_heap_t* heap;
@@ -276,14 +282,14 @@ func_exit:
return(err);
}
-/*************************************************************************
-Creates an update node for a query graph. */
+/*********************************************************************//**
+Creates an update node for a query graph.
+@return own: update node */
UNIV_INTERN
upd_node_t*
upd_node_create(
/*============*/
- /* out, own: update node */
- mem_heap_t* heap) /* in: mem heap where created */
+ mem_heap_t* heap) /*!< in: mem heap where created */
{
upd_node_t* node;
@@ -313,20 +319,21 @@ upd_node_create(
return(node);
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Updates the trx id and roll ptr field in a clustered index record in database
recovery. */
UNIV_INTERN
void
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() */
- ulint pos, /* in: TRX_ID position in rec */
- dulint trx_id, /* in: transaction id */
- dulint roll_ptr)/* in: roll ptr of the undo log record */
+ 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() */
+ 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 */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
@@ -347,19 +354,20 @@ row_upd_rec_sys_fields_in_recovery(
}
}
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Sets the trx id or roll ptr field of a clustered index entry. */
UNIV_INTERN
void
row_upd_index_entry_sys_field(
/*==========================*/
- const dtuple_t* entry, /* in: index entry, where the memory buffers
+ const dtuple_t* entry, /*!< in: index entry, where the memory buffers
for sys fields are already allocated:
the function just copies the new values to
them */
- dict_index_t* index, /* in: clustered index */
- ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
- dulint val) /* in: value to write */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint type, /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */
+ dulint val) /*!< in: value to write */
{
dfield_t* dfield;
byte* field;
@@ -380,19 +388,18 @@ row_upd_index_entry_sys_field(
}
}
-/***************************************************************
+/***********************************************************//**
Returns TRUE if row update changes size of some field in index or if some
-field to be updated is stored externally in rec or update. */
+field to be updated is stored externally in rec or update.
+@return TRUE if the update changes the size of some field in index or
+the field is external in rec or update */
UNIV_INTERN
ibool
row_upd_changes_field_size_or_external(
/*===================================*/
- /* out: TRUE if the update changes the size of
- some field in index or the field is external
- in rec or update */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- const upd_t* update) /* in: update vector */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update) /*!< in: update vector */
{
const upd_field_t* upd_field;
const dfield_t* new_val;
@@ -418,7 +425,8 @@ row_upd_changes_field_size_or_external(
new_len = dict_col_get_sql_null_size(
dict_index_get_nth_col(index,
- upd_field->field_no));
+ upd_field->field_no),
+ 0);
}
old_len = rec_offs_nth_size(offsets, upd_field->field_no);
@@ -445,19 +453,20 @@ row_upd_changes_field_size_or_external(
return(FALSE);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector to the record
given. No field size changes are allowed. */
UNIV_INTERN
void
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 upd_t* update, /* in: update vector */
- page_zip_des_t* page_zip)/* in: compressed page with enough space
+ 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 upd_t* update, /*!< in: update vector */
+ page_zip_des_t* page_zip)/*!< in: compressed page with enough space
available, or NULL */
{
const upd_field_t* upd_field;
@@ -491,20 +500,21 @@ row_upd_rec_in_place(
}
}
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Writes into the redo log the values of trx id and roll ptr and enough info
-to determine their positions within a clustered index record. */
+to determine their positions within a clustered index record.
+@return new pointer to mlog */
UNIV_INTERN
byte*
row_upd_write_sys_vals_to_log(
/*==========================*/
- /* out: new pointer to mlog */
- dict_index_t* index, /* in: clustered index */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr,/* in: roll ptr of the undo log record */
- byte* log_ptr,/* pointer to a buffer of size > 20 opened
+ dict_index_t* index, /*!< in: clustered index */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr,/*!< in: roll ptr of the undo log record */
+ byte* log_ptr,/*!< pointer to a buffer of size > 20 opened
in mlog */
- mtr_t* mtr __attribute__((unused))) /* in: mtr */
+ mtr_t* mtr __attribute__((unused))) /*!< in: mtr */
{
ut_ad(dict_index_is_clust(index));
ut_ad(mtr);
@@ -520,19 +530,20 @@ row_upd_write_sys_vals_to_log(
return(log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Parses the log data of system field values. */
+/*********************************************************************//**
+Parses the log data of system field values.
+@return log data end or NULL */
UNIV_INTERN
byte*
row_upd_parse_sys_vals(
/*===================*/
- /* out: log data end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint* pos, /* out: TRX_ID position in record */
- dulint* trx_id, /* out: trx id */
- dulint* roll_ptr)/* out: roll ptr */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint* pos, /*!< out: TRX_ID position in record */
+ trx_id_t* trx_id, /*!< out: trx id */
+ roll_ptr_t* roll_ptr)/*!< out: roll ptr */
{
ptr = mach_parse_compressed(ptr, end_ptr, pos);
@@ -554,18 +565,19 @@ row_upd_parse_sys_vals(
return(ptr);
}
-/***************************************************************
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
Writes to the redo log the new values of the fields occurring in the index. */
UNIV_INTERN
void
row_upd_index_write_log(
/*====================*/
- const upd_t* update, /* in: update vector */
- byte* log_ptr,/* in: pointer to mlog buffer: must
+ const upd_t* update, /*!< in: update vector */
+ byte* log_ptr,/*!< in: pointer to mlog buffer: must
contain at least MLOG_BUF_MARGIN bytes
of free space; the buffer is closed
within this function */
- mtr_t* mtr) /* in: mtr into whose log to write */
+ mtr_t* mtr) /*!< in: mtr into whose log to write */
{
const upd_field_t* upd_field;
const dfield_t* new_val;
@@ -624,19 +636,20 @@ row_upd_index_write_log(
mlog_close(mtr, log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Parses the log data written by row_upd_index_write_log. */
+/*********************************************************************//**
+Parses the log data written by row_upd_index_write_log.
+@return log data end or NULL */
UNIV_INTERN
byte*
row_upd_index_parse(
/*================*/
- /* out: log data end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- mem_heap_t* heap, /* in: memory heap where update vector is
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ mem_heap_t* heap, /*!< in: memory heap where update vector is
built */
- upd_t** update_out)/* out: update vector */
+ upd_t** update_out)/*!< out: update vector */
{
upd_t* update;
upd_field_t* upd_field;
@@ -704,21 +717,21 @@ row_upd_index_parse(
return(ptr);
}
-/*******************************************************************
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Builds an update vector from those fields which in a secondary index entry
differ from a record that has the equal ordering fields. NOTE: we compare
-the fields as binary strings! */
+the fields as binary strings!
+@return own: update vector of differing fields */
UNIV_INTERN
upd_t*
row_upd_build_sec_rec_difference_binary(
/*====================================*/
- /* out, own: update vector of differing
- fields */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: entry to insert */
- const rec_t* rec, /* in: secondary index record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap) /* in: memory heap from which allocated */
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ const rec_t* rec, /*!< in: secondary index record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
upd_field_t* upd_field;
const dfield_t* dfield;
@@ -774,21 +787,21 @@ row_upd_build_sec_rec_difference_binary(
return(update);
}
-/*******************************************************************
+/***************************************************************//**
Builds an update vector from those fields, excluding the roll ptr and
trx id fields, which in an index entry differ from a record that has
-the equal ordering fields. NOTE: we compare the fields as binary strings! */
+the equal ordering fields. NOTE: we compare the fields as binary strings!
+@return own: update vector of differing fields, excluding roll ptr and
+trx id */
UNIV_INTERN
upd_t*
row_upd_build_difference_binary(
/*============================*/
- /* out, own: update vector of differing
- fields, excluding roll ptr and trx id */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* entry, /* in: entry to insert */
- const rec_t* rec, /* in: clustered index record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap) /* in: memory heap from which allocated */
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ const rec_t* rec, /*!< in: clustered index record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
upd_field_t* upd_field;
const dfield_t* dfield;
@@ -851,25 +864,25 @@ skip_compare:
return(update);
}
-/***************************************************************
+/***********************************************************//**
Fetch a prefix of an externally stored column. This is similar
to row_ext_lookup(), but the row_ext_t holds the old values
-of the column and must not be poisoned with the new values. */
+of the column and must not be poisoned with the new values.
+@return BLOB prefix */
static
byte*
row_upd_ext_fetch(
/*==============*/
- /* out: BLOB prefix */
- const byte* data, /* in: 'internally' stored part of the
+ const byte* data, /*!< in: 'internally' stored part of the
field containing also the reference to
the external part */
- ulint local_len, /* in: length of data, in bytes */
- ulint zip_size, /* in: nonzero=compressed BLOB
+ ulint local_len, /*!< in: length of data, in bytes */
+ ulint zip_size, /*!< in: nonzero=compressed BLOB
page size, zero for uncompressed
BLOBs */
- ulint* len, /* in: length of prefix to fetch;
+ ulint* len, /*!< in: length of prefix to fetch;
out: fetched length of the prefix */
- mem_heap_t* heap) /* in: heap where to allocate */
+ mem_heap_t* heap) /*!< in: heap where to allocate */
{
byte* buf = mem_heap_alloc(heap, *len);
@@ -882,21 +895,21 @@ row_upd_ext_fetch(
return(buf);
}
-/***************************************************************
+/***********************************************************//**
Replaces the new column value stored in the update vector in
the given index entry field. */
static
void
row_upd_index_replace_new_col_val(
/*==============================*/
- dfield_t* dfield, /* in/out: data field
+ dfield_t* dfield, /*!< in/out: data field
of the index entry */
- const dict_field_t* field, /* in: index field */
- const dict_col_t* col, /* in: field->col */
- const upd_field_t* uf, /* in: update field */
- mem_heap_t* heap, /* in: memory heap for allocating
+ const dict_field_t* field, /*!< in: index field */
+ const dict_col_t* col, /*!< in: field->col */
+ const upd_field_t* uf, /*!< in: update field */
+ mem_heap_t* heap, /*!< in: memory heap for allocating
and copying the new value */
- ulint zip_size)/* in: compressed page
+ ulint zip_size)/*!< in: compressed page
size of the table, or 0 */
{
ulint len;
@@ -975,27 +988,27 @@ row_upd_index_replace_new_col_val(
}
}
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
UNIV_INTERN
void
row_upd_index_replace_new_col_vals_index_pos(
/*=========================================*/
- dtuple_t* entry, /* in/out: index entry where replaced;
+ 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
+ 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 index so
+ const upd_t* update, /*!< in: an update vector built for the index so
that the field number in an upd_field is the
index position */
ibool order_only,
- /* in: if TRUE, limit the replacement to
+ /*!< in: if TRUE, limit the replacement to
ordering fields of index; note that this
does not work for non-clustered indexes. */
- mem_heap_t* heap) /* in: memory heap for allocating and
+ mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
{
ulint i;
@@ -1029,23 +1042,23 @@ row_upd_index_replace_new_col_vals_index_pos(
}
}
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
UNIV_INTERN
void
row_upd_index_replace_new_col_vals(
/*===============================*/
- dtuple_t* entry, /* in/out: index entry where replaced;
+ 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
+ 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
+ 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
+ mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
{
ulint i;
@@ -1074,23 +1087,23 @@ row_upd_index_replace_new_col_vals(
}
}
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector. */
UNIV_INTERN
void
row_upd_replace(
/*============*/
- dtuple_t* row, /* in/out: row where replaced,
+ dtuple_t* row, /*!< in/out: row where replaced,
indexed by col_no;
the clustered index record must be
covered by a lock or a page latch to
prevent deletion (rollback or purge) */
- row_ext_t** ext, /* out, own: NULL, or externally
+ row_ext_t** ext, /*!< out, own: NULL, or externally
stored column prefixes */
- const dict_index_t* index, /* in: clustered index */
- const upd_t* update, /* in: an update vector built for the
+ const dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: an update vector built for the
clustered index */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ulint col_no;
ulint i;
@@ -1157,25 +1170,23 @@ row_upd_replace(
}
}
-/***************************************************************
+/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
+
This function is fast if the update vector is short or the number of ordering
fields in the index is small. Otherwise, this can be quadratic.
-NOTE: we compare the fields as binary strings! */
+NOTE: we compare the fields as binary strings!
+@return TRUE if update vector changes an ordering field in the index record */
UNIV_INTERN
ibool
row_upd_changes_ord_field_binary(
/*=============================*/
- /* out: TRUE if update vector changes
- an ordering field in the index record;
- NOTE: the fields are compared as binary
- strings */
- const dtuple_t* row, /* in: old value of row, or NULL if the
+ const dtuple_t* row, /*!< in: old value of row, or NULL if the
row and the data values in update are not
known when this function is called, e.g., at
compile time */
- dict_index_t* index, /* in: index of the record */
- const upd_t* update) /* in: update vector for the row; NOTE: the
+ dict_index_t* index, /*!< in: index of the record */
+ const upd_t* update) /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
{
@@ -1228,18 +1239,17 @@ row_upd_changes_ord_field_binary(
return(FALSE);
}
-/***************************************************************
+/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
-NOTE: we compare the fields as binary strings! */
+NOTE: we compare the fields as binary strings!
+@return TRUE if update vector may change an ordering field in an index
+record */
UNIV_INTERN
ibool
row_upd_changes_some_index_ord_field_binary(
/*========================================*/
- /* out: TRUE if update vector
- may change an ordering field
- in an index record */
- const dict_table_t* table, /* in: table */
- const upd_t* update) /* in: update vector for the row */
+ const dict_table_t* table, /*!< in: table */
+ const upd_t* update) /*!< in: update vector for the row */
{
upd_field_t* upd_field;
dict_index_t* index;
@@ -1262,19 +1272,19 @@ row_upd_changes_some_index_ord_field_binary(
return(FALSE);
}
-/***************************************************************
+/***********************************************************//**
Checks if an update vector changes some of the first ordering fields of an
index record. This is only used in foreign key checks and we can assume
-that index does not contain column prefixes. */
+that index does not contain column prefixes.
+@return TRUE if changes */
static
ibool
row_upd_changes_first_fields_binary(
/*================================*/
- /* out: TRUE if changes */
- dtuple_t* entry, /* in: index entry */
- dict_index_t* index, /* in: index of entry */
- const upd_t* update, /* in: update vector for the row */
- ulint n) /* in: how many first fields to check */
+ dtuple_t* entry, /*!< in: index entry */
+ dict_index_t* index, /*!< in: index of entry */
+ const upd_t* update, /*!< in: update vector for the row */
+ ulint n) /*!< in: how many first fields to check */
{
ulint n_upd_fields;
ulint i, j;
@@ -1316,15 +1326,15 @@ row_upd_changes_first_fields_binary(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Copies the column values from a record. */
UNIV_INLINE
void
row_upd_copy_columns(
/*=================*/
- rec_t* rec, /* in: record in a clustered index */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- sym_node_t* column) /* in: first column in a column list, or
+ rec_t* rec, /*!< in: record in a clustered index */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ sym_node_t* column) /*!< in: first column in a column list, or
NULL */
{
byte* data;
@@ -1343,14 +1353,14 @@ row_upd_copy_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the new values for fields to update. Note that row_upd_copy_columns
must have been called first. */
UNIV_INLINE
void
row_upd_eval_new_vals(
/*==================*/
- upd_t* update) /* in/out: update vector */
+ upd_t* update) /*!< in/out: update vector */
{
que_node_t* exp;
upd_field_t* upd_field;
@@ -1370,13 +1380,13 @@ row_upd_eval_new_vals(
}
}
-/***************************************************************
+/***********************************************************//**
Stores to the heap the row on which the node->pcur is positioned. */
static
void
row_upd_store_row(
/*==============*/
- upd_node_t* node) /* in: row update node */
+ upd_node_t* node) /*!< in: row update node */
{
dict_index_t* clust_index;
rec_t* rec;
@@ -1413,16 +1423,16 @@ row_upd_store_row(
}
}
-/***************************************************************
-Updates a secondary index entry of a row. */
+/***********************************************************//**
+Updates a secondary index entry of a row.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_upd_sec_index_entry(
/*====================*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- que_thr_t* thr) /* in: query thread */
+ upd_node_t* node, /*!< in: row update node */
+ que_thr_t* thr) /*!< in: query thread */
{
ibool check_ref;
ibool found;
@@ -1517,17 +1527,17 @@ func_exit:
return(err);
}
-/***************************************************************
+/***********************************************************//**
Updates the secondary index record if it is changed in the row update or
-deletes it if this is a delete. */
+deletes it if this is a delete.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
UNIV_INLINE
ulint
row_upd_sec_step(
/*=============*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- que_thr_t* thr) /* in: query thread */
+ upd_node_t* node, /*!< in: row update node */
+ que_thr_t* thr) /*!< in: query thread */
{
ut_ad((node->state == UPD_NODE_UPDATE_ALL_SEC)
|| (node->state == UPD_NODE_UPDATE_SOME_SEC));
@@ -1542,23 +1552,23 @@ row_upd_sec_step(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Marks the clustered index record deleted and inserts the updated version
of the record to the index. This function should be used when the ordering
fields of the clustered index record change. This should be quite rare in
-database applications. */
+database applications.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_upd_clust_rec_by_insert(
/*========================*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- dict_index_t* index, /* in: clustered index of the record */
- que_thr_t* thr, /* in: query thread */
- ibool check_ref,/* in: TRUE if index may be referenced in
+ upd_node_t* node, /*!< in: row update node */
+ dict_index_t* index, /*!< in: clustered index of the record */
+ que_thr_t* thr, /*!< in: query thread */
+ ibool check_ref,/*!< in: TRUE if index may be referenced in
a foreign key constraint */
- mtr_t* mtr) /* in: mtr; gets committed here */
+ mtr_t* mtr) /*!< in: mtr; gets committed here */
{
mem_heap_t* heap = NULL;
btr_pcur_t* pcur;
@@ -1651,19 +1661,19 @@ row_upd_clust_rec_by_insert(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Updates a clustered index record of a row when the ordering fields do
-not change. */
+not change.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_upd_clust_rec(
/*==============*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- dict_index_t* index, /* in: clustered index */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; gets committed here */
+ upd_node_t* node, /*!< in: row update node */
+ dict_index_t* index, /*!< in: clustered index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; gets committed here */
{
mem_heap_t* heap = NULL;
big_rec_t* big_rec = NULL;
@@ -1754,22 +1764,21 @@ row_upd_clust_rec(
return(err);
}
-/***************************************************************
-Delete marks a clustered index record. */
+/***********************************************************//**
+Delete marks a clustered index record.
+@return DB_SUCCESS if operation successfully completed, else error code */
static
ulint
row_upd_del_mark_clust_rec(
/*=======================*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code */
- upd_node_t* node, /* in: row update node */
- dict_index_t* index, /* in: clustered index */
- ulint* offsets,/* in/out: rec_get_offsets() for the
+ upd_node_t* node, /*!< in: row update node */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint* offsets,/*!< in/out: rec_get_offsets() for the
record under the cursor */
- que_thr_t* thr, /* in: query thread */
- ibool check_ref,/* in: TRUE if index may be referenced in
+ que_thr_t* thr, /*!< in: query thread */
+ ibool check_ref,/*!< in: TRUE if index may be referenced in
a foreign key constraint */
- mtr_t* mtr) /* in: mtr; gets committed here */
+ mtr_t* mtr) /*!< in: mtr; gets committed here */
{
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
@@ -1806,17 +1815,16 @@ row_upd_del_mark_clust_rec(
return(err);
}
-/***************************************************************
-Updates the clustered index record. */
+/***********************************************************//**
+Updates the clustered index record.
+@return DB_SUCCESS if operation successfully completed, DB_LOCK_WAIT
+in case of a lock wait, else error code */
static
ulint
row_upd_clust_step(
/*===============*/
- /* out: DB_SUCCESS if operation successfully
- completed, DB_LOCK_WAIT in case of a lock wait,
- else error code */
- upd_node_t* node, /* in: row update node */
- que_thr_t* thr) /* in: query thread */
+ upd_node_t* node, /*!< in: row update node */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_index_t* index;
btr_pcur_t* pcur;
@@ -1976,18 +1984,18 @@ exit_func:
return(err);
}
-/***************************************************************
+/***********************************************************//**
Updates the affected index records of a row. When the control is transferred
to this node, we assume that we have a persistent cursor which was on a
-record, and the position of the cursor is stored in the cursor. */
+record, and the position of the cursor is stored in the cursor.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_upd(
/*====*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- que_thr_t* thr) /* in: query thread */
+ upd_node_t* node, /*!< in: row update node */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err = DB_SUCCESS;
@@ -2052,15 +2060,15 @@ function_exit:
return(err);
}
-/***************************************************************
+/***********************************************************//**
Updates a row in a table. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_upd_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
upd_node_t* node;
sel_node_t* sel_node;
@@ -2166,3 +2174,4 @@ error_handling:
return(thr);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/row/row0vers.c b/storage/xtradb/row/row0vers.c
index 3abba6d6fb8..a4fbb5289aa 100644
--- a/storage/xtradb/row/row0vers.c
+++ b/storage/xtradb/row/row0vers.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0vers.c
Row versions
Created 2/6/1997 Heikki Tuuri
@@ -45,26 +46,24 @@ Created 2/6/1997 Heikki Tuuri
#include "read0read.h"
#include "lock0lock.h"
-/*********************************************************************
+/*****************************************************************//**
Finds out if an active transaction has inserted or modified a secondary
index record. NOTE: the kernel mutex is temporarily released in this
-function! */
+function!
+@return NULL if committed, else the active transaction */
UNIV_INTERN
trx_t*
row_vers_impl_x_locked_off_kernel(
/*==============================*/
- /* out: NULL if committed, else the active
- transaction; NOTE that the kernel mutex is
- temporarily released! */
- const rec_t* rec, /* in: record in a secondary index */
- dict_index_t* index, /* in: the secondary index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: record in a secondary index */
+ dict_index_t* index, /*!< in: the secondary index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
dict_index_t* clust_index;
rec_t* clust_rec;
ulint* clust_offsets;
rec_t* version;
- dulint trx_id;
+ trx_id_t trx_id;
mem_heap_t* heap;
mem_heap_t* heap2;
dtuple_t* row;
@@ -157,7 +156,7 @@ row_vers_impl_x_locked_off_kernel(
rec_t* prev_version;
ulint vers_del;
row_ext_t* ext;
- dulint prev_trx_id;
+ trx_id_t prev_trx_id;
mutex_exit(&kernel_mutex);
@@ -298,17 +297,18 @@ exit_func:
return(trx);
}
-/*********************************************************************
+/*****************************************************************//**
Finds out if we must preserve a delete marked earlier version of a clustered
-index record, because it is >= the purge view. */
+index record, because it is >= the purge view.
+@return TRUE if earlier version should be preserved */
UNIV_INTERN
ibool
row_vers_must_preserve_del_marked(
/*==============================*/
- /* out: TRUE if earlier version should be preserved */
- dulint trx_id, /* in: transaction id in the version */
- mtr_t* mtr) /* in: mtr holding the latch on the clustered index
- record; it will also hold the latch on purge_view */
+ trx_id_t trx_id, /*!< in: transaction id in the version */
+ mtr_t* mtr) /*!< in: mtr holding the latch on the
+ clustered index record; it will also
+ hold the latch on purge_view */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
@@ -327,26 +327,26 @@ row_vers_must_preserve_del_marked(
return(FALSE);
}
-/*********************************************************************
+/*****************************************************************//**
Finds out if a version of the record, where the version >= the current
purge view, should have ientry as its secondary index entry. We check
if there is any not delete marked version of the record where the trx
id >= purge view, and the secondary index entry and ientry are identified in
-the alphabetical ordering; exactly in this case we return TRUE. */
+the alphabetical ordering; exactly in this case we return TRUE.
+@return TRUE if earlier version should have */
UNIV_INTERN
ibool
row_vers_old_has_index_entry(
/*=========================*/
- /* out: TRUE if earlier version should have */
- ibool also_curr,/* in: TRUE if also rec is included in the
+ ibool also_curr,/*!< in: TRUE if also rec is included in the
versions to search; otherwise only versions
prior to it are searched */
- const rec_t* rec, /* in: record in the clustered index; the
+ const rec_t* rec, /*!< in: record in the clustered index; the
caller must have a latch on the page */
- mtr_t* mtr, /* in: mtr holding the latch on rec; it will
+ 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 secondary index */
- const dtuple_t* ientry) /* in: the secondary index entry */
+ dict_index_t* index, /*!< in: the secondary index */
+ const dtuple_t* ientry) /*!< in: the secondary index entry */
{
const rec_t* version;
rec_t* prev_version;
@@ -469,37 +469,37 @@ row_vers_old_has_index_entry(
}
}
-/*********************************************************************
+/*****************************************************************//**
Constructs the version of a clustered index record which a consistent
read should see. We assume that the trx id stored in rec is such that
-the consistent read should not see rec in its present version. */
+the consistent read should not see rec in its present version.
+@return DB_SUCCESS or DB_MISSING_HISTORY */
UNIV_INTERN
ulint
row_vers_build_for_consistent_read(
/*===============================*/
- /* out: DB_SUCCESS or DB_MISSING_HISTORY */
- const rec_t* rec, /* in: record in a clustered index; the
+ const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
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
+ 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_get_offsets(rec, index) */
- read_view_t* view, /* in: the consistent read view */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ read_view_t* view, /*!< in: the consistent read view */
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ mem_heap_t* in_heap,/*!< in: memory heap from which the memory for
*old_vers is allocated; memory for possible
intermediate versions is allocated and freed
locally within the function */
- rec_t** old_vers)/* out, own: old version, or NULL if the
+ rec_t** old_vers)/*!< out, own: old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
{
const rec_t* version;
rec_t* prev_version;
- dulint trx_id;
+ trx_id_t trx_id;
mem_heap_t* heap = NULL;
byte* buf;
ulint err;
@@ -523,8 +523,8 @@ row_vers_build_for_consistent_read(
for (;;) {
mem_heap_t* heap2 = heap;
trx_undo_rec_t* undo_rec;
- dulint roll_ptr;
- dulint undo_no;
+ roll_ptr_t roll_ptr;
+ undo_no_t undo_no;
heap = mem_heap_create(1024);
/* If we have high-granularity consistent read view and
@@ -602,29 +602,29 @@ row_vers_build_for_consistent_read(
return(err);
}
-/*********************************************************************
+/*****************************************************************//**
Constructs the last committed version of a clustered index record,
-which should be seen by a semi-consistent read. */
+which should be seen by a semi-consistent read.
+@return DB_SUCCESS or DB_MISSING_HISTORY */
UNIV_INTERN
ulint
row_vers_build_for_semi_consistent_read(
/*====================================*/
- /* out: DB_SUCCESS or DB_MISSING_HISTORY */
- const rec_t* rec, /* in: record in a clustered index; the
+ const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
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
+ 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_get_offsets(rec, index) */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ mem_heap_t* in_heap,/*!< in: memory heap from which the memory for
*old_vers is allocated; memory for possible
intermediate versions is allocated and freed
locally within the function */
- const rec_t** old_vers)/* out: rec, old version, or NULL if the
+ const rec_t** old_vers)/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
{
@@ -632,7 +632,7 @@ row_vers_build_for_semi_consistent_read(
mem_heap_t* heap = NULL;
byte* buf;
ulint err;
- dulint rec_trx_id = ut_dulint_zero;
+ trx_id_t rec_trx_id = ut_dulint_zero;
ut_ad(dict_index_is_clust(index));
ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
@@ -655,7 +655,7 @@ row_vers_build_for_semi_consistent_read(
trx_t* version_trx;
mem_heap_t* heap2;
rec_t* prev_version;
- dulint version_trx_id;
+ trx_id_t version_trx_id;
version_trx_id = row_get_rec_trx_id(version, index, *offsets);
if (rec == version) {
diff --git a/storage/xtradb/scripts/install_innodb_plugins.sql b/storage/xtradb/scripts/install_innodb_plugins.sql
index b2e5e3f6de0..5a555a652f7 100644
--- a/storage/xtradb/scripts/install_innodb_plugins.sql
+++ b/storage/xtradb/scripts/install_innodb_plugins.sql
@@ -14,3 +14,4 @@ INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_INDEX SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_rseg SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_table_stats SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_index_stats SONAME 'ha_innodb.so';
+INSTALL PLUGIN xtradb_admin_command SONAME 'ha_innodb.so';
diff --git a/storage/xtradb/scripts/install_innodb_plugins_win.sql b/storage/xtradb/scripts/install_innodb_plugins_win.sql
index 8c94b4e240d..7cda3335694 100644
--- a/storage/xtradb/scripts/install_innodb_plugins_win.sql
+++ b/storage/xtradb/scripts/install_innodb_plugins_win.sql
@@ -7,3 +7,11 @@ INSTALL PLUGIN innodb_cmp SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmp_reset SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmpmem SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmpmem_reset SONAME 'ha_innodb.dll';
+INSTALL PLUGIN XTRADB_ENHANCEMENTS SONAME 'ha_innodb.dll';
+INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES SONAME 'ha_innodb.dll';
+INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_BLOB SONAME 'ha_innodb.dll';
+INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_INDEX SONAME 'ha_innodb.dll';
+INSTALL PLUGIN innodb_rseg SONAME 'ha_innodb.dll';
+INSTALL PLUGIN innodb_table_stats SONAME 'ha_innodb.dll';
+INSTALL PLUGIN innodb_index_stats SONAME 'ha_innodb.dll';
+INSTALL PLUGIN xtradb_admin_command SONAME 'ha_innodb.dll';
diff --git a/storage/xtradb/srv/srv0que.c b/storage/xtradb/srv/srv0que.c
index 344aaed8775..fc50a86a55c 100644
--- a/storage/xtradb/srv/srv0que.c
+++ b/storage/xtradb/srv/srv0que.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file srv/srv0que.c
Server query execution
Created 6/5/1996 Heikki Tuuri
@@ -30,72 +31,14 @@ Created 6/5/1996 Heikki Tuuri
#include "usr0sess.h"
#include "que0que.h"
-/**************************************************************************
-Checks if there is work to do in the server task queue. If there is, the
-thread starts processing a task. Before leaving, it again checks the task
-queue and picks a new task if any exists. This is called by a SRV_WORKER
-thread. */
-UNIV_INTERN
-void
-srv_que_task_queue_check(void)
-/*==========================*/
-{
- que_thr_t* thr;
-
- for (;;) {
- mutex_enter(&kernel_mutex);
-
- thr = UT_LIST_GET_FIRST(srv_sys->tasks);
-
- if (thr == NULL) {
- mutex_exit(&kernel_mutex);
-
- return;
- }
-
- UT_LIST_REMOVE(queue, srv_sys->tasks, thr);
-
- mutex_exit(&kernel_mutex);
-
- que_run_threads(thr);
- }
-}
-
-/**************************************************************************
-Performs round-robin on the server tasks. This is called by a SRV_WORKER
-thread every second or so. */
-UNIV_INTERN
-que_thr_t*
-srv_que_round_robin(
-/*================*/
- /* out: the new (may be == thr) query thread
- to run */
- que_thr_t* thr) /* in: query thread */
-{
- que_thr_t* new_thr;
-
- ut_ad(thr);
- ut_ad(thr->state == QUE_THR_RUNNING);
-
- mutex_enter(&kernel_mutex);
-
- UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
-
- new_thr = UT_LIST_GET_FIRST(srv_sys->tasks);
-
- mutex_exit(&kernel_mutex);
-
- return(new_thr);
-}
-
-/**************************************************************************
+/**********************************************************************//**
Enqueues a task to server task queue and releases a worker thread, if there
is a suspended one. */
UNIV_INTERN
void
srv_que_task_enqueue_low(
/*=====================*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ut_ad(thr);
ut_ad(mutex_own(&kernel_mutex));
@@ -104,23 +47,3 @@ srv_que_task_enqueue_low(
srv_release_threads(SRV_WORKER, 1);
}
-
-/**************************************************************************
-Enqueues a task to server task queue and releases a worker thread, if there
-is a suspended one. */
-UNIV_INTERN
-void
-srv_que_task_enqueue(
-/*=================*/
- que_thr_t* thr) /* in: query thread */
-{
- ut_ad(thr);
-
- ut_a(0); /* Under MySQL this is never called */
-
- mutex_enter(&kernel_mutex);
-
- srv_que_task_enqueue_low(thr);
-
- mutex_exit(&kernel_mutex);
-}
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index 35b80d72615..00352191c2b 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009 Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,8 +22,35 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free 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
-/******************************************************
+***********************************************************************/
+
+/**************************************************//**
+@file srv/srv0srv.c
The database server main program
NOTE: SQL Server 7 uses something which the documentation
@@ -75,6 +102,10 @@ Created 10/8/1995 Heikki Tuuri
#include "row0mysql.h"
#include "ha_prototypes.h"
#include "trx0i_s.h"
+#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+
+/* prototypes for new functions added to ha_innodb.cc */
+ibool innobase_get_slow_log();
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
affects only FOREIGN KEY definition parsing */
@@ -96,7 +127,7 @@ UNIV_INTERN ibool srv_error_monitor_active = FALSE;
UNIV_INTERN const char* srv_main_thread_op_info = "";
-/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
+/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
UNIV_INTERN const char srv_mysql50_table_name_prefix[9] = "#mysql50#";
/* Server parameters which are read from the initfile */
@@ -109,12 +140,12 @@ UNIV_INTERN char* srv_data_home = NULL;
UNIV_INTERN char* srv_arch_dir = NULL;
#endif /* UNIV_LOG_ARCHIVE */
-/* store to its own file each table created by an user; data
+/** store to its own file each table created by an user; data
dictionary tables are in the system tablespace 0 */
UNIV_INTERN my_bool srv_file_per_table;
-/* The file format to use on new *.ibd files. */
+/** The file format to use on new *.ibd files. */
UNIV_INTERN ulint srv_file_format = 0;
-/* Whether to check file format during startup a value of
+/** Whether to check file format during startup. A value of
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to
set it to the highest format we support. */
UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
@@ -122,7 +153,7 @@ UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
#if DICT_TF_FORMAT_51
# error "DICT_TF_FORMAT_51 must be 0!"
#endif
-/* Place locks to records only i.e. do not use next-key locking except
+/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
UNIV_INTERN ibool srv_locks_unsafe_for_binlog = FALSE;
@@ -134,6 +165,9 @@ UNIV_INTERN ulint* srv_data_file_sizes = NULL;
UNIV_INTERN ibool srv_extra_undoslots = FALSE;
UNIV_INTERN ibool srv_fast_recovery = FALSE;
+UNIV_INTERN ibool srv_recovery_stats = FALSE;
+
+UNIV_INTERN ulint srv_use_purge_thread = 0;
/* if TRUE, then we auto-extend the last data file */
UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;
@@ -160,6 +194,10 @@ UNIV_INTERN ulint srv_log_file_size = ULINT_MAX;
UNIV_INTERN ulint srv_log_buffer_size = ULINT_MAX;
UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1;
+/* Try to flush dirty pages so as to avoid IO bursts at
+the checkpoints. */
+UNIV_INTERN char srv_adaptive_flushing = TRUE;
+
UNIV_INTERN ulong srv_show_locks_held = 10;
UNIV_INTERN ulong srv_show_verbose_locks = 0;
@@ -180,9 +218,16 @@ UNIV_INTERN ulint srv_buf_pool_curr_size = 0;
UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
+/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
+instead. */
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
-UNIV_INTERN ulint srv_n_read_io_threads = 1;
-UNIV_INTERN ulint srv_n_write_io_threads = 1;
+UNIV_INTERN ulint srv_n_read_io_threads = ULINT_MAX;
+UNIV_INTERN ulint srv_n_write_io_threads = ULINT_MAX;
+
+/* User settable value of the number of pages that must be present
+in the buffer cache and accessed sequentially for InnoDB to trigger a
+readahead request. */
+UNIV_INTERN ulong srv_read_ahead_threshold = 56;
#ifdef UNIV_LOG_ARCHIVE
UNIV_INTERN ibool srv_log_archive_on = FALSE;
@@ -206,12 +251,15 @@ UNIV_INTERN ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
UNIV_INTERN ulint srv_max_n_open_files = 300;
+/* Number of IO operations per second the server can do */
+UNIV_INTERN ulong srv_io_capacity = 200;
+
/* The InnoDB main thread tries to keep the ratio of modified pages
in the buffer pool to all database pages in the buffer pool smaller than
the following number. But it is not guaranteed that the value stays below
that during a time of heavy update/insert activity. */
-UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 90;
+UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 75;
/* variable counts amount of data read in total (in bytes) */
UNIV_INTERN ulint srv_data_read = 0;
@@ -255,16 +303,10 @@ UNIV_INTERN ulint srv_buf_pool_wait_free = 0;
pool to the disk */
UNIV_INTERN ulint srv_buf_pool_flushed = 0;
-/* variable to count the number of buffer pool reads that led to the
+/** Number of buffer pool reads that led to the
reading of a disk page */
UNIV_INTERN ulint srv_buf_pool_reads = 0;
-/* variable to count the number of sequential read-aheads */
-UNIV_INTERN ulint srv_read_ahead_seq = 0;
-
-/* variable to count the number of random read-aheads */
-UNIV_INTERN ulint srv_read_ahead_rnd = 0;
-
/* structure to pass status variables to MySQL */
UNIV_INTERN export_struc export_vars;
@@ -303,17 +345,17 @@ UNIV_INTERN ulint srv_conc_n_waiting_threads = 0;
typedef struct srv_conc_slot_struct srv_conc_slot_t;
struct srv_conc_slot_struct{
- os_event_t event; /* event to wait */
- ibool reserved; /* TRUE if slot
+ os_event_t event; /*!< event to wait */
+ ibool reserved; /*!< TRUE if slot
reserved */
- ibool wait_ended; /* TRUE when another
+ ibool wait_ended; /*!< TRUE when another
thread has already set
the event and the
thread in this slot is
free to proceed; but
reserved may still be
TRUE at that point */
- UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue node */
+ UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /*!< queue node */
};
/* queue of threads waiting to get in */
@@ -340,6 +382,7 @@ this many index pages */
UNIV_INTERN unsigned long long srv_stats_sample_pages = 8;
UNIV_INTERN ulong srv_stats_method = 0;
UNIV_INTERN ulong srv_stats_auto_update = 1;
+UNIV_INTERN ulint srv_stats_update_need_lock = 1;
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
UNIV_INTERN ibool srv_use_checksums = TRUE;
@@ -349,18 +392,12 @@ UNIV_INTERN int srv_query_thread_priority = 0;
UNIV_INTERN ulong srv_replication_delay = 0;
-UNIV_INTERN ulong srv_io_capacity = 100;
-
-/* Returns the number of IO operations that is X percent of the capacity.
-PCT_IO(5) -> returns the number of IO operations that is 5% of the max
-where max is srv_io_capacity. */
-#define PCT_IO(pct) ((ulint) (srv_io_capacity * ((double) pct / 100.0)))
-
UNIV_INTERN long long srv_ibuf_max_size = 0;
UNIV_INTERN ulong srv_ibuf_active_contract = 0; /* 0:disable 1:enable */
UNIV_INTERN ulong srv_ibuf_accel_rate = 100;
#define PCT_IBUF_IO(pct) ((ulint) (srv_io_capacity * srv_ibuf_accel_rate * ((double) pct / 10000.0)))
+UNIV_INTERN ulint srv_checkpoint_age_target = 0;
UNIV_INTERN ulong srv_flush_neighbor_pages = 1; /* 0:disable 1:enable */
UNIV_INTERN ulong srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */
@@ -368,15 +405,15 @@ UNIV_INTERN ulong srv_read_ahead = 3; /* 1: random 2: linear 3: Both */
UNIV_INTERN ulong srv_adaptive_checkpoint = 0; /* 0: none 1: reflex 2: estimate */
UNIV_INTERN ulong srv_expand_import = 0; /* 0:disable 1:enable */
+UNIV_INTERN ulint srv_relax_table_creation = 0; /* 0:disable 1:enable */
UNIV_INTERN ulong srv_extra_rsegments = 0; /* extra rseg for users */
UNIV_INTERN ulong srv_dict_size_limit = 0;
/*-------------------------------------------*/
-UNIV_INTERN ulong srv_n_spin_wait_rounds = 20;
+UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
UNIV_INTERN ulong srv_thread_sleep_delay = 10000;
-UNIV_INTERN ulint srv_spin_wait_delay = 5;
-UNIV_INTERN ulint srv_spins_microsec = 50;
+UNIV_INTERN ulong srv_spin_wait_delay = 6;
UNIV_INTERN ibool srv_priority_boost = TRUE;
#ifdef UNIV_DEBUG
@@ -391,12 +428,11 @@ UNIV_INTERN ulint srv_n_rows_inserted = 0;
UNIV_INTERN ulint srv_n_rows_updated = 0;
UNIV_INTERN ulint srv_n_rows_deleted = 0;
UNIV_INTERN ulint srv_n_rows_read = 0;
-#ifndef UNIV_HOTBACKUP
+
static ulint srv_n_rows_inserted_old = 0;
static ulint srv_n_rows_updated_old = 0;
static ulint srv_n_rows_deleted_old = 0;
static ulint srv_n_rows_read_old = 0;
-#endif /* !UNIV_HOTBACKUP */
UNIV_INTERN ulint srv_n_lock_wait_count = 0;
UNIV_INTERN ulint srv_n_lock_wait_current_count = 0;
@@ -444,6 +480,34 @@ UNIV_INTERN FILE* srv_misc_tmpfile;
UNIV_INTERN ulint srv_main_thread_process_no = 0;
UNIV_INTERN ulint srv_main_thread_id = 0;
+/* The following count work done by srv_master_thread. */
+
+/* Iterations by the 'once per second' loop. */
+static ulint srv_main_1_second_loops = 0;
+/* Calls to sleep by the 'once per second' loop. */
+static ulint srv_main_sleeps = 0;
+/* Iterations by the 'once per 10 seconds' loop. */
+static ulint srv_main_10_second_loops = 0;
+/* Iterations of the loop bounded by the 'background_loop' label. */
+static ulint srv_main_background_loops = 0;
+/* Iterations of the loop bounded by the 'flush_loop' label. */
+static ulint srv_main_flush_loops = 0;
+/* Log writes involving flush. */
+static ulint srv_log_writes_and_flush = 0;
+
+/* This is only ever touched by the master thread. It records the
+time when the last flush of log file has happened. The master
+thread ensures that we flush the log files at least once per
+second. */
+static time_t srv_last_log_flush_time;
+
+/* The master thread performs various tasks based on the current
+state of IO activity and the level of IO utilization is past
+intervals. Following macros define thresholds for these conditions. */
+#define SRV_PEND_IO_THRESHOLD (PCT_IO(3))
+#define SRV_RECENT_IO_ACTIVITY (PCT_IO(5))
+#define SRV_PAST_IO_ACTIVITY (PCT_IO(200))
+
/*
IMPLEMENTATION OF THE SERVER MAIN PROGRAM
=========================================
@@ -578,7 +642,7 @@ future, but at the moment we plan to implement a more coarse solution,
which could be called a global priority inheritance. If a thread
has to wait for a long time, say 300 milliseconds, for a resource,
we just guess that it may be waiting for a resource owned by a background
-thread, and boost the the priority of all runnable background threads
+thread, and boost the priority of all runnable background threads
to the normal level. The background threads then themselves adjust
their fixed priority back to background after releasing all resources
they had (or, at some fixed points in their program code).
@@ -614,17 +678,17 @@ Unix.*/
/* Thread slot in the thread table */
struct srv_slot_struct{
- os_thread_id_t id; /* thread id */
- os_thread_t handle; /* thread handle */
- unsigned type:3; /* thread type: user, utility etc. */
- unsigned in_use:1; /* TRUE if this slot is in use */
- unsigned suspended:1; /* TRUE if the thread is waiting
+ os_thread_id_t id; /*!< thread id */
+ os_thread_t handle; /*!< thread handle */
+ unsigned type:3; /*!< thread type: user, utility etc. */
+ unsigned in_use:1; /*!< TRUE if this slot is in use */
+ unsigned suspended:1; /*!< TRUE if the thread is waiting
for the event of this slot */
- ib_time_t suspend_time; /* time when the thread was
+ ib_time_t suspend_time; /*!< time when the thread was
suspended */
- os_event_t event; /* event used in suspending the
+ os_event_t event; /*!< event used in suspending the
thread when it has nothing to do */
- que_thr_t* thr; /* suspended query thread (only
+ que_thr_t* thr; /*!< suspended query thread (only
used for MySQL threads) */
};
@@ -665,55 +729,31 @@ are indexed by the type of the thread. */
UNIV_INTERN ulint srv_n_threads_active[SRV_MASTER + 1];
UNIV_INTERN ulint srv_n_threads[SRV_MASTER + 1];
+/***********************************************************************
+Prints counters for work done by srv_master_thread. */
static
void
-srv_align_spins_microsec(void)
+srv_print_master_thread_info(
+/*=========================*/
+ FILE *file) /* in: output stream */
{
- ulint start_sec, end_sec;
- ulint start_usec, end_usec;
- ib_uint64_t usecs;
-
- /* change temporary */
- srv_spins_microsec = 1;
-
- if (ut_usectime(&start_sec, &start_usec)) {
- srv_spins_microsec = 50;
- goto end;
- }
-
- ut_delay(100000);
-
- if (ut_usectime(&end_sec, &end_usec)) {
- srv_spins_microsec = 50;
- goto end;
- }
-
- usecs = (end_sec - start_sec) * 1000000LL + (end_usec - start_usec);
-
- if (usecs) {
- srv_spins_microsec = 100000 / usecs;
- if (srv_spins_microsec == 0)
- srv_spins_microsec = 1;
- if (srv_spins_microsec > 50)
- srv_spins_microsec = 50;
- } else {
- srv_spins_microsec = 50;
- }
-end:
- if (srv_spins_microsec != 50)
- fprintf(stderr,
- "InnoDB: unit of spin count at ut_delay() is aligned to %lu\n",
- srv_spins_microsec);
+ fprintf(file, "srv_master_thread loops: %lu 1_second, %lu sleeps, "
+ "%lu 10_second, %lu background, %lu flush\n",
+ srv_main_1_second_loops, srv_main_sleeps,
+ srv_main_10_second_loops, srv_main_background_loops,
+ srv_main_flush_loops);
+ fprintf(file, "srv_master_thread log flush and writes: %lu\n",
+ srv_log_writes_and_flush);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the info describing an i/o thread current state. */
UNIV_INTERN
void
srv_set_io_thread_op_info(
/*======================*/
- ulint i, /* in: the 'segment' of the i/o thread */
- const char* str) /* in: constant char string describing the
+ ulint i, /*!< in: the 'segment' of the i/o thread */
+ const char* str) /*!< in: constant char string describing the
state */
{
ut_a(i < SRV_MAX_N_IO_THREADS);
@@ -721,24 +761,24 @@ srv_set_io_thread_op_info(
srv_io_thread_op_info[i] = str;
}
-/*************************************************************************
+/*********************************************************************//**
Accessor function to get pointer to n'th slot in the server thread
-table. */
+table.
+@return pointer to the slot */
static
srv_slot_t*
srv_table_get_nth_slot(
/*===================*/
- /* out: pointer to the slot */
- ulint index) /* in: index of the slot */
+ ulint index) /*!< in: index of the slot */
{
ut_a(index < OS_THREAD_MAX_N);
return(srv_sys->threads + index);
}
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
-Gets the number of threads in the system. */
+/*********************************************************************//**
+Gets the number of threads in the system.
+@return sum of srv_n_threads[] */
UNIV_INTERN
ulint
srv_get_n_threads(void)
@@ -759,16 +799,16 @@ srv_get_n_threads(void)
return(n_threads);
}
-/*************************************************************************
+/*********************************************************************//**
Reserves a slot in the thread table for the current thread. Also creates the
thread local storage struct for the current thread. NOTE! The server mutex
-has to be reserved by the caller! */
+has to be reserved by the caller!
+@return reserved slot index */
static
ulint
srv_table_reserve_slot(
/*===================*/
- /* out: reserved slot index */
- enum srv_thread_type type) /* in: type of the thread */
+ enum srv_thread_type type) /*!< in: type of the thread */
{
srv_slot_t* slot;
ulint i;
@@ -799,14 +839,14 @@ srv_table_reserve_slot(
return(i);
}
-/*************************************************************************
+/*********************************************************************//**
Suspends the calling thread to wait for the event in its thread slot.
-NOTE! The server mutex has to be reserved by the caller! */
+NOTE! The server mutex has to be reserved by the caller!
+@return event for the calling thread to wait */
static
os_event_t
srv_suspend_thread(void)
/*====================*/
- /* out: event for the calling thread to wait */
{
srv_slot_t* slot;
os_event_t event;
@@ -842,21 +882,18 @@ srv_suspend_thread(void)
return(event);
}
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Releases threads of the type given from suspension in the thread table.
-NOTE! The server mutex has to be reserved by the caller! */
+NOTE! The server mutex has to be reserved by the caller!
+@return number of threads released: this may be less than n if not
+enough threads were suspended at the moment */
UNIV_INTERN
ulint
srv_release_threads(
/*================*/
- /* out: number of threads
- released: this may be < n if
- not enough threads were
- suspended at the moment */
- enum srv_thread_type type, /* in: thread type */
- ulint n) /* in: number of threads to release */
+ enum srv_thread_type type, /*!< in: thread type */
+ ulint n) /*!< in: number of threads to release */
{
srv_slot_t* slot;
ulint i;
@@ -898,13 +935,13 @@ srv_release_threads(
return(count);
}
-/*************************************************************************
-Returns the calling thread type. */
+/*********************************************************************//**
+Returns the calling thread type.
+@return SRV_COM, ... */
UNIV_INTERN
enum srv_thread_type
srv_get_thread_type(void)
/*=====================*/
- /* out: SRV_COM, ... */
{
ulint slot_no;
srv_slot_t* slot;
@@ -926,7 +963,7 @@ srv_get_thread_type(void)
return(type);
}
-/*************************************************************************
+/*********************************************************************//**
Initializes the server. */
UNIV_INTERN
void
@@ -935,11 +972,8 @@ srv_init(void)
{
srv_conc_slot_t* conc_slot;
srv_slot_t* slot;
- dict_table_t* table;
ulint i;
- srv_align_spins_microsec();
-
srv_sys = mem_alloc(sizeof(srv_sys_t));
kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
@@ -983,30 +1017,9 @@ srv_init(void)
UT_LIST_INIT(srv_sys->tasks);
- /* create dummy table and index for old-style infimum and supremum */
- table = dict_mem_table_create("SYS_DUMMY1",
- DICT_HDR_SPACE, 1, 0);
- dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
- DATA_ENGLISH | DATA_NOT_NULL, 8);
-
- srv_sys->dummy_ind1 = dict_mem_index_create(
- "SYS_DUMMY1", "SYS_DUMMY1", DICT_HDR_SPACE, 0, 1);
- dict_index_add_col(srv_sys->dummy_ind1, table,
- dict_table_get_nth_col(table, 0), 0);
- srv_sys->dummy_ind1->table = table;
- /* create dummy table and index for new-style infimum and supremum */
- table = dict_mem_table_create("SYS_DUMMY2",
- DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
- dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
- DATA_ENGLISH | DATA_NOT_NULL, 8);
- srv_sys->dummy_ind2 = dict_mem_index_create(
- "SYS_DUMMY2", "SYS_DUMMY2", DICT_HDR_SPACE, 0, 1);
- dict_index_add_col(srv_sys->dummy_ind2, table,
- dict_table_get_nth_col(table, 0), 0);
- srv_sys->dummy_ind2->table = table;
-
- /* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
- srv_sys->dummy_ind1->cached = srv_sys->dummy_ind2->cached = TRUE;
+ /* Create dummy indexes for infimum and supremum records */
+
+ dict_ind_init();
/* Init the server concurrency restriction data structures */
@@ -1027,17 +1040,30 @@ srv_init(void)
trx_i_s_cache_init(trx_i_s_cache);
}
-/*************************************************************************
-Frees the OS fast mutex created in srv_init(). */
+/*********************************************************************//**
+Frees the data structures created in srv_init(). */
UNIV_INTERN
void
srv_free(void)
/*==========*/
{
os_fast_mutex_free(&srv_conc_mutex);
+ mem_free(srv_conc_slots);
+ srv_conc_slots = NULL;
+
+ mem_free(srv_sys->threads);
+ mem_free(srv_sys);
+ srv_sys = NULL;
+
+ mem_free(kernel_mutex_temp);
+ kernel_mutex_temp = NULL;
+ mem_free(srv_mysql_table);
+ srv_mysql_table = NULL;
+
+ trx_i_s_cache_free(trx_i_s_cache);
}
-/*************************************************************************
+/*********************************************************************//**
Initializes the synchronization primitives, memory system, and the thread
local storage. */
UNIV_INTERN
@@ -1046,6 +1072,8 @@ srv_general_init(void)
/*==================*/
{
ut_mem_init();
+ /* Reset the system variables in the recovery module. */
+ recv_sys_var_init();
os_sync_init();
sync_init();
mem_init(srv_mem_pool_size);
@@ -1057,11 +1085,11 @@ srv_general_init(void)
/* Maximum allowable purge history length. <=0 means 'infinite'. */
UNIV_INTERN ulong srv_max_purge_lag = 0;
-/*************************************************************************
+/*********************************************************************//**
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+#ifdef HAVE_ATOMIC_BUILTINS
static void
enter_innodb_with_tickets(trx_t* trx)
{
@@ -1087,12 +1115,12 @@ srv_conc_enter_innodb_timer_based(trx_t* trx)
}
retry:
if (srv_conc_n_threads < (lint) srv_thread_concurrency) {
- conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
if (conc_n_threads <= (lint) srv_thread_concurrency) {
enter_innodb_with_tickets(trx);
return;
}
- __sync_add_and_fetch(&srv_conc_n_threads, -1);
+ os_atomic_increment_lint(&srv_conc_n_threads, -1);
}
if (!has_yielded)
{
@@ -1103,7 +1131,7 @@ retry:
if (trx->has_search_latch
|| NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
- conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
enter_innodb_with_tickets(trx);
return;
}
@@ -1114,7 +1142,7 @@ retry:
trx->op_info = "";
has_slept++;
}
- conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
enter_innodb_with_tickets(trx);
return;
}
@@ -1122,7 +1150,7 @@ retry:
static void
srv_conc_exit_innodb_timer_based(trx_t* trx)
{
- __sync_add_and_fetch(&srv_conc_n_threads, -1);
+ os_atomic_increment_lint(&srv_conc_n_threads, -1);
trx->declared_to_be_inside_innodb = FALSE;
trx->n_tickets_to_enter_innodb = 0;
return;
@@ -1133,12 +1161,16 @@ UNIV_INTERN
void
srv_conc_enter_innodb(
/*==================*/
- trx_t* trx) /* in: transaction object associated with the
+ trx_t* trx) /*!< in: transaction object associated with the
thread */
{
ibool has_slept = FALSE;
srv_conc_slot_t* slot = NULL;
ulint i;
+ ib_uint64_t start_time = 0L;
+ ib_uint64_t finish_time = 0L;
+ ulint sec;
+ ulint ms;
if (trx->mysql_thd != NULL
&& thd_is_replication_slave_thread(trx->mysql_thd)) {
@@ -1159,7 +1191,7 @@ srv_conc_enter_innodb(
return;
}
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+#ifdef HAVE_ATOMIC_BUILTINS
if (srv_thread_concurrency_timer_based) {
srv_conc_enter_innodb_timer_based(trx);
return;
@@ -1215,6 +1247,7 @@ retry:
switches. */
if (SRV_THREAD_SLEEP_DELAY > 0) {
os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
+ trx->innodb_que_wait_timer += SRV_THREAD_SLEEP_DELAY;
}
trx->op_info = "";
@@ -1270,12 +1303,25 @@ retry:
/* Go to wait for the event; when a thread leaves InnoDB it will
release this thread */
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ start_time = (ib_uint64_t)sec * 1000000 + ms;
+ } else {
+ start_time = 0;
+ }
+
trx->op_info = "waiting in InnoDB queue";
os_event_wait(slot->event);
trx->op_info = "";
+ if (innobase_get_slow_log() && trx->take_stats && start_time) {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->innodb_que_wait_timer += (ulint)(finish_time - start_time);
+ }
+
os_fast_mutex_lock(&srv_conc_mutex);
srv_conc_n_waiting_threads--;
@@ -1293,14 +1339,14 @@ retry:
os_fast_mutex_unlock(&srv_conc_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
UNIV_INTERN
void
srv_conc_force_enter_innodb(
/*========================*/
- trx_t* trx) /* in: transaction object associated with the
+ trx_t* trx) /*!< in: transaction object associated with the
thread */
{
if (UNIV_LIKELY(!srv_thread_concurrency)) {
@@ -1309,9 +1355,9 @@ srv_conc_force_enter_innodb(
}
ut_ad(srv_conc_n_threads >= 0);
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+#ifdef HAVE_ATOMIC_BUILTINS
if (srv_thread_concurrency_timer_based) {
- __sync_add_and_fetch(&srv_conc_n_threads, 1);
+ os_atomic_increment_lint(&srv_conc_n_threads, 1);
trx->declared_to_be_inside_innodb = TRUE;
trx->n_tickets_to_enter_innodb = 1;
return;
@@ -1327,14 +1373,14 @@ srv_conc_force_enter_innodb(
os_fast_mutex_unlock(&srv_conc_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
This must be called when a thread exits InnoDB in a lock wait or at the
end of an SQL statement. */
UNIV_INTERN
void
srv_conc_force_exit_innodb(
/*=======================*/
- trx_t* trx) /* in: transaction object associated with the
+ trx_t* trx) /*!< in: transaction object associated with the
thread */
{
srv_conc_slot_t* slot = NULL;
@@ -1350,7 +1396,7 @@ srv_conc_force_exit_innodb(
return;
}
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+#ifdef HAVE_ATOMIC_BUILTINS
if (srv_thread_concurrency_timer_based) {
srv_conc_exit_innodb_timer_based(trx);
return;
@@ -1391,13 +1437,13 @@ srv_conc_force_exit_innodb(
}
}
-/*************************************************************************
+/*********************************************************************//**
This must be called when a thread exits InnoDB. */
UNIV_INTERN
void
srv_conc_exit_innodb(
/*=================*/
- trx_t* trx) /* in: transaction object associated with the
+ trx_t* trx) /*!< in: transaction object associated with the
thread */
{
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1416,13 +1462,13 @@ srv_conc_exit_innodb(
/*========================================================================*/
-/*************************************************************************
-Normalizes init parameter values to use units we use inside InnoDB. */
+/*********************************************************************//**
+Normalizes init parameter values to use units we use inside InnoDB.
+@return DB_SUCCESS or error code */
static
ulint
srv_normalize_init_values(void)
/*===========================*/
- /* out: DB_SUCCESS or error code */
{
ulint n;
ulint i;
@@ -1446,13 +1492,13 @@ srv_normalize_init_values(void)
return(DB_SUCCESS);
}
-/*************************************************************************
-Boots the InnoDB server. */
+/*********************************************************************//**
+Boots the InnoDB server.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
srv_boot(void)
/*==========*/
- /* out: DB_SUCCESS or error code */
{
ulint err;
@@ -1477,15 +1523,14 @@ srv_boot(void)
return(DB_SUCCESS);
}
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+/*********************************************************************//**
Reserves a slot in the thread table for the current MySQL OS thread.
-NOTE! The kernel mutex has to be reserved by the caller! */
+NOTE! The kernel mutex has to be reserved by the caller!
+@return reserved slot */
static
srv_slot_t*
srv_table_reserve_slot_for_mysql(void)
/*==================================*/
- /* out: reserved slot */
{
srv_slot_t* slot;
ulint i;
@@ -1542,9 +1587,8 @@ srv_table_reserve_slot_for_mysql(void)
return(slot);
}
-#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Puts a MySQL OS thread to wait for a lock to be released. If an error
occurs during the wait trx->error_state associated with thr is
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
@@ -1554,10 +1598,9 @@ UNIV_INTERN
void
srv_suspend_mysql_thread(
/*=====================*/
- que_thr_t* thr) /* in: query thread associated with the MySQL
+ que_thr_t* thr) /*!< in: query thread associated with the MySQL
OS thread */
{
-#ifndef UNIV_HOTBACKUP
srv_slot_t* slot;
os_event_t event;
double wait_time;
@@ -1722,25 +1765,18 @@ srv_suspend_mysql_thread(
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
}
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
-/************************************************************************
+/********************************************************************//**
Releases a MySQL OS thread waiting for a lock to be released, if the
thread is already suspended. */
UNIV_INTERN
void
srv_release_mysql_thread_if_suspended(
/*==================================*/
- que_thr_t* thr) /* in: query thread associated with the
+ que_thr_t* thr) /*!< in: query thread associated with the
MySQL OS thread */
{
-#ifndef UNIV_HOTBACKUP
srv_slot_t* slot;
ulint i;
@@ -1760,16 +1796,9 @@ srv_release_mysql_thread_if_suspended(
}
/* not found */
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
-#ifndef UNIV_HOTBACKUP
-/**********************************************************************
+/******************************************************************//**
Refreshes the values used to calculate per-second averages. */
static
void
@@ -1797,16 +1826,16 @@ srv_refresh_innodb_monitor_stats(void)
mutex_exit(&srv_innodb_monitor_mutex);
}
-/**********************************************************************
+/******************************************************************//**
Outputs to a file the output of the InnoDB Monitor. */
UNIV_INTERN
void
srv_printf_innodb_monitor(
/*======================*/
- FILE* file, /* in: output stream */
- ulint* trx_start, /* out: file position of the start of
+ FILE* file, /*!< in: output stream */
+ ulint* trx_start, /*!< out: file position of the start of
the list of active transactions */
- ulint* trx_end) /* out: file position of the end of
+ ulint* trx_end) /*!< out: file position of the end of
the list of active transactions */
{
double time_elapsed;
@@ -1843,6 +1872,11 @@ srv_printf_innodb_monitor(
(ulong)time_elapsed);
fputs("----------\n"
+ "BACKGROUND THREAD\n"
+ "----------\n", file);
+ srv_print_master_thread_info(file);
+
+ fputs("----------\n"
"SEMAPHORES\n"
"----------\n", file);
sync_print(file);
@@ -2055,11 +2089,12 @@ srv_printf_innodb_monitor(
fflush(file);
}
-/**********************************************************************
+/******************************************************************//**
Function to pass InnoDB status variables to MySQL */
UNIV_INTERN
void
srv_export_innodb_status(void)
+/*==========================*/
{
mutex_enter(&srv_innodb_monitor_mutex);
@@ -2076,14 +2111,16 @@ srv_export_innodb_status(void)
export_vars.innodb_data_writes = os_n_file_writes;
export_vars.innodb_data_written = srv_data_written;
export_vars.innodb_dict_tables= (dict_sys ? UT_LIST_GET_LEN(dict_sys->table_LRU) : 0);
- export_vars.innodb_buffer_pool_read_requests = buf_pool->n_page_gets;
+ export_vars.innodb_buffer_pool_read_requests = buf_pool->stat.n_page_gets;
export_vars.innodb_buffer_pool_write_requests
= srv_buf_pool_write_requests;
export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
- export_vars.innodb_buffer_pool_read_ahead_rnd = srv_read_ahead_rnd;
- export_vars.innodb_buffer_pool_read_ahead_seq = srv_read_ahead_seq;
+ export_vars.innodb_buffer_pool_read_ahead
+ = buf_pool->stat.n_ra_pages_read;
+ export_vars.innodb_buffer_pool_read_ahead_evicted
+ = buf_pool->stat.n_ra_pages_evicted;
export_vars.innodb_buffer_pool_pages_data
= UT_LIST_GET_LEN(buf_pool->LRU);
export_vars.innodb_buffer_pool_pages_dirty
@@ -2099,7 +2136,7 @@ srv_export_innodb_status(void)
export_vars.innodb_buffer_pool_pages_misc = buf_pool->curr_size
- UT_LIST_GET_LEN(buf_pool->LRU)
- UT_LIST_GET_LEN(buf_pool->free);
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
+#ifdef HAVE_ATOMIC_BUILTINS
export_vars.innodb_have_atomic_builtins = 1;
#else
export_vars.innodb_have_atomic_builtins = 0;
@@ -2114,9 +2151,9 @@ srv_export_innodb_status(void)
export_vars.innodb_log_writes = srv_log_writes;
export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
export_vars.innodb_dblwr_writes = srv_dblwr_writes;
- export_vars.innodb_pages_created = buf_pool->n_pages_created;
- export_vars.innodb_pages_read = buf_pool->n_pages_read;
- export_vars.innodb_pages_written = buf_pool->n_pages_written;
+ export_vars.innodb_pages_created = buf_pool->stat.n_pages_created;
+ export_vars.innodb_pages_read = buf_pool->stat.n_pages_read;
+ export_vars.innodb_pages_written = buf_pool->stat.n_pages_written;
export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
export_vars.innodb_row_lock_current_waits
= srv_n_lock_wait_current_count;
@@ -2137,16 +2174,16 @@ srv_export_innodb_status(void)
mutex_exit(&srv_innodb_monitor_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+This also prints the info output by various InnoDB monitors.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_lock_timeout_and_monitor_thread(
/*================================*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)))
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
{
srv_slot_t* slot;
@@ -2324,16 +2361,16 @@ exit_func:
OS_THREAD_DUMMY_RETURN;
}
-/*************************************************************************
+/*********************************************************************//**
A thread which prints warnings about semaphore waits which have lasted
-too long. These can be used to track bugs which cause hangs. */
+too long. These can be used to track bugs which cause hangs.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_error_monitor_thread(
/*=====================*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)))
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
{
/* number of successive fatal timeouts observed */
@@ -2376,13 +2413,16 @@ loop:
}
/* Update the statistics collected for deciding LRU
- eviction policy. */
+ eviction policy. */
buf_LRU_stat_update();
+ /* Update the statistics collected for flush rate policy. */
+ buf_flush_stat_update();
+
/* In case mutex_exit is not a memory barrier, it is
theoretically possible some threads are left waiting though
the semaphore is already released. Wake up those threads: */
-
+
sync_arr_wake_threads_if_sema_free();
if (sync_array_print_long_waits()) {
@@ -2424,7 +2464,7 @@ loop:
OS_THREAD_DUMMY_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Tells the InnoDB server that there has been activity in the database
and wakes up the master thread if it is suspended (not sleeping). Used
in the MySQL interface. Note that there is a small chance that the master
@@ -2447,7 +2487,7 @@ srv_active_wake_master_thread(void)
}
}
-/***********************************************************************
+/*******************************************************************//**
Wakes up the master thread if it is suspended or being suspended. */
UNIV_INTERN
void
@@ -2463,20 +2503,38 @@ srv_wake_master_thread(void)
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
-The master thread controlling the server. */
+/**********************************************************************
+The master thread is tasked to ensure that flush of log file happens
+once every second in the background. This is to ensure that not more
+than one second of trxs are lost in case of crash when
+innodb_flush_logs_at_trx_commit != 1 */
+static
+void
+srv_sync_log_buffer_in_background(void)
+/*===================================*/
+{
+ time_t current_time = time(NULL);
+
+ srv_main_thread_op_info = "flushing log";
+ if (difftime(current_time, srv_last_log_flush_time) >= 1) {
+ log_buffer_sync_in_background(TRUE);
+ srv_last_log_flush_time = current_time;
+ srv_log_writes_and_flush++;
+ }
+}
+
+/*********************************************************************//**
+The master thread controlling the server.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_master_thread(
/*==============*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)))
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
{
os_event_t event;
- time_t last_flush_time;
- time_t current_time;
ulint old_activity_count;
ulint n_pages_purged = 0;
ulint n_bytes_merged;
@@ -2493,7 +2551,7 @@ srv_master_thread(
ib_uint64_t lsn_old;
ib_uint64_t oldest_lsn;
-
+
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id()));
@@ -2501,10 +2559,9 @@ srv_master_thread(
srv_main_thread_process_no = os_proc_get_number();
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
- srv_table_reserve_slot(SRV_MASTER);
-
mutex_enter(&kernel_mutex);
+ srv_table_reserve_slot(SRV_MASTER);
srv_n_threads_active[SRV_MASTER]++;
mutex_exit(&kernel_mutex);
@@ -2519,8 +2576,8 @@ loop:
srv_main_thread_op_info = "reserving kernel mutex";
- n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios_very_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
mutex_enter(&kernel_mutex);
/* Store the user activity counter at the start of this loop */
@@ -2536,16 +2593,19 @@ loop:
/* ---- We run the following loop approximately once per second
when there is database activity */
+ srv_last_log_flush_time = time(NULL);
skip_sleep = FALSE;
for (i = 0; i < 10; i++) {
- n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
srv_main_thread_op_info = "sleeping";
+ srv_main_1_second_loops++;
if (!skip_sleep) {
os_thread_sleep(1000000);
+ srv_main_sleeps++;
/*
mutex_enter(&(log_sys->mutex));
@@ -2578,34 +2638,27 @@ loop:
goto background_loop;
}
- /* We flush the log once in a second even if no commit
- is issued or the we have specified in my.cnf no flush
- at transaction commit */
-
- srv_main_thread_op_info = "flushing log";
- log_buffer_flush_to_disk();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
srv_main_thread_op_info = "making checkpoint";
log_free_check();
- /* If there were less than 5 i/os during the
- one second sleep, we assume that there is free
- disk i/o capacity available, and it makes sense to
- do an insert buffer merge. */
+ /* If i/os during one second sleep were less than 5% of
+ capacity, we assume that there is free disk i/o capacity
+ available, and it makes sense to do an insert buffer merge. */
n_pend_ios = buf_get_n_pending_ios()
+ log_sys->n_pending_writes;
- n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
- if (n_pend_ios < PCT_IO(3) && (n_ios - n_ios_old < PCT_IO(5))) {
+ n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
+ if (n_pend_ios < SRV_PEND_IO_THRESHOLD
+ && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
srv_main_thread_op_info = "doing insert buffer merge";
- ibuf_contract_for_n_pages(
- TRUE, PCT_IBUF_IO((srv_insert_buffer_batch_size / 4)));
+ ibuf_contract_for_n_pages(FALSE, PCT_IBUF_IO(5));
- srv_main_thread_op_info = "flushing log";
-
- /* No fsync when srv_flush_log_at_trx_commit != 1 */
- log_buffer_flush_maybe_sync();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
}
if (UNIV_UNLIKELY(buf_get_modified_ratio_pct()
@@ -2614,7 +2667,10 @@ loop:
/* Try to keep the number of modified pages in the
buffer pool under the limit wished by the user */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ srv_main_thread_op_info =
+ "flushing buffer pool pages";
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
/* If we had to do the flush, it may have taken
@@ -2623,10 +2679,34 @@ loop:
iteration of this loop. */
skip_sleep = TRUE;
+
+ mutex_enter(&(log_sys->mutex));
+ lsn_old = log_sys->lsn;
+ mutex_exit(&(log_sys->mutex));
+ } else if (srv_adaptive_flushing) {
+
+ /* Try to keep the rate of flushing of dirty
+ pages such that redo log generation does not
+ produce bursts of IO at checkpoint time. */
+ ulint n_flush = buf_flush_get_desired_flush_rate();
+
+ if (n_flush) {
+ srv_main_thread_op_info =
+ "flushing buffer pool pages";
+ n_flush = ut_min(PCT_IO(100), n_flush);
+ n_pages_flushed =
+ buf_flush_batch(
+ BUF_FLUSH_LIST,
+ n_flush,
+ IB_ULONGLONG_MAX);
+ skip_sleep = TRUE;
+ }
+
mutex_enter(&(log_sys->mutex));
lsn_old = log_sys->lsn;
mutex_exit(&(log_sys->mutex));
} else if (srv_adaptive_checkpoint == 1) {
+ /* adaptive_flushing option is prior to adaptive_checkpoint option, for now */
/* Try to keep modified age not to exceed
max_checkpoint_age * 7/8 line */
@@ -2688,16 +2768,16 @@ loop:
lsn_old = log_sys->lsn;
mutex_exit(&(log_sys->mutex));
} else if ((log_sys->lsn - oldest_lsn)
- > (log_sys->max_checkpoint_age)/2 ) {
+ > (log_sys->max_checkpoint_age)/4 ) {
/* defence line (max_checkpoint_age * 1/2) */
ib_uint64_t lsn = log_sys->lsn;
+
ib_uint64_t level, bpl;
buf_page_t* bpage;
- mutex_exit(&(log_sys->mutex));
-
mutex_exit(&(log_sys->mutex));
+
mutex_enter(&flush_list_mutex);
level = 0;
@@ -2724,7 +2804,7 @@ loop:
if (!srv_use_doublewrite_buf) {
/* flush is faster than when doublewrite */
- bpl = (bpl * 3) / 4;
+ bpl = (bpl * 7) / 8;
}
if (bpl) {
@@ -2774,38 +2854,43 @@ retry_flush_batch:
seconds */
mem_validate_all_blocks();
#endif
- /* If there were less than 200 i/os during the 10 second period,
- we assume that there is free disk i/o capacity available, and it
- makes sense to flush 100 pages. */
+ /* If i/os during the 10 second period were less than 200% of
+ capacity, we assume that there is free disk i/o capacity
+ available, and it makes sense to flush srv_io_capacity pages.
+
+ Note that this is done regardless of the fraction of dirty
+ pages relative to the max requested by the user. The one second
+ loop above requests writes for that case. The writes done here
+ are not required, and may be disabled. */
n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
- n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
- if (n_pend_ios < 3 && (n_ios - n_ios_very_old < PCT_IO(200))) {
-
- srv_main_thread_op_info = "flushing buffer pool pages";
- buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100), IB_ULONGLONG_MAX);
+ n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
- srv_main_thread_op_info = "flushing log";
- /* No fsync when srv_flush_log_at_trx_commit != 1 */
- log_buffer_flush_maybe_sync();
+ srv_main_10_second_loops++;
+ if (n_pend_ios < SRV_PEND_IO_THRESHOLD
+ && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
+
+ srv_main_thread_op_info = "flushing buffer pool pages";
+ buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ IB_ULONGLONG_MAX);
+
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
}
/* We run a batch of insert buffer merge every 10 seconds,
even if the server were active */
srv_main_thread_op_info = "doing insert buffer merge";
- ibuf_contract_for_n_pages(TRUE, PCT_IBUF_IO((srv_insert_buffer_batch_size / 4)));
+ ibuf_contract_for_n_pages(FALSE, PCT_IBUF_IO(5));
- srv_main_thread_op_info = "flushing log";
- /* No fsync when srv_flush_log_at_trx_commit != 1 */
- log_buffer_flush_maybe_sync();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
+ if (!srv_use_purge_thread) {
/* We run a full purge every 10 seconds, even if the server
were active */
-
- last_flush_time = time(NULL);
-
do {
if (srv_fast_shutdown && srv_shutdown_state > 0) {
@@ -2816,15 +2901,11 @@ retry_flush_batch:
srv_main_thread_op_info = "purging";
n_pages_purged = trx_purge();
- current_time = time(NULL);
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
- if (difftime(current_time, last_flush_time) > 1) {
- srv_main_thread_op_info = "flushing log";
-
- log_buffer_flush_to_disk();
- last_flush_time = current_time;
- }
} while (n_pages_purged);
+ }
srv_main_thread_op_info = "flushing buffer pool pages";
@@ -2836,14 +2917,16 @@ retry_flush_batch:
(> 70 %), we assume we can afford reserving the disk(s) for
the time it requires to flush 100 pages */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
} else {
/* Otherwise, we only flush a small number of pages so that
we do not unnecessarily use much disk i/o capacity from
other work */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(10),
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(10),
IB_ULONGLONG_MAX);
}
@@ -2877,7 +2960,7 @@ background_loop:
/* The server has been quiet for a while: start running background
operations */
-
+ srv_main_background_loops++;
srv_main_thread_op_info = "doing background drop tables";
n_tables_to_drop = row_drop_tables_for_mysql_in_background();
@@ -2891,12 +2974,10 @@ background_loop:
os_thread_sleep(100000);
}
+ if (!srv_use_purge_thread) {
srv_main_thread_op_info = "purging";
/* Run a full purge */
-
- last_flush_time = time(NULL);
-
do {
if (srv_fast_shutdown && srv_shutdown_state > 0) {
@@ -2906,15 +2987,11 @@ background_loop:
srv_main_thread_op_info = "purging";
n_pages_purged = trx_purge();
- current_time = time(NULL);
-
- if (difftime(current_time, last_flush_time) > 1) {
- srv_main_thread_op_info = "flushing log";
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
- log_buffer_flush_to_disk();
- last_flush_time = current_time;
- }
} while (n_pages_purged);
+ }
srv_main_thread_op_info = "reserving kernel mutex";
@@ -2930,8 +3007,12 @@ background_loop:
if (srv_fast_shutdown && srv_shutdown_state > 0) {
n_bytes_merged = 0;
} else {
- n_bytes_merged = ibuf_contract_for_n_pages(
- TRUE, PCT_IBUF_IO((srv_insert_buffer_batch_size * 5)));
+ /* This should do an amount of IO similar to the number of
+ dirty pages that will be flushed in the call to
+ buf_flush_batch below. Otherwise, the system favors
+ clean pages over cleanup throughput. */
+ n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
+ PCT_IBUF_IO(100));
}
srv_main_thread_op_info = "reserving kernel mutex";
@@ -2945,9 +3026,10 @@ background_loop:
flush_loop:
srv_main_thread_op_info = "flushing buffer pool pages";
-
+ srv_main_flush_loops++;
if (srv_fast_shutdown < 2) {
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
} else {
/* In the fastest shutdown we do not flush the buffer pool
@@ -2968,16 +3050,8 @@ flush_loop:
srv_main_thread_op_info = "waiting for buffer pool flush to end";
buf_flush_wait_batch_end(BUF_FLUSH_LIST);
- srv_main_thread_op_info = "flushing log";
-
- current_time = time(NULL);
- if (difftime(current_time, last_flush_time) > 1) {
- log_buffer_flush_to_disk();
- last_flush_time = current_time;
- } else {
- /* No fsync when srv_flush_log_at_trx_commit != 1 */
- log_buffer_flush_maybe_sync();
- }
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
srv_main_thread_op_info = "making checkpoint";
@@ -3070,4 +3144,143 @@ suspend_thread:
OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
}
-#endif /* !UNIV_HOTBACKUP */
+
+/*************************************************************************
+A thread which is devoted to purge, for take over the master thread's
+purging */
+UNIV_INTERN
+os_thread_ret_t
+srv_purge_thread(
+/*=============*/
+ void* arg __attribute__((unused)))
+ /* in: a dummy parameter required by os_thread_create */
+{
+ ulint n_pages_purged;
+ ulint n_pages_purged_sum = 1; /* dummy */
+ ulint history_len;
+ ulint sleep_ms= 10000; /* initial: 10 sec. */
+ ibool can_be_last = FALSE;
+
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ fprintf(stderr, "Purge thread starts, id %lu\n",
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
+
+ mutex_enter(&kernel_mutex);
+ srv_table_reserve_slot(SRV_PURGE);
+ srv_n_threads_active[SRV_PURGE]++;
+ mutex_exit(&kernel_mutex);
+
+loop:
+ if (srv_shutdown_state > 0) {
+ if (srv_fast_shutdown) {
+ /* someone other should wait the end of the workers */
+ goto exit_func;
+ }
+
+ mutex_enter(&kernel_mutex);
+ if (srv_n_threads_active[SRV_PURGE_WORKER]) {
+ can_be_last = FALSE;
+ } else {
+ can_be_last = TRUE;
+ }
+ mutex_exit(&kernel_mutex);
+
+ sleep_ms = 10;
+ }
+
+ os_thread_sleep( sleep_ms * 1000 );
+
+ history_len = trx_sys->rseg_history_len;
+ if (history_len > 1000)
+ sleep_ms /= 10;
+ if (sleep_ms < 10)
+ sleep_ms = 10;
+
+ n_pages_purged_sum = 0;
+
+ do {
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+ goto exit_func;
+ }
+ n_pages_purged = trx_purge();
+ n_pages_purged_sum += n_pages_purged;
+ } while (n_pages_purged);
+
+ if (srv_shutdown_state > 0 && can_be_last) {
+ /* the last trx_purge() is executed without workers */
+ goto exit_func;
+ }
+
+ if (n_pages_purged_sum) {
+ srv_active_wake_master_thread();
+ }
+
+ if (n_pages_purged_sum == 0)
+ sleep_ms *= 10;
+ if (sleep_ms > 10000)
+ sleep_ms = 10000;
+
+ goto loop;
+
+exit_func:
+ trx_purge_worker_wake(); /* It may not make sense. for safety only */
+
+ /* wake master thread to flush the pages */
+ srv_wake_master_thread();
+
+ mutex_enter(&kernel_mutex);
+ srv_n_threads_active[SRV_PURGE]--;
+ mutex_exit(&kernel_mutex);
+ os_thread_exit(NULL);
+
+ OS_THREAD_DUMMY_RETURN;
+}
+
+/*************************************************************************
+A thread which is devoted to purge, for take over the master thread's
+purging */
+UNIV_INTERN
+os_thread_ret_t
+srv_purge_worker_thread(
+/*====================*/
+ void* arg)
+{
+ ulint worker_id; /* index for array */
+
+ worker_id = *((ulint*)arg);
+
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ fprintf(stderr, "Purge worker thread starts, id %lu\n",
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
+ mutex_enter(&kernel_mutex);
+ srv_table_reserve_slot(SRV_PURGE_WORKER);
+ srv_n_threads_active[SRV_PURGE_WORKER]++;
+ mutex_exit(&kernel_mutex);
+
+loop:
+ /* purge worker threads only works when srv_shutdown_state==0 */
+ /* for safety and exactness. */
+ if (srv_shutdown_state > 0) {
+ goto exit_func;
+ }
+
+ trx_purge_worker_wait();
+
+ if (srv_shutdown_state > 0) {
+ goto exit_func;
+ }
+
+ trx_purge_worker(worker_id);
+
+ goto loop;
+
+exit_func:
+ mutex_enter(&kernel_mutex);
+ srv_n_threads_active[SRV_PURGE_WORKER]--;
+ mutex_exit(&kernel_mutex);
+ os_thread_exit(NULL);
+
+ OS_THREAD_DUMMY_RETURN;
+}
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c
index 3d5ddb9c89b..264bf7a7c05 100644
--- a/storage/xtradb/srv/srv0start.c
+++ b/storage/xtradb/srv/srv0start.c
@@ -22,113 +22,154 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
-/************************************************************************
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+This program is free 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
+
+***********************************************************************/
+
+/********************************************************************//**
+@file srv/srv0start.c
Starts the InnoDB database server
Created 2/16/1996 Heikki Tuuri
*************************************************************************/
-#include "os0proc.h"
-#include "sync0sync.h"
#include "ut0mem.h"
#include "mem0mem.h"
#include "data0data.h"
#include "data0type.h"
#include "dict0dict.h"
#include "buf0buf.h"
-#include "buf0flu.h"
-#include "buf0rea.h"
#include "os0file.h"
#include "os0thread.h"
#include "fil0fil.h"
#include "fsp0fsp.h"
#include "rem0rec.h"
-#include "rem0cmp.h"
#include "mtr0mtr.h"
#include "log0log.h"
#include "log0recv.h"
#include "page0page.h"
#include "page0cur.h"
#include "trx0trx.h"
-#include "dict0boot.h"
-#include "dict0load.h"
#include "trx0sys.h"
-#include "dict0crea.h"
#include "btr0btr.h"
-#include "btr0pcur.h"
#include "btr0cur.h"
-#include "btr0sea.h"
#include "rem0rec.h"
-#include "srv0srv.h"
-#include "que0que.h"
-#include "usr0sess.h"
-#include "lock0lock.h"
-#include "trx0roll.h"
-#include "trx0purge.h"
-#include "row0ins.h"
-#include "row0sel.h"
-#include "row0upd.h"
-#include "row0row.h"
-#include "row0mysql.h"
-#include "lock0lock.h"
#include "ibuf0ibuf.h"
-#include "pars0pars.h"
-#include "btr0sea.h"
#include "srv0start.h"
-#include "que0que.h"
-
-/* Log sequence number immediately after startup */
+#include "srv0srv.h"
+#ifndef UNIV_HOTBACKUP
+# include "os0proc.h"
+# include "sync0sync.h"
+# include "buf0flu.h"
+# include "buf0rea.h"
+# include "dict0boot.h"
+# include "dict0load.h"
+# include "que0que.h"
+# include "usr0sess.h"
+# include "lock0lock.h"
+# include "trx0roll.h"
+# include "trx0purge.h"
+# include "lock0lock.h"
+# include "pars0pars.h"
+# include "btr0sea.h"
+# include "rem0cmp.h"
+# include "dict0crea.h"
+# include "row0ins.h"
+# include "row0sel.h"
+# include "row0upd.h"
+# include "row0row.h"
+# include "row0mysql.h"
+# include "btr0pcur.h"
+# include "thr0loc.h"
+# include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
+
+/** Log sequence number immediately after startup */
UNIV_INTERN ib_uint64_t srv_start_lsn;
-/* Log sequence number at shutdown */
+/** Log sequence number at shutdown */
UNIV_INTERN ib_uint64_t srv_shutdown_lsn;
#ifdef HAVE_DARWIN_THREADS
# include <sys/utsname.h>
+/** TRUE if the F_FULLFSYNC option is available */
UNIV_INTERN ibool srv_have_fullfsync = FALSE;
#endif
+/** TRUE if a raw partition is in use */
UNIV_INTERN ibool srv_start_raw_disk_in_use = FALSE;
+/** TRUE if the server is being started, before rolling back any
+incomplete transactions */
UNIV_INTERN ibool srv_startup_is_before_trx_rollback_phase = FALSE;
+/** TRUE if the server is being started */
UNIV_INTERN ibool srv_is_being_started = FALSE;
+/** TRUE if the server was successfully started */
UNIV_INTERN ibool srv_was_started = FALSE;
-#ifndef UNIV_HOTBACKUP
+/** TRUE if innobase_start_or_create_for_mysql() has been called */
static ibool srv_start_has_been_called = FALSE;
-#endif /* !UNIV_HOTBACKUP */
-/* At a shutdown the value first climbs to SRV_SHUTDOWN_CLEANUP
-and then to SRV_SHUTDOWN_LAST_PHASE */
-UNIV_INTERN ulint srv_shutdown_state = 0;
+/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
+SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
+UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE;
-#ifndef UNIV_HOTBACKUP
+/** Files comprising the system tablespace */
static os_file_t files[1000];
+/** Mutex protecting the ios count */
static mutex_t ios_mutex;
+/** Count of I/O operations in io_handler_thread() */
static ulint ios;
-static ulint n[SRV_MAX_N_IO_THREADS + 5];
-static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5];
+/** io_handler_thread parameters for thread identification */
+static ulint n[SRV_MAX_N_IO_THREADS + 5 + 64];
+/** io_handler_thread identifiers */
+static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5 + 64];
-/* We use this mutex to test the return value of pthread_mutex_trylock
+/** We use this mutex to test the return value of pthread_mutex_trylock
on successful locking. HP-UX does NOT return 0, though Linux et al do. */
static os_fast_mutex_t srv_os_test_mutex;
-/* Name of srv_monitor_file */
+/** Name of srv_monitor_file */
static char* srv_monitor_file_name;
#endif /* !UNIV_HOTBACKUP */
+/** */
#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD
#define SRV_MAX_N_PENDING_SYNC_IOS 100
+/*********************************************************************//**
+Convert a numeric string that optionally ends in G or M, to a number
+containing megabytes.
+@return next character in string */
static
char*
srv_parse_megabytes(
/*================*/
- /* out: next character in string */
- char* str, /* in: string containing a quantity in bytes */
- ulint* megs) /* out: the number in megabytes */
+ char* str, /*!< in: string containing a quantity in bytes */
+ ulint* megs) /*!< out: the number in megabytes */
{
char* endp;
ulint size;
@@ -153,15 +194,15 @@ srv_parse_megabytes(
return(str);
}
-/*************************************************************************
+/*********************************************************************//**
Reads the data files and their sizes from a character string given in
-the .cnf file. */
+the .cnf file.
+@return TRUE if ok, FALSE on parse error */
UNIV_INTERN
ibool
srv_parse_data_file_paths_and_sizes(
/*================================*/
- /* out: TRUE if ok, FALSE on parse error */
- char* str) /* in/out: the data file path string */
+ char* str) /*!< in/out: the data file path string */
{
char* input_str;
char* path;
@@ -337,15 +378,15 @@ srv_parse_data_file_paths_and_sizes(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Reads log group home directories from a character string given in
-the .cnf file. */
+the .cnf file.
+@return TRUE if ok, FALSE on parse error */
UNIV_INTERN
ibool
srv_parse_log_group_home_dirs(
/*==========================*/
- /* out: TRUE if ok, FALSE on parse error */
- char* str) /* in/out: character string */
+ char* str) /*!< in/out: character string */
{
char* input_str;
char* path;
@@ -409,7 +450,7 @@ srv_parse_log_group_home_dirs(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Frees the memory allocated by srv_parse_data_file_paths_and_sizes()
and srv_parse_log_group_home_dirs(). */
UNIV_INTERN
@@ -428,14 +469,15 @@ srv_free_paths_and_sizes(void)
}
#ifndef UNIV_HOTBACKUP
-/************************************************************************
-I/o-handler thread function. */
+/********************************************************************//**
+I/o-handler thread function.
+@return OS_THREAD_DUMMY_RETURN */
static
-
os_thread_ret_t
io_handler_thread(
/*==============*/
- void* arg)
+ void* arg) /*!< in: pointer to the number of the segment in
+ the aio array */
{
ulint segment;
ulint i;
@@ -454,6 +496,8 @@ io_handler_thread(
mutex_exit(&ios_mutex);
}
+ thr_local_free(os_thread_get_curr_id());
+
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit.
The thread actually never comes here because it is exited in an
@@ -471,13 +515,13 @@ io_handler_thread(
#define SRV_PATH_SEPARATOR '/'
#endif
-/*************************************************************************
+/*********************************************************************//**
Normalizes a directory path for Windows: converts slashes to backslashes. */
UNIV_INTERN
void
srv_normalize_path_for_win(
/*=======================*/
- char* str __attribute__((unused))) /* in/out: null-terminated
+ char* str __attribute__((unused))) /*!< in/out: null-terminated
character string */
{
#ifdef __WIN__
@@ -490,96 +534,72 @@ srv_normalize_path_for_win(
#endif
}
-/*************************************************************************
-Adds a slash or a backslash to the end of a string if it is missing
-and the string is not empty. */
-UNIV_INTERN
-char*
-srv_add_path_separator_if_needed(
-/*=============================*/
- /* out: string which has the separator if the
- string is not empty */
- char* str) /* in: null-terminated character string */
-{
- char* out_str;
- ulint len = ut_strlen(str);
-
- if (len == 0 || str[len - 1] == SRV_PATH_SEPARATOR) {
-
- return(str);
- }
-
- out_str = ut_malloc(len + 2);
- memcpy(out_str, str, len);
- out_str[len] = SRV_PATH_SEPARATOR;
- out_str[len + 1] = 0;
-
- return(out_str);
-}
-
#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+/*********************************************************************//**
Calculates the low 32 bits when a file size which is given as a number
-database pages is converted to the number of bytes. */
+database pages is converted to the number of bytes.
+@return low 32 bytes of file size when expressed in bytes */
static
ulint
srv_calc_low32(
/*===========*/
- /* out: low 32 bytes of file size when
- expressed in bytes */
- ulint file_size) /* in: file size in database pages */
+ ulint file_size) /*!< in: file size in database pages */
{
return(0xFFFFFFFFUL & (file_size << UNIV_PAGE_SIZE_SHIFT));
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the high 32 bits when a file size which is given as a number
-database pages is converted to the number of bytes. */
+database pages is converted to the number of bytes.
+@return high 32 bytes of file size when expressed in bytes */
static
ulint
srv_calc_high32(
/*============*/
- /* out: high 32 bytes of file size when
- expressed in bytes */
- ulint file_size) /* in: file size in database pages */
+ ulint file_size) /*!< in: file size in database pages */
{
return(file_size >> (32 - UNIV_PAGE_SIZE_SHIFT));
}
-/*************************************************************************
-Creates or opens the log files and closes them. */
+/*********************************************************************//**
+Creates or opens the log files and closes them.
+@return DB_SUCCESS or error code */
static
ulint
open_or_create_log_file(
/*====================*/
- /* out: DB_SUCCESS or error code */
- ibool create_new_db, /* in: TRUE if we should create a
+ ibool create_new_db, /*!< in: TRUE if we should create a
new database */
- ibool* log_file_created, /* out: TRUE if new log file
+ ibool* log_file_created, /*!< out: TRUE if new log file
created */
- ibool log_file_has_been_opened,/* in: TRUE if a log file has been
+ ibool log_file_has_been_opened,/*!< in: TRUE if a log file has been
opened before: then it is an error
to try to create another log file */
- ulint k, /* in: log group number */
- ulint i) /* in: log file number in group */
+ ulint k, /*!< in: log group number */
+ ulint i) /*!< in: log file number in group */
{
ibool ret;
ulint size;
ulint size_high;
char name[10000];
+ ulint dirnamelen;
UT_NOT_USED(create_new_db);
*log_file_created = FALSE;
srv_normalize_path_for_win(srv_log_group_home_dirs[k]);
- srv_log_group_home_dirs[k] = srv_add_path_separator_if_needed(
- srv_log_group_home_dirs[k]);
- ut_a(strlen(srv_log_group_home_dirs[k])
- < (sizeof name) - 10 - sizeof "ib_logfile");
- sprintf(name, "%s%s%lu", srv_log_group_home_dirs[k],
- "ib_logfile", (ulong) i);
+ dirnamelen = strlen(srv_log_group_home_dirs[k]);
+ ut_a(dirnamelen < (sizeof name) - 10 - sizeof "ib_logfile");
+ memcpy(name, srv_log_group_home_dirs[k], dirnamelen);
+
+ /* Add a path separator if needed. */
+ if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
+ name[dirnamelen++] = SRV_PATH_SEPARATOR;
+ }
+
+ sprintf(name + dirnamelen, "%s%lu", "ib_logfile", (ulong) i);
files[i] = os_file_create(name, OS_FILE_CREATE, OS_FILE_NORMAL,
OS_LOG_FILE, &ret);
@@ -699,26 +719,26 @@ open_or_create_log_file(
return(DB_SUCCESS);
}
-/*************************************************************************
-Creates or opens database data files and closes them. */
+/*********************************************************************//**
+Creates or opens database data files and closes them.
+@return DB_SUCCESS or error code */
static
ulint
open_or_create_data_files(
/*======================*/
- /* out: DB_SUCCESS or error code */
- ibool* create_new_db, /* out: TRUE if new database should be
+ ibool* create_new_db, /*!< out: TRUE if new database should be
created */
#ifdef UNIV_LOG_ARCHIVE
- ulint* min_arch_log_no,/* out: min of archived log
+ ulint* min_arch_log_no,/*!< out: min of archived log
numbers in data files */
- ulint* max_arch_log_no,/* out: max of archived log
+ ulint* max_arch_log_no,/*!< out: max of archived log
numbers in data files */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t* min_flushed_lsn,/* out: min of flushed lsn
+ ib_uint64_t* min_flushed_lsn,/*!< out: min of flushed lsn
values in data files */
- ib_uint64_t* max_flushed_lsn,/* out: max of flushed lsn
+ ib_uint64_t* max_flushed_lsn,/*!< out: max of flushed lsn
values in data files */
- ulint* sum_of_new_sizes)/* out: sum of sizes of the
+ ulint* sum_of_new_sizes)/*!< out: sum of sizes of the
new files added */
{
ibool ret;
@@ -742,14 +762,22 @@ open_or_create_data_files(
*create_new_db = FALSE;
srv_normalize_path_for_win(srv_data_home);
- srv_data_home = srv_add_path_separator_if_needed(srv_data_home);
for (i = 0; i < srv_n_data_files; i++) {
+ ulint dirnamelen;
+
srv_normalize_path_for_win(srv_data_file_names[i]);
+ dirnamelen = strlen(srv_data_home);
- ut_a(strlen(srv_data_home) + strlen(srv_data_file_names[i])
+ ut_a(dirnamelen + strlen(srv_data_file_names[i])
< (sizeof name) - 1);
- sprintf(name, "%s%s", srv_data_home, srv_data_file_names[i]);
+ memcpy(name, srv_data_home, dirnamelen);
+ /* Add a path separator if needed. */
+ if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
+ name[dirnamelen++] = SRV_PATH_SEPARATOR;
+ }
+
+ strcpy(name + dirnamelen, srv_data_file_names[i]);
if (srv_data_file_is_raw_partition[i] == 0) {
@@ -973,12 +1001,12 @@ skip_size_check:
/********************************************************************
Starts InnoDB and creates a new database if database files
-are not found and the user wants. */
+are not found and the user wants.
+@return DB_SUCCESS or error code */
UNIV_INTERN
int
innobase_start_or_create_for_mysql(void)
/*====================================*/
- /* out: DB_SUCCESS or error code */
{
buf_pool_t* ret;
ibool create_new_db;
@@ -996,6 +1024,7 @@ innobase_start_or_create_for_mysql(void)
ulint tablespace_size_in_header;
ulint err;
ulint i;
+ ulint io_limit;
my_bool srv_file_per_table_original_value
= srv_file_per_table;
mtr_t mtr;
@@ -1058,6 +1087,10 @@ innobase_start_or_create_for_mysql(void)
"InnoDB: !!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!\n");
#endif
+#ifdef UNIV_LOG_LSN_DEBUG
+ fprintf(stderr,
+ "InnoDB: !!!!!!!! UNIV_LOG_LSN_DEBUG switched on !!!!!!!!!\n");
+#endif /* UNIV_LOG_LSN_DEBUG */
#ifdef UNIV_MEM_DEBUG
fprintf(stderr,
"InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n");
@@ -1068,18 +1101,7 @@ innobase_start_or_create_for_mysql(void)
"InnoDB: The InnoDB memory heap is disabled\n");
}
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- fprintf(stderr,
- "InnoDB: Mutexes and rw_locks use GCC atomic builtins.\n");
-#else /* INNODB_RW_LOCKS_USE_ATOMICS */
- fprintf(stderr,
- "InnoDB: Mutexes use GCC atomic builtins, rw_locks do not.\n");
-#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#else /* HAVE_GCC_ATOMIC_BUILTINS */
- fprintf(stderr,
- "InnoDB: Neither mutexes nor rw_locks use GCC atomic builtins.\n");
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+ fprintf(stderr, "InnoDB: %s\n", IB_ATOMICS_STARTUP_MSG);
/* Since InnoDB does not currently clean up all its internal data
structures in MySQL Embedded Server Library server_end(), we
@@ -1088,7 +1110,7 @@ innobase_start_or_create_for_mysql(void)
if (srv_start_has_been_called) {
fprintf(stderr,
- "InnoDB: Error:startup called second time"
+ "InnoDB: Error: startup called second time"
" during the process lifetime.\n"
"InnoDB: In the MySQL Embedded Server Library"
" you cannot call server_init()\n"
@@ -1108,25 +1130,26 @@ innobase_start_or_create_for_mysql(void)
os_aio_use_native_aio = FALSE;
#ifdef __WIN__
- if (os_get_os_version() == OS_WIN95
- || os_get_os_version() == OS_WIN31
- || os_get_os_version() == OS_WINNT) {
-
+ switch (os_get_os_version()) {
+ case OS_WIN95:
+ case OS_WIN31:
+ case OS_WINNT:
/* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
and NT use simulated aio. In NT Windows provides async i/o,
but when run in conjunction with InnoDB Hot Backup, it seemed
to corrupt the data files. */
os_aio_use_native_aio = FALSE;
- } else {
- /* On Win 2000 and XP currently native async i/o
- is not used for xtradb by default */
+ break;
+ default:
+ /* On Win 2000 and XP use async i/o */
//os_aio_use_native_aio = TRUE;
os_aio_use_native_aio = FALSE;
fprintf(stderr,
"InnoDB: Windows native async i/o is disabled as default.\n"
"InnoDB: It is not applicable for the current"
" multi io threads implementation.\n");
+ break;
}
#endif
if (srv_file_flush_method_str == NULL) {
@@ -1250,32 +1273,37 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR);
}
- /* over write innodb_file_io_threads */
- srv_n_file_io_threads = 2 + srv_n_read_io_threads + srv_n_write_io_threads;
+ /* If user has set the value of innodb_file_io_threads then
+ we'll emit a message telling the user that this parameter
+ is now deprecated. */
+ if (srv_n_file_io_threads != 4) {
+ fprintf(stderr, "InnoDB: Warning:"
+ " innodb_file_io_threads is deprecated."
+ " Please use innodb_read_io_threads and"
+ " innodb_write_io_threads instead\n");
+ }
- /* Restrict the maximum number of file i/o threads */
- if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) {
+ /* Now overwrite the value on srv_n_file_io_threads */
+ srv_n_file_io_threads = 2 + srv_n_read_io_threads
+ + srv_n_write_io_threads;
- srv_n_file_io_threads = SRV_MAX_N_IO_THREADS;
- srv_n_read_io_threads = srv_n_write_io_threads = (SRV_MAX_N_IO_THREADS - 2) / 2;
- }
+ ut_a(srv_n_file_io_threads <= SRV_MAX_N_IO_THREADS);
+ /* TODO: Investigate if SRV_N_PENDING_IOS_PER_THREAD (32) limit
+ still applies to windows. */
if (!os_aio_use_native_aio) {
- /* In simulated aio we currently have use only for 4 threads */
- /*srv_n_file_io_threads = 4;*/
-
- os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD
- * srv_n_file_io_threads,
- srv_n_read_io_threads, srv_n_write_io_threads,
- SRV_MAX_N_PENDING_SYNC_IOS);
+ io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
} else {
- os_aio_init(SRV_N_PENDING_IOS_PER_THREAD
- * srv_n_file_io_threads,
- srv_n_read_io_threads, srv_n_write_io_threads,
- SRV_MAX_N_PENDING_SYNC_IOS);
+ io_limit = SRV_N_PENDING_IOS_PER_THREAD;
}
- fil_init(srv_max_n_open_files);
+ os_aio_init(io_limit,
+ srv_n_read_io_threads,
+ srv_n_write_io_threads,
+ SRV_MAX_N_PENDING_SYNC_IOS);
+
+ fil_init(srv_file_per_table ? 50000 : 5000,
+ srv_max_n_open_files);
ret = buf_pool_init();
@@ -1349,7 +1377,7 @@ innobase_start_or_create_for_mysql(void)
sum_of_new_sizes += srv_data_file_sizes[i];
}
- if (sum_of_new_sizes < 640) {
+ if (sum_of_new_sizes < 10485760 / UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Error: tablespace size must be"
" at least 10 MB\n");
@@ -1484,6 +1512,12 @@ innobase_start_or_create_for_mysql(void)
dict_create();
srv_startup_is_before_trx_rollback_phase = FALSE;
+ if (trx_doublewrite == NULL) {
+ /* Create the doublewrite buffer here to avoid assertion error
+ about page_no of doublewrite_buf */
+ trx_sys_create_doublewrite_buf();
+ }
+
if (srv_extra_rsegments)
trx_sys_create_extra_rseg(srv_extra_rsegments);
#ifdef UNIV_LOG_ARCHIVE
@@ -1671,6 +1705,20 @@ innobase_start_or_create_for_mysql(void)
os_thread_create(&srv_master_thread, NULL, thread_ids
+ (1 + SRV_MAX_N_IO_THREADS));
+
+ if (srv_use_purge_thread) {
+ ulint i;
+
+ os_thread_create(&srv_purge_thread, NULL, thread_ids
+ + (4 + SRV_MAX_N_IO_THREADS));
+
+ for (i = 0; i < srv_use_purge_thread - 1; i++) {
+ n[5 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */
+ os_thread_create(&srv_purge_worker_thread,
+ n + (5 + i + SRV_MAX_N_IO_THREADS),
+ thread_ids + (5 + i + SRV_MAX_N_IO_THREADS));
+ }
+ }
#ifdef UNIV_DEBUG
/* buf_debug_prints = TRUE; */
#endif /* UNIV_DEBUG */
@@ -1782,7 +1830,7 @@ innobase_start_or_create_for_mysql(void)
/* Actually, we did not change the undo log format between
4.0 and 4.1.1, and we would not need to run purge to
completion. Note also that the purge algorithm in 4.1.1
- can process the the history list again even after a full
+ can process the history list again even after a full
purge, because our algorithm does not cut the end of the
history list in all cases so that it would become empty
after a full purge. That mean that we may purge 4.0 type
@@ -1822,8 +1870,7 @@ innobase_start_or_create_for_mysql(void)
" to an earlier version of\n"
"InnoDB: InnoDB! But if you absolutely need to"
" downgrade, see\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "multiple-tablespaces.html\n"
+ "InnoDB: " REFMAN "multiple-tablespaces.html\n"
"InnoDB: for instructions.\n");
}
@@ -1843,13 +1890,13 @@ innobase_start_or_create_for_mysql(void)
return((int) DB_SUCCESS);
}
-/********************************************************************
-Shuts down the InnoDB database. */
+/****************************************************************//**
+Shuts down the InnoDB database.
+@return DB_SUCCESS or error code */
UNIV_INTERN
int
innobase_shutdown_for_mysql(void)
/*=============================*/
- /* out: DB_SUCCESS or error code */
{
ulint i;
#ifdef __NETWARE__
@@ -1884,7 +1931,7 @@ innobase_shutdown_for_mysql(void)
}
#ifdef __NETWARE__
- if(!panic_shutdown)
+ if (!panic_shutdown)
#endif
logs_empty_and_mark_files_at_shutdown();
@@ -1935,8 +1982,10 @@ innobase_shutdown_for_mysql(void)
/* All the threads have exited or are just exiting;
NOTE that the threads may not have completed their
exit yet. Should we use pthread_join() to make sure
- they have exited? Now we just sleep 0.1 seconds and
- hope that is enough! */
+ they have exited? If we did, we would have to
+ remove the pthread_detach() from
+ os_thread_exit(). Now we just sleep 0.1
+ seconds and hope that is enough! */
os_mutex_exit(os_sync_mutex);
@@ -1975,36 +2024,40 @@ innobase_shutdown_for_mysql(void)
srv_misc_tmpfile = 0;
}
+ /* This must be disabled before closing the buffer pool
+ and closing the data dictionary. */
+ btr_search_disable();
+
+ ibuf_close();
+ log_shutdown();
+ lock_sys_close();
+ thr_local_close();
trx_sys_file_format_close();
+ trx_sys_close();
mutex_free(&srv_monitor_file_mutex);
mutex_free(&srv_dict_tmpfile_mutex);
mutex_free(&srv_misc_tmpfile_mutex);
+ dict_close();
+ btr_search_sys_free();
/* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
them */
+ os_aio_free();
sync_close();
+ srv_free();
+ fil_close();
/* 4. Free the os_conc_mutex and all os_events and os_mutexes */
- srv_free();
os_sync_free();
- /* Check that all read views are closed except read view owned
- by a purge. */
-
- if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
- fprintf(stderr,
- "InnoDB: Error: all read views were not closed"
- " before shutdown:\n"
- "InnoDB: %lu read views open \n",
- UT_LIST_GET_LEN(trx_sys->view_list) - 1);
- }
-
- /* 5. Free all allocated memory and the os_fast_mutex created in
- ut0mem.c */
+ /* 5. Free all allocated memory */
+ pars_lexer_close();
+ log_mem_free();
buf_pool_free();
+ mem_close();
ut_free_all_mem();
if (os_thread_count != 0
@@ -2036,6 +2089,7 @@ innobase_shutdown_for_mysql(void)
}
srv_was_started = FALSE;
+ srv_start_has_been_called = FALSE;
return((int) DB_SUCCESS);
}
diff --git a/storage/xtradb/sync/sync0arr.c b/storage/xtradb/sync/sync0arr.c
index 62165eefd46..cfa52cdcc88 100644
--- a/storage/xtradb/sync/sync0arr.c
+++ b/storage/xtradb/sync/sync0arr.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file sync/sync0arr.c
The wait array used in synchronization primitives
Created 9/5/1995 Heikki Tuuri
@@ -73,27 +74,29 @@ wait array for the sake of diagnostics and also to avoid infinite
wait The error_monitor thread scans the global wait array to signal
any waiting threads who have missed the signal. */
-/* A cell where an individual thread may wait suspended
+/** A cell where an individual thread may wait suspended
until a resource is released. The suspending is implemented
using an operating system event semaphore. */
struct sync_cell_struct {
- void* wait_object; /* pointer to the object the
+ void* wait_object; /*!< pointer to the object the
thread is waiting for; if NULL
the cell is free for use */
- mutex_t* old_wait_mutex; /* the latest wait mutex in cell */
- rw_lock_t* old_wait_rw_lock;/* the latest wait rw-lock in cell */
- ulint request_type; /* lock type requested on the
+ mutex_t* old_wait_mutex; /*!< the latest wait mutex in cell */
+ rw_lock_t* old_wait_rw_lock;
+ /*!< the latest wait rw-lock
+ in cell */
+ ulint request_type; /*!< lock type requested on the
object */
- const char* file; /* in debug version file where
+ const char* file; /*!< in debug version file where
requested */
- ulint line; /* in debug version line where
+ ulint line; /*!< in debug version line where
requested */
- os_thread_id_t thread; /* thread id of this waiting
+ os_thread_id_t thread; /*!< thread id of this waiting
thread */
- ibool waiting; /* TRUE if the thread has already
+ ibool waiting; /*!< TRUE if the thread has already
called sync_array_event_wait
on this cell */
- ib_int64_t signal_count; /* We capture the signal_count
+ ib_int64_t signal_count; /*!< We capture the signal_count
of the wait_object when we
reset the event. This value is
then passed on to os_event_wait
@@ -101,7 +104,7 @@ struct sync_cell_struct {
has not been signalled in the
period between the reset and
wait call. */
- time_t reservation_time;/* time when the thread reserved
+ time_t reservation_time;/*!< time when the thread reserved
the wait cell */
};
@@ -110,54 +113,56 @@ for an event allocated for the array without owning the
protecting mutex (depending on the case: OS or database mutex), but
all changes (set or reset) to the state of the event must be made
while owning the mutex. */
+
+/** Synchronization array */
struct sync_array_struct {
- ulint n_reserved; /* number of currently reserved
+ ulint n_reserved; /*!< number of currently reserved
cells in the wait array */
- ulint n_cells; /* number of cells in the
+ ulint n_cells; /*!< number of cells in the
wait array */
- sync_cell_t* array; /* pointer to wait array */
- ulint protection; /* this flag tells which
+ sync_cell_t* array; /*!< pointer to wait array */
+ ulint protection; /*!< this flag tells which
mutex protects the data */
- mutex_t mutex; /* possible database mutex
+ mutex_t mutex; /*!< possible database mutex
protecting this data structure */
- os_mutex_t os_mutex; /* Possible operating system mutex
+ os_mutex_t os_mutex; /*!< Possible operating system mutex
protecting the data structure.
As this data structure is used in
constructing the database mutex,
to prevent infinite recursion
in implementation, we fall back to
an OS mutex. */
- ulint sg_count; /* count of how many times an
+ ulint sg_count; /*!< count of how many times an
object has been signalled */
- ulint res_count; /* count of cell reservations
+ ulint res_count; /*!< count of cell reservations
since creation of the array */
};
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
This function is called only in the debug version. Detects a deadlock
-of one or more threads because of waits of semaphores. */
+of one or more threads because of waits of semaphores.
+@return TRUE if deadlock detected */
static
ibool
sync_array_detect_deadlock(
/*=======================*/
- /* out: TRUE if deadlock detected */
- sync_array_t* arr, /* in: wait array; NOTE! the caller must
+ sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
own the mutex to array */
- sync_cell_t* start, /* in: cell where recursive search started */
- sync_cell_t* cell, /* in: cell to search */
- ulint depth); /* in: recursion depth */
+ sync_cell_t* start, /*!< in: cell where recursive search started */
+ sync_cell_t* cell, /*!< in: cell to search */
+ ulint depth); /*!< in: recursion depth */
#endif /* UNIV_SYNC_DEBUG */
-/*********************************************************************
-Gets the nth cell in array. */
+/*****************************************************************//**
+Gets the nth cell in array.
+@return cell */
static
sync_cell_t*
sync_array_get_nth_cell(
/*====================*/
- /* out: cell */
- sync_array_t* arr, /* in: sync array */
- ulint n) /* in: index */
+ sync_array_t* arr, /*!< in: sync array */
+ ulint n) /*!< in: index */
{
ut_a(arr);
ut_a(n < arr->n_cells);
@@ -165,13 +170,13 @@ sync_array_get_nth_cell(
return(arr->array + n);
}
-/**********************************************************************
+/******************************************************************//**
Reserves the mutex semaphore protecting a sync array. */
static
void
sync_array_enter(
/*=============*/
- sync_array_t* arr) /* in: sync wait array */
+ sync_array_t* arr) /*!< in: sync wait array */
{
ulint protection;
@@ -186,13 +191,13 @@ sync_array_enter(
}
}
-/**********************************************************************
+/******************************************************************//**
Releases the mutex semaphore protecting a sync array. */
static
void
sync_array_exit(
/*============*/
- sync_array_t* arr) /* in: sync wait array */
+ sync_array_t* arr) /*!< in: sync wait array */
{
ulint protection;
@@ -207,39 +212,36 @@ sync_array_exit(
}
}
-/***********************************************************************
+/*******************************************************************//**
Creates a synchronization wait array. It is protected by a mutex
which is automatically reserved when the functions operating on it
-are called. */
+are called.
+@return own: created wait array */
UNIV_INTERN
sync_array_t*
sync_array_create(
/*==============*/
- /* out, own: created wait array */
- ulint n_cells, /* in: number of cells in the array
+ ulint n_cells, /*!< in: number of cells in the array
to create */
- ulint protection) /* in: either SYNC_ARRAY_OS_MUTEX or
+ ulint protection) /*!< in: either SYNC_ARRAY_OS_MUTEX or
SYNC_ARRAY_MUTEX: determines the type
of mutex protecting the data structure */
{
+ ulint sz;
sync_array_t* arr;
- sync_cell_t* cell_array;
- sync_cell_t* cell;
- ulint i;
ut_a(n_cells > 0);
/* Allocate memory for the data structures */
arr = ut_malloc(sizeof(sync_array_t));
+ memset(arr, 0x0, sizeof(*arr));
- cell_array = ut_malloc(sizeof(sync_cell_t) * n_cells);
+ sz = sizeof(sync_cell_t) * n_cells;
+ arr->array = ut_malloc(sz);
+ memset(arr->array, 0x0, sz);
arr->n_cells = n_cells;
- arr->n_reserved = 0;
- arr->array = cell_array;
arr->protection = protection;
- arr->sg_count = 0;
- arr->res_count = 0;
/* Then create the mutex to protect the wait array complex */
if (protection == SYNC_ARRAY_OS_MUTEX) {
@@ -250,23 +252,16 @@ sync_array_create(
ut_error;
}
- for (i = 0; i < n_cells; i++) {
- cell = sync_array_get_nth_cell(arr, i);
- cell->wait_object = NULL;
- cell->waiting = FALSE;
- cell->signal_count = 0;
- }
-
return(arr);
}
-/**********************************************************************
+/******************************************************************//**
Frees the resources in a wait array. */
UNIV_INTERN
void
sync_array_free(
/*============*/
- sync_array_t* arr) /* in, own: sync wait array */
+ sync_array_t* arr) /*!< in, own: sync wait array */
{
ulint protection;
@@ -290,14 +285,14 @@ sync_array_free(
ut_free(arr);
}
-/************************************************************************
+/********************************************************************//**
Validates the integrity of the wait array. Checks
that the number of reserved cells equals the count variable. */
UNIV_INTERN
void
sync_array_validate(
/*================*/
- sync_array_t* arr) /* in: sync wait array */
+ sync_array_t* arr) /*!< in: sync wait array */
{
ulint i;
sync_cell_t* cell;
@@ -317,13 +312,13 @@ sync_array_validate(
sync_array_exit(arr);
}
-/***********************************************************************
+/*******************************************************************//**
Returns the event that the thread owning the cell waits for. */
static
os_event_t
sync_cell_get_event(
/*================*/
- sync_cell_t* cell) /* in: non-empty sync array cell */
+ sync_cell_t* cell) /*!< in: non-empty sync array cell */
{
ulint type = cell->request_type;
@@ -336,19 +331,19 @@ sync_cell_get_event(
}
}
-/**********************************************************************
+/******************************************************************//**
Reserves a wait array cell for waiting for an object.
The event of the cell is reset to nonsignalled state. */
UNIV_INTERN
void
sync_array_reserve_cell(
/*====================*/
- sync_array_t* arr, /* in: wait array */
- void* object, /* in: pointer to the object to wait for */
- ulint type, /* in: lock request type */
- const char* file, /* in: file where requested */
- ulint line, /* in: line where requested */
- ulint* index) /* out: index of the reserved cell */
+ sync_array_t* arr, /*!< in: wait array */
+ void* object, /*!< in: pointer to the object to wait for */
+ ulint type, /*!< in: lock request type */
+ const char* file, /*!< in: file where requested */
+ ulint line, /*!< in: line where requested */
+ ulint* index) /*!< out: index of the reserved cell */
{
sync_cell_t* cell;
os_event_t event;
@@ -406,7 +401,7 @@ sync_array_reserve_cell(
return;
}
-/**********************************************************************
+/******************************************************************//**
This function should be called when a thread starts to wait on
a wait array cell. In the debug version this function checks
if the wait for a semaphore will result in a deadlock, in which
@@ -415,8 +410,8 @@ UNIV_INTERN
void
sync_array_wait_event(
/*==================*/
- sync_array_t* arr, /* in: wait array */
- ulint index) /* in: index of the reserved cell */
+ sync_array_t* arr, /*!< in: wait array */
+ ulint index) /*!< in: index of the reserved cell */
{
sync_cell_t* cell;
os_event_t event;
@@ -458,14 +453,14 @@ sync_array_wait_event(
sync_array_free_cell(arr, index);
}
-/**********************************************************************
+/******************************************************************//**
Reports info of a wait array cell. */
static
void
sync_array_cell_print(
/*==================*/
- FILE* file, /* in: file where to print */
- sync_cell_t* cell) /* in: sync cell */
+ FILE* file, /*!< in: file where to print */
+ sync_cell_t* cell) /*!< in: sync cell */
{
mutex_t* mutex;
rw_lock_t* rwlock;
@@ -487,12 +482,12 @@ sync_array_cell_print(
mutex = cell->old_wait_mutex;
fprintf(file,
- "Mutex at %p created file %s line %lu, lock var %lu\n"
+ "Mutex at %p '%s', lock var %lu\n"
#ifdef UNIV_SYNC_DEBUG
"Last time reserved in file %s line %lu, "
#endif /* UNIV_SYNC_DEBUG */
"waiters flag %lu\n",
- (void*) mutex, mutex->cfile_name, (ulong) mutex->cline,
+ (void*) mutex, mutex->cmutex_name,
(ulong) mutex->lock_word,
#ifdef UNIV_SYNC_DEBUG
mutex->file_name, (ulong) mutex->line,
@@ -508,9 +503,8 @@ sync_array_cell_print(
rwlock = cell->old_wait_rw_lock;
fprintf(file,
- " RW-latch at %p created in file %s line %lu\n",
- (void*) rwlock, rwlock->cfile_name,
- (ulong) rwlock->cline);
+ " RW-latch at %p '%s'\n",
+ (void*) rwlock, rwlock->lock_name);
writer = rw_lock_get_writer(rwlock);
if (writer != RW_LOCK_NOT_LOCKED) {
fprintf(file,
@@ -544,16 +538,15 @@ sync_array_cell_print(
}
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
-Looks for a cell with the given thread id. */
+/******************************************************************//**
+Looks for a cell with the given thread id.
+@return pointer to cell or NULL if not found */
static
sync_cell_t*
sync_array_find_thread(
/*===================*/
- /* out: pointer to cell or NULL
- if not found */
- sync_array_t* arr, /* in: wait array */
- os_thread_id_t thread) /* in: thread id */
+ sync_array_t* arr, /*!< in: wait array */
+ os_thread_id_t thread) /*!< in: thread id */
{
ulint i;
sync_cell_t* cell;
@@ -572,20 +565,20 @@ sync_array_find_thread(
return(NULL); /* Not found */
}
-/**********************************************************************
-Recursion step for deadlock detection. */
+/******************************************************************//**
+Recursion step for deadlock detection.
+@return TRUE if deadlock detected */
static
ibool
sync_array_deadlock_step(
/*=====================*/
- /* out: TRUE if deadlock detected */
- sync_array_t* arr, /* in: wait array; NOTE! the caller must
+ sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
own the mutex to array */
- sync_cell_t* start, /* in: cell where recursive search
+ sync_cell_t* start, /*!< in: cell where recursive search
started */
- os_thread_id_t thread, /* in: thread to look at */
- ulint pass, /* in: pass value */
- ulint depth) /* in: recursion depth */
+ os_thread_id_t thread, /*!< in: thread to look at */
+ ulint pass, /*!< in: pass value */
+ ulint depth) /*!< in: recursion depth */
{
sync_cell_t* new;
ibool ret;
@@ -623,19 +616,19 @@ sync_array_deadlock_step(
return(FALSE);
}
-/**********************************************************************
+/******************************************************************//**
This function is called only in the debug version. Detects a deadlock
-of one or more threads because of waits of semaphores. */
+of one or more threads because of waits of semaphores.
+@return TRUE if deadlock detected */
static
ibool
sync_array_detect_deadlock(
/*=======================*/
- /* out: TRUE if deadlock detected */
- sync_array_t* arr, /* in: wait array; NOTE! the caller must
+ sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
own the mutex to array */
- sync_cell_t* start, /* in: cell where recursive search started */
- sync_cell_t* cell, /* in: cell to search */
- ulint depth) /* in: recursion depth */
+ sync_cell_t* start, /*!< in: cell where recursive search started */
+ sync_cell_t* cell, /*!< in: cell to search */
+ ulint depth) /*!< in: recursion depth */
{
mutex_t* mutex;
rw_lock_t* lock;
@@ -768,13 +761,13 @@ print:
}
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Determines if we can wake up the thread waiting for a sempahore. */
static
ibool
sync_arr_cell_can_wake_up(
/*======================*/
- sync_cell_t* cell) /* in: cell to search */
+ sync_cell_t* cell) /*!< in: cell to search */
{
mutex_t* mutex;
rw_lock_t* lock;
@@ -820,15 +813,15 @@ sync_arr_cell_can_wake_up(
return(FALSE);
}
-/**********************************************************************
+/******************************************************************//**
Frees the cell. NOTE! sync_array_wait_event frees the cell
automatically! */
UNIV_INTERN
void
sync_array_free_cell(
/*=================*/
- sync_array_t* arr, /* in: wait array */
- ulint index) /* in: index of the cell in array */
+ sync_array_t* arr, /*!< in: wait array */
+ ulint index) /*!< in: index of the cell in array */
{
sync_cell_t* cell;
@@ -848,16 +841,16 @@ sync_array_free_cell(
sync_array_exit(arr);
}
-/**************************************************************************
+/**********************************************************************//**
Increments the signalled count. */
UNIV_INTERN
void
sync_array_object_signalled(
/*========================*/
- sync_array_t* arr) /* in: wait array */
+ sync_array_t* arr) /*!< in: wait array */
{
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
- (void) os_atomic_increment(&arr->sg_count, 1);
+#ifdef HAVE_ATOMIC_BUILTINS
+ (void) os_atomic_increment_ulint(&arr->sg_count, 1);
#else
sync_array_enter(arr);
@@ -867,7 +860,7 @@ sync_array_object_signalled(
#endif
}
-/**************************************************************************
+/**********************************************************************//**
If the wakeup algorithm does not work perfectly at semaphore relases,
this function will do the waking (see the comment in mutex_exit). This
function should be called about every 1 second in the server.
@@ -913,14 +906,13 @@ sync_arr_wake_threads_if_sema_free(void)
sync_array_exit(arr);
}
-/**************************************************************************
-Prints warnings of long semaphore waits to stderr. */
+/**********************************************************************//**
+Prints warnings of long semaphore waits to stderr.
+@return TRUE if fatal semaphore wait threshold was exceeded */
UNIV_INTERN
ibool
sync_array_print_long_waits(void)
/*=============================*/
- /* out: TRUE if fatal semaphore wait threshold
- was exceeded */
{
sync_cell_t* cell;
ibool old_val;
@@ -979,14 +971,14 @@ sync_array_print_long_waits(void)
return(fatal);
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of the wait array. */
static
void
sync_array_output_info(
/*===================*/
- FILE* file, /* in: file where to print */
- sync_array_t* arr) /* in: wait array; NOTE! caller must own the
+ FILE* file, /*!< in: file where to print */
+ sync_array_t* arr) /*!< in: wait array; NOTE! caller must own the
mutex */
{
sync_cell_t* cell;
@@ -1012,14 +1004,14 @@ sync_array_output_info(
}
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of the wait array. */
UNIV_INTERN
void
sync_array_print_info(
/*==================*/
- FILE* file, /* in: file where to print */
- sync_array_t* arr) /* in: wait array */
+ FILE* file, /*!< in: file where to print */
+ sync_array_t* arr) /*!< in: wait array */
{
sync_array_enter(arr);
diff --git a/storage/xtradb/sync/sync0rw.c b/storage/xtradb/sync/sync0rw.c
index 09c732eefc9..07eac403dfe 100644
--- a/storage/xtradb/sync/sync0rw.c
+++ b/storage/xtradb/sync/sync0rw.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file sync/sync0rw.c
The read-write lock (for thread synchronization)
Created 9/11/1995 Heikki Tuuri
@@ -37,6 +38,7 @@ Created 9/11/1995 Heikki Tuuri
#include "os0thread.h"
#include "mem0mem.h"
#include "srv0srv.h"
+#include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
/*
IMPLEMENTATION OF THE RW_LOCK
@@ -132,29 +134,33 @@ wait_ex_event: A thread may only wait on the wait_ex_event after it has
*/
-/* number of spin waits on rw-latches,
+/** number of spin waits on rw-latches,
resulted during shared (read) locks */
UNIV_INTERN ib_int64_t rw_s_spin_wait_count = 0;
+/** number of spin loop rounds on rw-latches,
+resulted during shared (read) locks */
UNIV_INTERN ib_int64_t rw_s_spin_round_count = 0;
-/* number of OS waits on rw-latches,
+/** number of OS waits on rw-latches,
resulted during shared (read) locks */
UNIV_INTERN ib_int64_t rw_s_os_wait_count = 0;
-/* number of unlocks (that unlock shared locks),
+/** number of unlocks (that unlock shared locks),
set only when UNIV_SYNC_PERF_STAT is defined */
UNIV_INTERN ib_int64_t rw_s_exit_count = 0;
-/* number of spin waits on rw-latches,
+/** number of spin waits on rw-latches,
resulted during exclusive (write) locks */
UNIV_INTERN ib_int64_t rw_x_spin_wait_count = 0;
+/** number of spin loop rounds on rw-latches,
+resulted during exclusive (write) locks */
UNIV_INTERN ib_int64_t rw_x_spin_round_count = 0;
-/* number of OS waits on rw-latches,
+/** number of OS waits on rw-latches,
resulted during exclusive (write) locks */
UNIV_INTERN ib_int64_t rw_x_os_wait_count = 0;
-/* number of unlocks (that unlock exclusive locks),
+/** number of unlocks (that unlock exclusive locks),
set only when UNIV_SYNC_PERF_STAT is defined */
UNIV_INTERN ib_int64_t rw_x_exit_count = 0;
@@ -174,13 +180,13 @@ UNIV_INTERN os_event_t rw_lock_debug_event;
/* This is set to TRUE, if there may be waiters for the event */
UNIV_INTERN ibool rw_lock_debug_waiters;
-/**********************************************************************
+/******************************************************************//**
Creates a debug info struct. */
static
rw_lock_debug_t*
rw_lock_debug_create(void);
/*======================*/
-/**********************************************************************
+/******************************************************************//**
Frees a debug info struct. */
static
void
@@ -188,8 +194,9 @@ rw_lock_debug_free(
/*===============*/
rw_lock_debug_t* info);
-/**********************************************************************
-Creates a debug info struct. */
+/******************************************************************//**
+Creates a debug info struct.
+@return own: debug info struct */
static
rw_lock_debug_t*
rw_lock_debug_create(void)
@@ -198,7 +205,7 @@ rw_lock_debug_create(void)
return((rw_lock_debug_t*) mem_alloc(sizeof(rw_lock_debug_t)));
}
-/**********************************************************************
+/******************************************************************//**
Frees a debug info struct. */
static
void
@@ -210,7 +217,7 @@ rw_lock_debug_free(
}
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes an rw-lock object in a specified memory
location (which must be appropriately aligned). The rw-lock is initialized
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
@@ -219,15 +226,15 @@ UNIV_INTERN
void
rw_lock_create_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to memory */
+ rw_lock_t* lock, /*!< in: pointer to memory */
#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
- ulint level, /* in: level */
+ ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
- const char* cmutex_name, /* in: mutex name */
#endif /* UNIV_DEBUG */
- const char* cfile_name, /* in: file name where created */
- ulint cline) /* in: file line where created */
+ const char* cmutex_name, /*!< in: mutex name */
+ const char* cfile_name, /*!< in: file name where created */
+ ulint cline) /*!< in: file line where created */
{
/* If this is the very first time a synchronization object is
created, then the following call initializes the sync system. */
@@ -235,17 +242,15 @@ rw_lock_create_func(
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
- lock->mutex.cfile_name = cfile_name;
- lock->mutex.cline = cline;
+ ut_d(lock->mutex.cfile_name = cfile_name);
+ ut_d(lock->mutex.cline = cline);
-# if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
lock->mutex.cmutex_name = cmutex_name;
- lock->mutex.mutex_type = 1;
-# endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-
+ ut_d(lock->mutex.mutex_type = 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
# ifdef UNIV_DEBUG
- UT_NOT_USED(cmutex_name);
+ UT_NOT_USED(cfile_name);
+ UT_NOT_USED(cline);
# endif
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
@@ -265,8 +270,7 @@ rw_lock_create_func(
lock->magic_n = RW_LOCK_MAGIC_N;
- lock->cfile_name = cfile_name;
- lock->cline = (unsigned int) cline;
+ lock->lock_name = cmutex_name;
lock->count_os_wait = 0;
lock->last_s_file_name = "not yet reserved";
@@ -288,7 +292,7 @@ rw_lock_create_func(
mutex_exit(&rw_lock_list_mutex);
}
-/**********************************************************************
+/******************************************************************//**
Calling this function is obligatory only if the memory buffer containing
the rw-lock is freed. Removes an rw-lock object from the global list. The
rw-lock is checked to be in the non-locked state. */
@@ -296,13 +300,11 @@ UNIV_INTERN
void
rw_lock_free(
/*=========*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in: rw-lock */
{
ut_ad(rw_lock_validate(lock));
ut_a(lock->lock_word == X_LOCK_DECR);
- lock->magic_n = 0;
-
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
mutex_free(rw_lock_get_mutex(lock));
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
@@ -322,17 +324,20 @@ rw_lock_free(
UT_LIST_REMOVE(list, rw_lock_list, lock);
mutex_exit(&rw_lock_list_mutex);
+
+ lock->magic_n = 0;
}
#ifdef UNIV_DEBUG
-/**********************************************************************
+/******************************************************************//**
Checks that the rw-lock has been initialized and that there are no
-simultaneous shared and exclusive locks. */
+simultaneous shared and exclusive locks.
+@return TRUE */
UNIV_INTERN
ibool
rw_lock_validate(
/*=============*/
- rw_lock_t* lock)
+ rw_lock_t* lock) /*!< in: rw-lock */
{
ut_a(lock);
@@ -347,7 +352,7 @@ rw_lock_validate(
}
#endif /* UNIV_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Lock an rw-lock in shared mode for the current thread. If the rw-lock is
locked in exclusive mode, or there is an exclusive lock request waiting,
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
@@ -356,18 +361,18 @@ UNIV_INTERN
void
rw_lock_s_lock_spin(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock
will be passed to another thread to unlock */
- const char* file_name, /* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name, /*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
ulint index; /* index of the reserved wait cell */
ulint i = 0; /* spin round count */
ut_ad(rw_lock_validate(lock));
- rw_s_spin_wait_count++; /* Count calls to this function */
+ rw_s_spin_wait_count++; /*!< Count calls to this function */
lock_loop:
/* Spin waiting for the writer field to become free */
@@ -386,10 +391,10 @@ lock_loop:
if (srv_print_latch_waits) {
fprintf(stderr,
"Thread %lu spin wait rw-s-lock at %p"
- " cfile %s cline %lu rnds %lu\n",
+ " '%s' rnds %lu\n",
(ulong) os_thread_pf(os_thread_get_curr_id()),
(void*) lock,
- lock->cfile_name, (ulong) lock->cline, (ulong) i);
+ lock->lock_name, (ulong) i);
}
/* We try once again to obtain the lock */
@@ -422,10 +427,9 @@ lock_loop:
if (srv_print_latch_waits) {
fprintf(stderr,
"Thread %lu OS wait rw-s-lock at %p"
- " cfile %s cline %lu\n",
+ " '%s'\n",
os_thread_pf(os_thread_get_curr_id()),
- (void*) lock, lock->cfile_name,
- (ulong) lock->cline);
+ (void*) lock, lock->lock_name);
}
/* these stats may not be accurate */
@@ -439,7 +443,7 @@ lock_loop:
}
}
-/**********************************************************************
+/******************************************************************//**
This function is used in the insert buffer to move the ownership of an
x-latch on a buffer frame to the current thread. The x-latch was set by
the buffer read operation and it protected the buffer frame while the
@@ -451,7 +455,7 @@ UNIV_INTERN
void
rw_lock_x_lock_move_ownership(
/*==========================*/
- rw_lock_t* lock) /* in: lock which was x-locked in the
+ rw_lock_t* lock) /*!< in: lock which was x-locked in the
buffer read */
{
ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX));
@@ -459,20 +463,20 @@ rw_lock_x_lock_move_ownership(
rw_lock_set_writer_id_and_recursion_flag(lock, TRUE);
}
-/**********************************************************************
+/******************************************************************//**
Function for the next writer to call. Waits for readers to exit.
-The caller must have already decremented lock_word by X_LOCK_DECR.*/
+The caller must have already decremented lock_word by X_LOCK_DECR. */
UNIV_INLINE
void
rw_lock_x_lock_wait(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ulint pass, /* in: pass value; != 0, if the lock will
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
#endif
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
ulint index;
ulint i = 0;
@@ -527,19 +531,18 @@ rw_lock_x_lock_wait(
rw_x_spin_round_count += i;
}
-/**********************************************************************
-Low-level function for acquiring an exclusive lock. */
+/******************************************************************//**
+Low-level function for acquiring an exclusive lock.
+@return RW_LOCK_NOT_LOCKED if did not succeed, RW_LOCK_EX if success. */
UNIV_INLINE
ibool
rw_lock_x_lock_low(
/*===============*/
- /* out: RW_LOCK_NOT_LOCKED if did
- not succeed, RW_LOCK_EX if success. */
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
os_thread_id_t curr_thread = os_thread_get_curr_id();
@@ -582,7 +585,7 @@ rw_lock_x_lock_low(
return(TRUE);
}
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread. If the rw-lock is locked
in shared or exclusive mode, or there is an exclusive lock request waiting,
@@ -595,14 +598,14 @@ UNIV_INTERN
void
rw_lock_x_lock_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
- ulint index; /* index of the reserved wait cell */
- ulint i; /* spin round count */
+ ulint index; /*!< index of the reserved wait cell */
+ ulint i; /*!< spin round count */
ibool spinning = FALSE;
ut_ad(rw_lock_validate(lock));
@@ -645,9 +648,9 @@ lock_loop:
if (srv_print_latch_waits) {
fprintf(stderr,
"Thread %lu spin wait rw-x-lock at %p"
- " cfile %s cline %lu rnds %lu\n",
+ " '%s' rnds %lu\n",
os_thread_pf(os_thread_get_curr_id()), (void*) lock,
- lock->cfile_name, (ulong) lock->cline, (ulong) i);
+ lock->lock_name, (ulong) i);
}
sync_array_reserve_cell(sync_primary_wait_array,
@@ -668,9 +671,9 @@ lock_loop:
if (srv_print_latch_waits) {
fprintf(stderr,
"Thread %lu OS wait for rw-x-lock at %p"
- " cfile %s cline %lu\n",
+ " '%s'\n",
os_thread_pf(os_thread_get_curr_id()), (void*) lock,
- lock->cfile_name, (ulong) lock->cline);
+ lock->lock_name);
}
/* these stats may not be accurate */
@@ -684,7 +687,7 @@ lock_loop:
}
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
because the debug mutex is also acquired in sync0arr while holding the OS
mutex protecting the sync array, and the ordinary mutex_enter might
@@ -713,7 +716,7 @@ loop:
goto loop;
}
-/**********************************************************************
+/******************************************************************//**
Releases the debug mutex. */
UNIV_INTERN
void
@@ -728,17 +731,17 @@ rw_lock_debug_mutex_exit(void)
}
}
-/**********************************************************************
+/******************************************************************//**
Inserts the debug information for an rw-lock. */
UNIV_INTERN
void
rw_lock_add_debug_info(
/*===================*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint pass, /* in: pass value */
- ulint lock_type, /* in: lock type */
- const char* file_name, /* in: file where requested */
- ulint line) /* in: line where requested */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint pass, /*!< in: pass value */
+ ulint lock_type, /*!< in: lock type */
+ const char* file_name, /*!< in: file where requested */
+ ulint line) /*!< in: line where requested */
{
rw_lock_debug_t* info;
@@ -764,15 +767,15 @@ rw_lock_add_debug_info(
}
}
-/**********************************************************************
+/******************************************************************//**
Removes a debug information struct for an rw-lock. */
UNIV_INTERN
void
rw_lock_remove_debug_info(
/*======================*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint pass, /* in: pass value */
- ulint lock_type) /* in: lock type */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint pass, /*!< in: pass value */
+ ulint lock_type) /*!< in: lock type */
{
rw_lock_debug_t* info;
@@ -810,16 +813,16 @@ rw_lock_remove_debug_info(
#endif /* UNIV_SYNC_DEBUG */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Checks if the thread has locked the rw-lock in the specified mode, with
-the pass value == 0. */
+the pass value == 0.
+@return TRUE if locked */
UNIV_INTERN
ibool
rw_lock_own(
/*========*/
- /* out: TRUE if locked */
- rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type) /* in: lock type: RW_LOCK_SHARED,
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
RW_LOCK_EX */
{
rw_lock_debug_t* info;
@@ -851,15 +854,15 @@ rw_lock_own(
}
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
-Checks if somebody has locked the rw-lock in the specified mode. */
+/******************************************************************//**
+Checks if somebody has locked the rw-lock in the specified mode.
+@return TRUE if locked */
UNIV_INTERN
ibool
rw_lock_is_locked(
/*==============*/
- /* out: TRUE if locked */
- rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type) /* in: lock type: RW_LOCK_SHARED,
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
RW_LOCK_EX */
{
ibool ret = FALSE;
@@ -883,13 +886,13 @@ rw_lock_is_locked(
}
#ifdef UNIV_SYNC_DEBUG
-/*******************************************************************
+/***************************************************************//**
Prints debug info of currently locked rw-locks. */
UNIV_INTERN
void
rw_lock_list_print_info(
/*====================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
rw_lock_t* lock;
ulint count = 0;
@@ -937,13 +940,13 @@ rw_lock_list_print_info(
mutex_exit(&rw_lock_list_mutex);
}
-/*******************************************************************
+/***************************************************************//**
Prints debug info of an rw-lock. */
UNIV_INTERN
void
rw_lock_print(
/*==========*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in: rw-lock */
{
rw_lock_debug_t* info;
@@ -953,7 +956,12 @@ rw_lock_print(
"RW-LATCH: %p ", (void*) lock);
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
- mutex_enter(&(lock->mutex));
+ /* We used to acquire lock->mutex here, but it would cause a
+ recursive call to sync_thread_add_level() if UNIV_SYNC_DEBUG
+ is defined. Since this function is only invoked from
+ sync_thread_levels_g(), let us choose the smaller evil:
+ performing dirty reads instead of causing bogus deadlocks or
+ assertion failures. */
#endif
if (lock->lock_word != X_LOCK_DECR) {
@@ -969,18 +977,15 @@ rw_lock_print(
info = UT_LIST_GET_NEXT(list, info);
}
}
-#ifndef INNODB_RW_LOCKS_USE_ATOMICS
- mutex_exit(&(lock->mutex));
-#endif
}
-/*************************************************************************
+/*********************************************************************//**
Prints info of a debug struct. */
UNIV_INTERN
void
rw_lock_debug_print(
/*================*/
- rw_lock_debug_t* info) /* in: debug struct */
+ rw_lock_debug_t* info) /*!< in: debug struct */
{
ulint rwt;
@@ -1004,9 +1009,10 @@ rw_lock_debug_print(
putc('\n', stderr);
}
-/*******************************************************************
+/***************************************************************//**
Returns the number of currently locked rw-locks. Works only in the debug
-version. */
+version.
+@return number of locked rw-locks */
UNIV_INTERN
ulint
rw_lock_n_locked(void)
diff --git a/storage/xtradb/sync/sync0sync.c b/storage/xtradb/sync/sync0sync.c
index 1e7f6f95580..272492cb3e4 100644
--- a/storage/xtradb/sync/sync0sync.c
+++ b/storage/xtradb/sync/sync0sync.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file sync/sync0sync.c
Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri
@@ -38,6 +39,7 @@ Created 9/5/1995 Heikki Tuuri
#include "buf0buf.h"
#include "srv0srv.h"
#include "buf0types.h"
+#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
/*
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
@@ -163,60 +165,70 @@ Q.E.D. */
/* Number of spin waits on mutexes: for performance monitoring */
-/* round=one iteration of a spin loop */
-UNIV_INTERN ib_int64_t mutex_spin_round_count = 0;
-UNIV_INTERN ib_int64_t mutex_spin_wait_count = 0;
-UNIV_INTERN ib_int64_t mutex_os_wait_count = 0;
+/** The number of iterations in the mutex_spin_wait() spin loop.
+Intended for performance monitoring. */
+static ib_int64_t mutex_spin_round_count = 0;
+/** The number of mutex_spin_wait() calls. Intended for
+performance monitoring. */
+static ib_int64_t mutex_spin_wait_count = 0;
+/** The number of OS waits in mutex_spin_wait(). Intended for
+performance monitoring. */
+static ib_int64_t mutex_os_wait_count = 0;
+/** The number of mutex_exit() calls. Intended for performance
+monitoring. */
UNIV_INTERN ib_int64_t mutex_exit_count = 0;
-/* The global array of wait cells for implementation of the database's own
+/** The global array of wait cells for implementation of the database's own
mutexes and read-write locks */
UNIV_INTERN sync_array_t* sync_primary_wait_array;
-/* This variable is set to TRUE when sync_init is called */
+/** This variable is set to TRUE when sync_init is called */
UNIV_INTERN ibool sync_initialized = FALSE;
-
+/** An acquired mutex or rw-lock and its level in the latching order */
typedef struct sync_level_struct sync_level_t;
+/** Mutexes or rw-locks held by a thread */
typedef struct sync_thread_struct sync_thread_t;
#ifdef UNIV_SYNC_DEBUG
-/* The latch levels currently owned by threads are stored in this data
+/** The latch levels currently owned by threads are stored in this data
structure; the size of this array is OS_THREAD_MAX_N */
UNIV_INTERN sync_thread_t* sync_thread_level_arrays;
-/* Mutex protecting sync_thread_level_arrays */
+/** Mutex protecting sync_thread_level_arrays */
UNIV_INTERN mutex_t sync_thread_mutex;
#endif /* UNIV_SYNC_DEBUG */
-/* Global list of database mutexes (not OS mutexes) created. */
+/** Global list of database mutexes (not OS mutexes) created. */
UNIV_INTERN ut_list_base_node_t mutex_list;
-/* Mutex protecting the mutex_list variable */
+/** Mutex protecting the mutex_list variable */
UNIV_INTERN mutex_t mutex_list_mutex;
#ifdef UNIV_SYNC_DEBUG
-/* Latching order checks start when this is set TRUE */
+/** Latching order checks start when this is set TRUE */
UNIV_INTERN ibool sync_order_checks_on = FALSE;
#endif /* UNIV_SYNC_DEBUG */
+/** Mutexes or rw-locks held by a thread */
struct sync_thread_struct{
- os_thread_id_t id; /* OS thread id */
- sync_level_t* levels; /* level array for this thread; if this is NULL
- this slot is unused */
+ os_thread_id_t id; /*!< OS thread id */
+ sync_level_t* levels; /*!< level array for this thread; if
+ this is NULL this slot is unused */
};
-/* Number of slots reserved for each OS thread in the sync level array */
+/** Number of slots reserved for each OS thread in the sync level array */
#define SYNC_THREAD_N_LEVELS 10000
+/** An acquired mutex or rw-lock and its level in the latching order */
struct sync_level_struct{
- void* latch; /* pointer to a mutex or an rw-lock; NULL means that
+ void* latch; /*!< pointer to a mutex or an rw-lock; NULL means that
the slot is empty */
- ulint level; /* level of the latch in the latching order */
+ ulint level; /*!< level of the latch in the latching order */
};
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes a mutex object in a specified memory
location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
@@ -225,26 +237,24 @@ UNIV_INTERN
void
mutex_create_func(
/*==============*/
- mutex_t* mutex, /* in: pointer to memory */
+ mutex_t* mutex, /*!< in: pointer to memory */
+ const char* cmutex_name, /*!< in: mutex name */
#ifdef UNIV_DEBUG
- const char* cmutex_name, /* in: mutex name */
# ifdef UNIV_SYNC_DEBUG
- ulint level, /* in: level */
+ ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
#endif /* UNIV_DEBUG */
- const char* cfile_name, /* in: file name where created */
- ulint cline) /* in: file line where created */
+ const char* cfile_name, /*!< in: file name where created */
+ ulint cline) /*!< in: file line where created */
{
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
- mutex_reset_lock_word(mutex);
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
+#if defined(HAVE_ATOMIC_BUILTINS)
mutex_reset_lock_word(mutex);
#else
os_fast_mutex_init(&(mutex->os_fast_mutex));
mutex->lock_word = 0;
#endif
mutex->event = os_event_create(NULL);
- mutex_set_waiters(mutex, 0);
+ mutex->waiters = 0;
#ifdef UNIV_DEBUG
mutex->magic_n = MUTEX_MAGIC_N;
#endif /* UNIV_DEBUG */
@@ -253,12 +263,13 @@ mutex_create_func(
mutex->file_name = "not yet reserved";
mutex->level = level;
#endif /* UNIV_SYNC_DEBUG */
+#ifdef UNIV_DEBUG
mutex->cfile_name = cfile_name;
mutex->cline = cline;
-#ifndef UNIV_HOTBACKUP
+#endif /* UNIV_DEBUG */
mutex->count_os_wait = 0;
-# ifdef UNIV_DEBUG
mutex->cmutex_name= cmutex_name;
+#ifdef UNIV_DEBUG
mutex->count_using= 0;
mutex->mutex_type= 0;
mutex->lspent_time= 0;
@@ -266,8 +277,7 @@ mutex_create_func(
mutex->count_spin_loop= 0;
mutex->count_spin_rounds= 0;
mutex->count_os_yield= 0;
-# endif /* UNIV_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
/* Check that lock_word is aligned; this is important on Intel */
ut_ad(((ulint)(&(mutex->lock_word))) % 4 == 0);
@@ -293,7 +303,7 @@ mutex_create_func(
mutex_exit(&mutex_list_mutex);
}
-/**********************************************************************
+/******************************************************************//**
Calling this function is obligatory only if the memory buffer containing
the mutex is freed. Removes a mutex object from the mutex list. The mutex
is checked to be in the reset state. */
@@ -301,7 +311,7 @@ UNIV_INTERN
void
mutex_free(
/*=======*/
- mutex_t* mutex) /* in: mutex */
+ mutex_t* mutex) /*!< in: mutex */
{
ut_ad(mutex_validate(mutex));
ut_a(mutex_get_lock_word(mutex) == 0);
@@ -329,9 +339,7 @@ mutex_free(
os_event_free(mutex->event);
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
-#else
+#if !defined(HAVE_ATOMIC_BUILTINS)
os_fast_mutex_free(&(mutex->os_fast_mutex));
#endif
/* If we free the mutex protecting the mutex list (freeing is
@@ -342,21 +350,21 @@ mutex_free(
#endif /* UNIV_DEBUG */
}
-/************************************************************************
+/********************************************************************//**
NOTE! Use the corresponding macro in the header file, not this function
directly. Tries to lock the mutex for the current thread. If the lock is not
-acquired immediately, returns with return value 1. */
+acquired immediately, returns with return value 1.
+@return 0 if succeed, 1 if not */
UNIV_INTERN
ulint
mutex_enter_nowait_func(
/*====================*/
- /* out: 0 if succeed, 1 if not */
- mutex_t* mutex, /* in: pointer to mutex */
+ mutex_t* mutex, /*!< in: pointer to mutex */
const char* file_name __attribute__((unused)),
- /* in: file name where mutex
+ /*!< in: file name where mutex
requested */
ulint line __attribute__((unused)))
- /* in: line where requested */
+ /*!< in: line where requested */
{
ut_ad(mutex_validate(mutex));
@@ -374,13 +382,14 @@ mutex_enter_nowait_func(
}
#ifdef UNIV_DEBUG
-/**********************************************************************
-Checks that the mutex has been initialized. */
+/******************************************************************//**
+Checks that the mutex has been initialized.
+@return TRUE */
UNIV_INTERN
ibool
mutex_validate(
/*===========*/
- const mutex_t* mutex)
+ const mutex_t* mutex) /*!< in: mutex */
{
ut_a(mutex);
ut_a(mutex->magic_n == MUTEX_MAGIC_N);
@@ -388,15 +397,15 @@ mutex_validate(
return(TRUE);
}
-/**********************************************************************
+/******************************************************************//**
Checks that the current thread owns the mutex. Works only in the debug
-version. */
+version.
+@return TRUE if owns */
UNIV_INTERN
ibool
mutex_own(
/*======*/
- /* out: TRUE if owns */
- const mutex_t* mutex) /* in: mutex */
+ const mutex_t* mutex) /*!< in: mutex */
{
ut_ad(mutex_validate(mutex));
@@ -405,26 +414,34 @@ mutex_own(
}
#endif /* UNIV_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Sets the waiters field in a mutex. */
UNIV_INTERN
void
mutex_set_waiters(
/*==============*/
- mutex_t* mutex, /* in: mutex */
- ulint n) /* in: value to set */
+ mutex_t* mutex, /*!< in: mutex */
+ ulint n) /*!< in: value to set */
{
volatile ulint* ptr; /* declared volatile to ensure that
the value is stored to memory */
ut_ad(mutex);
+#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+ if (n) {
+ os_compare_and_swap_ulint(&mutex->waiters, 0, 1);
+ } else {
+ os_compare_and_swap_ulint(&mutex->waiters, 1, 0);
+ }
+#else
ptr = &(mutex->waiters);
*ptr = n; /* Here we assume that the write of a single
word in memory is atomic */
+#endif
}
-/**********************************************************************
+/******************************************************************//**
Reserves a mutex for the current thread. If the mutex is reserved, the
function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
for the mutex before suspending the thread. */
@@ -432,20 +449,20 @@ UNIV_INTERN
void
mutex_spin_wait(
/*============*/
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where mutex
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where mutex
requested */
- ulint line) /* in: line where requested */
+ ulint line) /*!< in: line where requested */
{
ulint index; /* index of the reserved wait cell */
ulint i; /* spin round count */
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
+#ifdef UNIV_DEBUG
ib_int64_t lstart_time = 0, lfinish_time; /* for timing os_wait */
ulint ltime_diff;
ulint sec;
ulint ms;
uint timer_started = 0;
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
ut_ad(mutex);
/* This update is not thread safe, but we don't mind if the count
@@ -465,9 +482,7 @@ mutex_loop:
a memory word. */
spin_loop:
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
- mutex->count_spin_loop++;
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+ ut_d(mutex->count_spin_loop++);
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
if (srv_spin_wait_delay) {
@@ -478,30 +493,30 @@ spin_loop:
}
if (i == SYNC_SPIN_ROUNDS) {
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
+#ifdef UNIV_DEBUG
mutex->count_os_yield++;
- if (timed_mutexes == 1 && timer_started==0) {
+#ifndef UNIV_HOTBACKUP
+ if (timed_mutexes && timer_started == 0) {
ut_usectime(&sec, &ms);
lstart_time= (ib_int64_t)sec * 1000000 + ms;
timer_started = 1;
}
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+#endif /* UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
os_thread_yield();
}
#ifdef UNIV_SRV_PRINT_LATCH_WAITS
fprintf(stderr,
"Thread %lu spin wait mutex at %p"
- " cfile %s cline %lu rnds %lu\n",
+ " '%s' rnds %lu\n",
(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
- mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
+ mutex->cmutex_name, (ulong) i);
#endif
mutex_spin_round_count += i;
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
- mutex->count_spin_rounds += i;
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+ ut_d(mutex->count_spin_rounds += i);
if (mutex_test_and_set(mutex) == 0) {
/* Succeeded! */
@@ -571,31 +586,30 @@ spin_loop:
#ifdef UNIV_SRV_PRINT_LATCH_WAITS
fprintf(stderr,
- "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n",
+ "Thread %lu OS wait mutex at %p '%s' rnds %lu\n",
(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
- mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
+ mutex->cmutex_name, (ulong) i);
#endif
mutex_os_wait_count++;
-#ifndef UNIV_HOTBACKUP
mutex->count_os_wait++;
-# ifdef UNIV_DEBUG
+#ifdef UNIV_DEBUG
/* !!!!! Sometimes os_wait can be called without os_thread_yield */
-
- if (timed_mutexes == 1 && timer_started==0) {
+#ifndef UNIV_HOTBACKUP
+ if (timed_mutexes == 1 && timer_started == 0) {
ut_usectime(&sec, &ms);
lstart_time= (ib_int64_t)sec * 1000000 + ms;
timer_started = 1;
}
-# endif /* UNIV_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
sync_array_wait_event(sync_primary_wait_array, index);
goto mutex_loop;
finish_timing:
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
+#ifdef UNIV_DEBUG
if (timed_mutexes == 1 && timer_started==1) {
ut_usectime(&sec, &ms);
lfinish_time= (ib_int64_t)sec * 1000000 + ms;
@@ -607,17 +621,17 @@ finish_timing:
mutex->lmax_spent_time= ltime_diff;
}
}
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
return;
}
-/**********************************************************************
+/******************************************************************//**
Releases the threads waiting in the primary wait array for this mutex. */
UNIV_INTERN
void
mutex_signal_object(
/*================*/
- mutex_t* mutex) /* in: mutex */
+ mutex_t* mutex) /*!< in: mutex */
{
mutex_set_waiters(mutex, 0);
@@ -628,15 +642,15 @@ mutex_signal_object(
}
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Sets the debug information for a reserved mutex. */
UNIV_INTERN
void
mutex_set_debug_info(
/*=================*/
- mutex_t* mutex, /* in: mutex */
- const char* file_name, /* in: file where requested */
- ulint line) /* in: line where requested */
+ mutex_t* mutex, /*!< in: mutex */
+ const char* file_name, /*!< in: file where requested */
+ ulint line) /*!< in: line where requested */
{
ut_ad(mutex);
ut_ad(file_name);
@@ -647,16 +661,16 @@ mutex_set_debug_info(
mutex->line = line;
}
-/**********************************************************************
+/******************************************************************//**
Gets the debug information for a reserved mutex. */
UNIV_INTERN
void
mutex_get_debug_info(
/*=================*/
- mutex_t* mutex, /* in: mutex */
- const char** file_name, /* out: file where requested */
- ulint* line, /* out: line where requested */
- os_thread_id_t* thread_id) /* out: id of the thread which owns
+ mutex_t* mutex, /*!< in: mutex */
+ const char** file_name, /*!< out: file where requested */
+ ulint* line, /*!< out: line where requested */
+ os_thread_id_t* thread_id) /*!< out: id of the thread which owns
the mutex */
{
ut_ad(mutex);
@@ -666,13 +680,13 @@ mutex_get_debug_info(
*thread_id = mutex->thread_id;
}
-/**********************************************************************
+/******************************************************************//**
Prints debug info of currently reserved mutexes. */
static
void
mutex_list_print_info(
/*==================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
mutex_t* mutex;
const char* file_name;
@@ -709,8 +723,9 @@ mutex_list_print_info(
mutex_exit(&mutex_list_mutex);
}
-/**********************************************************************
-Counts currently reserved mutexes. Works only in the debug version. */
+/******************************************************************//**
+Counts currently reserved mutexes. Works only in the debug version.
+@return number of reserved mutexes */
UNIV_INTERN
ulint
mutex_n_reserved(void)
@@ -740,9 +755,10 @@ mutex_n_reserved(void)
was holding one mutex (mutex_list_mutex) */
}
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if no mutex or rw-lock is currently locked. Works only in
-the debug version. */
+the debug version.
+@return TRUE if no mutexes and rw-locks reserved */
UNIV_INTERN
ibool
sync_all_freed(void)
@@ -751,27 +767,27 @@ sync_all_freed(void)
return(mutex_n_reserved() + rw_lock_n_locked() == 0);
}
-/**********************************************************************
-Gets the value in the nth slot in the thread level arrays. */
+/******************************************************************//**
+Gets the value in the nth slot in the thread level arrays.
+@return pointer to thread slot */
static
sync_thread_t*
sync_thread_level_arrays_get_nth(
/*=============================*/
- /* out: pointer to thread slot */
- ulint n) /* in: slot number */
+ ulint n) /*!< in: slot number */
{
ut_ad(n < OS_THREAD_MAX_N);
return(sync_thread_level_arrays + n);
}
-/**********************************************************************
-Looks for the thread slot for the calling thread. */
+/******************************************************************//**
+Looks for the thread slot for the calling thread.
+@return pointer to thread slot, NULL if not found */
static
sync_thread_t*
sync_thread_level_arrays_find_slot(void)
/*====================================*/
- /* out: pointer to thread slot, NULL if not found */
{
sync_thread_t* slot;
@@ -793,13 +809,13 @@ sync_thread_level_arrays_find_slot(void)
return(NULL);
}
-/**********************************************************************
-Looks for an unused thread slot. */
+/******************************************************************//**
+Looks for an unused thread slot.
+@return pointer to thread slot */
static
sync_thread_t*
sync_thread_level_arrays_find_free(void)
/*====================================*/
- /* out: pointer to thread slot */
{
sync_thread_t* slot;
@@ -818,33 +834,34 @@ sync_thread_level_arrays_find_free(void)
return(NULL);
}
-/**********************************************************************
-Gets the value in the nth slot in the thread level array. */
+/******************************************************************//**
+Gets the value in the nth slot in the thread level array.
+@return pointer to level slot */
static
sync_level_t*
sync_thread_levels_get_nth(
/*=======================*/
- /* out: pointer to level slot */
- sync_level_t* arr, /* in: pointer to level array for an OS
+ sync_level_t* arr, /*!< in: pointer to level array for an OS
thread */
- ulint n) /* in: slot number */
+ ulint n) /*!< in: slot number */
{
ut_ad(n < SYNC_THREAD_N_LEVELS);
return(arr + n);
}
-/**********************************************************************
+/******************************************************************//**
Checks if all the level values stored in the level array are greater than
-the given limit. */
+the given limit.
+@return TRUE if all greater */
static
ibool
sync_thread_levels_g(
/*=================*/
- /* out: TRUE if all greater */
- sync_level_t* arr, /* in: pointer to level array for an OS
+ sync_level_t* arr, /*!< in: pointer to level array for an OS
thread */
- ulint limit) /* in: level limit */
+ ulint limit, /*!< in: level limit */
+ ulint warn) /*!< in: TRUE=display a diagnostic message */
{
sync_level_t* slot;
rw_lock_t* lock;
@@ -858,6 +875,11 @@ sync_thread_levels_g(
if (slot->latch != NULL) {
if (slot->level <= limit) {
+ if (!warn) {
+
+ return(FALSE);
+ }
+
lock = slot->latch;
mutex = slot->latch;
@@ -868,9 +890,8 @@ sync_thread_levels_g(
if (mutex->magic_n == MUTEX_MAGIC_N) {
fprintf(stderr,
- "Mutex created at %s %lu\n",
- mutex->cfile_name,
- (ulong) mutex->cline);
+ "Mutex '%s'\n",
+ mutex->cmutex_name);
if (mutex_get_lock_word(mutex) != 0) {
const char* file_name;
@@ -905,16 +926,16 @@ sync_thread_levels_g(
return(TRUE);
}
-/**********************************************************************
-Checks if the level value is stored in the level array. */
+/******************************************************************//**
+Checks if the level value is stored in the level array.
+@return TRUE if stored */
static
ibool
sync_thread_levels_contain(
/*=======================*/
- /* out: TRUE if stored */
- sync_level_t* arr, /* in: pointer to level array for an OS
+ sync_level_t* arr, /*!< in: pointer to level array for an OS
thread */
- ulint level) /* in: level */
+ ulint level) /*!< in: level */
{
sync_level_t* slot;
ulint i;
@@ -934,15 +955,14 @@ sync_thread_levels_contain(
return(FALSE);
}
-/**********************************************************************
-Checks that the level array for the current thread is empty. */
+/******************************************************************//**
+Checks that the level array for the current thread is empty.
+@return TRUE if empty except the exceptions specified below */
UNIV_INTERN
ibool
sync_thread_levels_empty_gen(
/*=========================*/
- /* out: TRUE if empty except the
- exceptions specified below */
- ibool dict_mutex_allowed) /* in: TRUE if dictionary mutex is
+ ibool dict_mutex_allowed) /*!< in: TRUE if dictionary mutex is
allowed to be owned by the thread,
also purge_is_running mutex is
allowed */
@@ -991,18 +1011,18 @@ sync_thread_levels_empty_gen(
return(TRUE);
}
-/**********************************************************************
-Checks that the level array for the current thread is empty. */
+/******************************************************************//**
+Checks that the level array for the current thread is empty.
+@return TRUE if empty */
UNIV_INTERN
ibool
sync_thread_levels_empty(void)
/*==========================*/
- /* out: TRUE if empty */
{
return(sync_thread_levels_empty_gen(FALSE));
}
-/**********************************************************************
+/******************************************************************//**
Adds a latch and its level in the thread level array. Allocates the memory
for the array if called first time for this OS thread. Makes the checks
against other latch levels stored in the array for this thread. */
@@ -1010,8 +1030,8 @@ UNIV_INTERN
void
sync_thread_add_level(
/*==================*/
- void* latch, /* in: pointer to a mutex or an rw-lock */
- ulint level) /* in: level in the latching order; if
+ void* latch, /*!< in: pointer to a mutex or an rw-lock */
+ ulint level) /*!< in: level in the latching order; if
SYNC_LEVEL_VARYING, nothing is done */
{
sync_level_t* array;
@@ -1102,7 +1122,7 @@ sync_thread_add_level(
case SYNC_DICT_HEADER:
case SYNC_TRX_I_S_RWLOCK:
case SYNC_TRX_I_S_LAST_READ:
- if (!sync_thread_levels_g(array, level)) {
+ if (!sync_thread_levels_g(array, level, TRUE)) {
fprintf(stderr,
"InnoDB: sync_thread_levels_g(array, %lu)"
" does not hold!\n", level);
@@ -1113,35 +1133,44 @@ sync_thread_add_level(
/* Either the thread must own the buffer pool mutex
(buf_pool_mutex), or it is allowed to latch only ONE
buffer block (block->mutex or buf_pool_zip_mutex). */
- ut_a((sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST)
- && sync_thread_levels_g(array, SYNC_BUF_BLOCK - 1))
- || sync_thread_levels_g(array, SYNC_BUF_BLOCK));
+ if (!sync_thread_levels_g(array, level, FALSE)) {
+ ut_a(sync_thread_levels_g(array, level - 1, TRUE));
+ ut_a(sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST));
+ }
break;
case SYNC_REC_LOCK:
- ut_a((sync_thread_levels_contain(array, SYNC_KERNEL)
- && sync_thread_levels_g(array, SYNC_REC_LOCK - 1))
- || sync_thread_levels_g(array, SYNC_REC_LOCK));
+ if (sync_thread_levels_contain(array, SYNC_KERNEL)) {
+ ut_a(sync_thread_levels_g(array, SYNC_REC_LOCK - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_REC_LOCK, TRUE));
+ }
break;
case SYNC_IBUF_BITMAP:
/* Either the thread must own the master mutex to all
the bitmap pages, or it is allowed to latch only ONE
bitmap page. */
- ut_a((sync_thread_levels_contain(array, SYNC_IBUF_BITMAP_MUTEX)
- && sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1))
- || sync_thread_levels_g(array, SYNC_IBUF_BITMAP));
+ if (sync_thread_levels_contain(array,
+ SYNC_IBUF_BITMAP_MUTEX)) {
+ ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP,
+ TRUE));
+ }
break;
case SYNC_FSP_PAGE:
ut_a(sync_thread_levels_contain(array, SYNC_FSP));
break;
case SYNC_FSP:
ut_a(sync_thread_levels_contain(array, SYNC_FSP)
- || sync_thread_levels_g(array, SYNC_FSP));
+ || sync_thread_levels_g(array, SYNC_FSP, TRUE));
break;
case SYNC_TRX_UNDO_PAGE:
ut_a(sync_thread_levels_contain(array, SYNC_TRX_UNDO)
|| sync_thread_levels_contain(array, SYNC_RSEG)
|| sync_thread_levels_contain(array, SYNC_PURGE_SYS)
- || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE));
+ || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE, TRUE));
break;
case SYNC_RSEG_HEADER:
ut_a(sync_thread_levels_contain(array, SYNC_RSEG));
@@ -1153,37 +1182,41 @@ sync_thread_add_level(
case SYNC_TREE_NODE:
ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE)
|| sync_thread_levels_contain(array, SYNC_DICT_OPERATION)
- || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
+ || sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE));
break;
case SYNC_TREE_NODE_NEW:
ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE)
|| sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
break;
case SYNC_INDEX_TREE:
- ut_a((sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
- && sync_thread_levels_contain(array, SYNC_FSP)
- && sync_thread_levels_g(array, SYNC_FSP_PAGE - 1))
- || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
+ if (sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
+ && sync_thread_levels_contain(array, SYNC_FSP)) {
+ ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1,
+ TRUE));
+ }
break;
case SYNC_IBUF_MUTEX:
- ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1, TRUE));
break;
case SYNC_IBUF_PESS_INSERT_MUTEX:
- ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
- && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
+ ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
break;
case SYNC_IBUF_HEADER:
- ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
- && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
- && !sync_thread_levels_contain(
- array, SYNC_IBUF_PESS_INSERT_MUTEX));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
+ ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+ ut_a(!sync_thread_levels_contain(array,
+ SYNC_IBUF_PESS_INSERT_MUTEX));
break;
case SYNC_DICT:
#ifdef UNIV_DEBUG
ut_a(buf_debug_prints
- || sync_thread_levels_g(array, SYNC_DICT));
+ || sync_thread_levels_g(array, SYNC_DICT, TRUE));
#else /* UNIV_DEBUG */
- ut_a(sync_thread_levels_g(array, SYNC_DICT));
+ ut_a(sync_thread_levels_g(array, SYNC_DICT, TRUE));
#endif /* UNIV_DEBUG */
break;
default:
@@ -1207,15 +1240,16 @@ sync_thread_add_level(
mutex_exit(&sync_thread_mutex);
}
-/**********************************************************************
-Removes a latch from the thread level array if it is found there. */
+/******************************************************************//**
+Removes a latch from the thread level array if it is found there.
+@return TRUE if found in the array; it is no error if the latch is
+not found, as we presently are not able to determine the level for
+every latch reservation the program does */
UNIV_INTERN
ibool
sync_thread_reset_level(
/*====================*/
- /* out: TRUE if found from the array; it is an error
- if the latch is not found */
- void* latch) /* in: pointer to a mutex or an rw-lock */
+ void* latch) /*!< in: pointer to a mutex or an rw-lock */
{
sync_level_t* array;
sync_level_t* slot;
@@ -1282,7 +1316,7 @@ sync_thread_reset_level(
}
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Initializes the synchronization data structures. */
UNIV_INTERN
void
@@ -1336,7 +1370,7 @@ sync_init(void)
#endif /* UNIV_SYNC_DEBUG */
}
-/**********************************************************************
+/******************************************************************//**
Frees the resources in InnoDB's own synchronization data structures. Use
os_sync_free() after calling this. */
UNIV_INTERN
@@ -1358,16 +1392,21 @@ sync_close(void)
mutex_free(&mutex_list_mutex);
#ifdef UNIV_SYNC_DEBUG
mutex_free(&sync_thread_mutex);
+
+ /* Switch latching order checks on in sync0sync.c */
+ sync_order_checks_on = FALSE;
#endif /* UNIV_SYNC_DEBUG */
+
+ sync_initialized = FALSE;
}
-/***********************************************************************
+/*******************************************************************//**
Prints wait info of the sync system. */
UNIV_INTERN
void
sync_print_wait_info(
/*=================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
#ifdef UNIV_SYNC_DEBUG
fprintf(file, "Mutex exits %llu, rws exits %llu, rwx exits %llu\n",
@@ -1397,13 +1436,13 @@ sync_print_wait_info(
(rw_x_spin_wait_count ? rw_x_spin_wait_count : 1));
}
-/***********************************************************************
+/*******************************************************************//**
Prints info of the sync system. */
UNIV_INTERN
void
sync_print(
/*=======*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
#ifdef UNIV_SYNC_DEBUG
mutex_list_print_info(file);
diff --git a/storage/xtradb/thr/thr0loc.c b/storage/xtradb/thr/thr0loc.c
index aea1992a921..5b9e83be920 100644
--- a/storage/xtradb/thr/thr0loc.c
+++ b/storage/xtradb/thr/thr0loc.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file thr/thr0loc.c
The thread local storage
Created 10/5/1995 Heikki Tuuri
@@ -43,39 +44,42 @@ is protected by a mutex. If you need modify the program and put new data to
the thread local storage, just add it to struct thr_local_struct in the
header file. */
-/* Mutex protecting the local storage hash table */
+/** Mutex protecting thr_local_hash */
static mutex_t thr_local_mutex;
-/* The hash table. The module is not yet initialized when it is NULL. */
+/** The hash table. The module is not yet initialized when it is NULL. */
static hash_table_t* thr_local_hash = NULL;
ulint thr_local_hash_n_nodes = 0;
-/* The private data for each thread should be put to
-the structure below and the accessor functions written
-for the field. */
+/** Thread local data */
typedef struct thr_local_struct thr_local_t;
+/** @brief Thread local data.
+The private data for each thread should be put to
+the structure below and the accessor functions written
+for the field. */
struct thr_local_struct{
- os_thread_id_t id; /* id of the thread which owns this struct */
- os_thread_t handle; /* operating system handle to the thread */
- ulint slot_no;/* the index of the slot in the thread table
+ os_thread_id_t id; /*!< id of the thread which owns this struct */
+ os_thread_t handle; /*!< operating system handle to the thread */
+ ulint slot_no;/*!< the index of the slot in the thread table
for this thread */
- ibool in_ibuf;/* TRUE if the the thread is doing an ibuf
+ ibool in_ibuf;/*!< TRUE if the thread is doing an ibuf
operation */
- hash_node_t hash; /* hash chain node */
- ulint magic_n;
+ hash_node_t hash; /*!< hash chain node */
+ ulint magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
};
+/** The value of thr_local_struct::magic_n */
#define THR_LOCAL_MAGIC_N 1231234
-/***********************************************************************
-Returns the local storage struct for a thread. */
+/*******************************************************************//**
+Returns the local storage struct for a thread.
+@return local storage */
static
thr_local_t*
thr_local_get(
/*==========*/
- /* out: local storage */
- os_thread_id_t id) /* in: thread id of the thread */
+ os_thread_id_t id) /*!< in: thread id of the thread */
{
thr_local_t* local;
@@ -104,14 +108,14 @@ try_again:
return(local);
}
-/***********************************************************************
-Gets the slot number in the thread table of a thread. */
+/*******************************************************************//**
+Gets the slot number in the thread table of a thread.
+@return slot number */
UNIV_INTERN
ulint
thr_local_get_slot_no(
/*==================*/
- /* out: slot number */
- os_thread_id_t id) /* in: thread id of the thread */
+ os_thread_id_t id) /*!< in: thread id of the thread */
{
ulint slot_no;
thr_local_t* local;
@@ -127,14 +131,14 @@ thr_local_get_slot_no(
return(slot_no);
}
-/***********************************************************************
+/*******************************************************************//**
Sets the slot number in the thread table of a thread. */
UNIV_INTERN
void
thr_local_set_slot_no(
/*==================*/
- os_thread_id_t id, /* in: thread id of the thread */
- ulint slot_no)/* in: slot number */
+ os_thread_id_t id, /*!< in: thread id of the thread */
+ ulint slot_no)/*!< in: slot number */
{
thr_local_t* local;
@@ -147,14 +151,14 @@ thr_local_set_slot_no(
mutex_exit(&thr_local_mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Returns pointer to the 'in_ibuf' field within the current thread local
-storage. */
+storage.
+@return pointer to the in_ibuf field */
UNIV_INTERN
ibool*
thr_local_get_in_ibuf_field(void)
/*=============================*/
- /* out: pointer to the in_ibuf field */
{
thr_local_t* local;
@@ -167,7 +171,7 @@ thr_local_get_in_ibuf_field(void)
return(&(local->in_ibuf));
}
-/***********************************************************************
+/*******************************************************************//**
Creates a local storage struct for the calling new thread. */
UNIV_INTERN
void
@@ -198,13 +202,13 @@ thr_local_create(void)
mutex_exit(&thr_local_mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Frees the local storage struct for the specified thread. */
UNIV_INTERN
void
thr_local_free(
/*===========*/
- os_thread_id_t id) /* in: thread id */
+ os_thread_id_t id) /*!< in: thread id */
{
thr_local_t* local;
@@ -231,7 +235,7 @@ thr_local_free(
mem_free(local);
}
-/********************************************************************
+/****************************************************************//**
Initializes the thread local storage module. */
UNIV_INTERN
void
@@ -246,6 +250,37 @@ thr_local_init(void)
mutex_create(&thr_local_mutex, SYNC_THR_LOCAL);
}
+/********************************************************************
+Close the thread local storage module. */
+UNIV_INTERN
+void
+thr_local_close(void)
+/*=================*/
+{
+ ulint i;
+
+ ut_a(thr_local_hash != NULL);
+
+ /* Free the hash elements. We don't remove them from the table
+ because we are going to destroy the table anyway. */
+ for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) {
+ thr_local_t* local;
+
+ local = HASH_GET_FIRST(thr_local_hash, i);
+
+ while (local) {
+ thr_local_t* prev_local = local;
+
+ local = HASH_GET_NEXT(hash, prev_local);
+ ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N);
+ mem_free(prev_local);
+ }
+ }
+
+ hash_table_free(thr_local_hash);
+ thr_local_hash = NULL;
+}
+
/*************************************************************************
Return local hash table informations. */
diff --git a/storage/xtradb/trx/trx0i_s.c b/storage/xtradb/trx/trx0i_s.c
index 512e38cc17e..e7646c99227 100644
--- a/storage/xtradb/trx/trx0i_s.c
+++ b/storage/xtradb/trx/trx0i_s.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0i_s.c
INFORMATION SCHEMA innodb_trx, innodb_locks and
innodb_lock_waits tables fetch code.
@@ -27,11 +28,11 @@ table cache" for later retrieval.
Created July 17, 2007 Vasil Dimov
*******************************************************/
-#include <mysql/plugin.h>
#include "mysql_addons.h"
#include "univ.i"
+#include <mysql/plugin.h>
#include "buf0buf.h"
#include "dict0dict.h"
#include "ha0storage.h"
@@ -53,22 +54,25 @@ Created July 17, 2007 Vasil Dimov
#include "ut0mem.h"
#include "ut0ut.h"
+/** Initial number of rows in the table cache */
#define TABLE_CACHE_INITIAL_ROWSNUM 1024
-/* Table cache's rows are stored in a set of chunks. When a new row is
-added a new chunk is allocated if necessary. MEM_CHUNKS_IN_TABLE_CACHE
-specifies the maximum number of chunks.
-Assuming that the first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM)
-and each subsequent is N/2 where N is the number of rows we have
-allocated till now, then 39th chunk would have 1677416425 number of rows
-and all chunks would have 3354832851 number of rows. */
+/** @brief The maximum number of chunks to allocate for a table cache.
+
+The rows of a table cache are stored in a set of chunks. When a new
+row is added a new chunk is allocated if necessary. Assuming that the
+first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM) and each
+subsequent is N/2 where N is the number of rows we have allocated till
+now, then 39th chunk would accommodate 1677416425 rows and all chunks
+would accommodate 3354832851 rows. */
#define MEM_CHUNKS_IN_TABLE_CACHE 39
-/* The following are some testing auxiliary macros. Do not enable them
+/** The following are some testing auxiliary macros. Do not enable them
in a production environment. */
+/* @{ */
#if 0
-/* If this is enabled then lock folds will always be different
+/** If this is enabled then lock folds will always be different
resulting in equal rows being put in a different cells of the hash
table. Checking for duplicates will be flawed because different
fold will be calculated when a row is searched in the hash table. */
@@ -76,7 +80,7 @@ fold will be calculated when a row is searched in the hash table. */
#endif
#if 0
-/* This effectively kills the search-for-duplicate-before-adding-a-row
+/** This effectively kills the search-for-duplicate-before-adding-a-row
function, but searching in the hash is still performed. It will always
be assumed that lock is not present and insertion will be performed in
the hash table. */
@@ -84,101 +88,113 @@ the hash table. */
#endif
#if 0
-/* This aggressively repeats adding each row many times. Depending on
+/** This aggressively repeats adding each row many times. Depending on
the above settings this may be noop or may result in lots of rows being
added. */
#define TEST_ADD_EACH_LOCKS_ROW_MANY_TIMES
#endif
#if 0
-/* Very similar to TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T but hash
+/** Very similar to TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T but hash
table search is not performed at all. */
#define TEST_DO_NOT_CHECK_FOR_DUPLICATE_ROWS
#endif
#if 0
-/* Do not insert each row into the hash table, duplicates may appear
+/** Do not insert each row into the hash table, duplicates may appear
if this is enabled, also if this is enabled searching into the hash is
noop because it will be empty. */
#define TEST_DO_NOT_INSERT_INTO_THE_HASH_TABLE
#endif
+/* @} */
+/** Memory limit passed to ha_storage_put_memlim().
+@param cache hash storage
+@return maximum allowed allocation size */
#define MAX_ALLOWED_FOR_STORAGE(cache) \
(TRX_I_S_MEM_LIMIT \
- (cache)->mem_allocd)
+/** Memory limit in table_cache_create_empty_row().
+@param cache hash storage
+@return maximum allowed allocation size */
#define MAX_ALLOWED_FOR_ALLOC(cache) \
(TRX_I_S_MEM_LIMIT \
- (cache)->mem_allocd \
- ha_storage_get_size((cache)->storage))
-/* Memory for each table in the intermediate buffer is allocated in
+/** Memory for each table in the intermediate buffer is allocated in
separate chunks. These chunks are considered to be concatenated to
represent one flat array of rows. */
typedef struct i_s_mem_chunk_struct {
- ulint offset; /* offset, in number of rows */
- ulint rows_allocd; /* the size of this chunk, in number
+ ulint offset; /*!< offset, in number of rows */
+ ulint rows_allocd; /*!< the size of this chunk, in number
of rows */
- void* base; /* start of the chunk */
+ void* base; /*!< start of the chunk */
} i_s_mem_chunk_t;
-/* This represents one table's cache. */
+/** This represents one table's cache. */
typedef struct i_s_table_cache_struct {
- ulint rows_used; /* number of used rows */
- ulint rows_allocd; /* number of allocated rows */
- ulint row_size; /* size of a single row */
- i_s_mem_chunk_t chunks[MEM_CHUNKS_IN_TABLE_CACHE]; /* array of
+ ulint rows_used; /*!< number of used rows */
+ ulint rows_allocd; /*!< number of allocated rows */
+ ulint row_size; /*!< size of a single row */
+ i_s_mem_chunk_t chunks[MEM_CHUNKS_IN_TABLE_CACHE]; /*!< array of
memory chunks that stores the
rows */
} i_s_table_cache_t;
-/* This structure describes the intermediate buffer */
+/** This structure describes the intermediate buffer */
struct trx_i_s_cache_struct {
- rw_lock_t rw_lock; /* read-write lock protecting
+ rw_lock_t rw_lock; /*!< read-write lock protecting
the rest of this structure */
- ullint last_read; /* last time the cache was read;
+ ullint last_read; /*!< last time the cache was read;
measured in microseconds since
epoch */
- mutex_t last_read_mutex;/* mutex protecting the
+ mutex_t last_read_mutex;/*!< mutex protecting the
last_read member - it is updated
inside a shared lock of the
rw_lock member */
- i_s_table_cache_t innodb_trx; /* innodb_trx table */
- i_s_table_cache_t innodb_locks; /* innodb_locks table */
- i_s_table_cache_t innodb_lock_waits;/* innodb_lock_waits table */
-/* the hash table size is LOCKS_HASH_CELLS_NUM * sizeof(void*) bytes */
+ i_s_table_cache_t innodb_trx; /*!< innodb_trx table */
+ i_s_table_cache_t innodb_locks; /*!< innodb_locks table */
+ i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */
+/** the hash table size is LOCKS_HASH_CELLS_NUM * sizeof(void*) bytes */
#define LOCKS_HASH_CELLS_NUM 10000
- hash_table_t* locks_hash; /* hash table used to eliminate
+ hash_table_t* locks_hash; /*!< hash table used to eliminate
duplicate entries in the
innodb_locks table */
+/** Initial size of the cache storage */
#define CACHE_STORAGE_INITIAL_SIZE 1024
+/** Number of hash cells in the cache storage */
#define CACHE_STORAGE_HASH_CELLS 2048
- ha_storage_t* storage; /* storage for external volatile
+ ha_storage_t* storage; /*!< storage for external volatile
data that can possibly not be
available later, when we release
the kernel mutex */
- ulint mem_allocd; /* the amount of memory
+ ulint mem_allocd; /*!< the amount of memory
allocated with mem_alloc*() */
- ibool is_truncated; /* this is TRUE if the memory
+ ibool is_truncated; /*!< this is TRUE if the memory
limit was hit and thus the data
in the cache is truncated */
};
-/* This is the intermediate buffer where data needed to fill the
+/** This is the intermediate buffer where data needed to fill the
INFORMATION SCHEMA tables is fetched and later retrieved by the C++
code in handler/i_s.cc. */
static trx_i_s_cache_t trx_i_s_cache_static;
+/** This is the intermediate buffer where data needed to fill the
+INFORMATION SCHEMA tables is fetched and later retrieved by the C++
+code in handler/i_s.cc. */
UNIV_INTERN trx_i_s_cache_t* trx_i_s_cache = &trx_i_s_cache_static;
-/***********************************************************************
+/*******************************************************************//**
For a record lock that is in waiting state retrieves the only bit that
-is set, for a table lock returns ULINT_UNDEFINED. */
+is set, for a table lock returns ULINT_UNDEFINED.
+@return record number within the heap */
static
ulint
wait_lock_get_heap_no(
/*==================*/
- /* out: record number within the heap */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ulint ret;
@@ -197,14 +213,14 @@ wait_lock_get_heap_no(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Initializes the members of a table cache. */
static
void
table_cache_init(
/*=============*/
- i_s_table_cache_t* table_cache, /* out: table cache */
- size_t row_size) /* in: the size of a
+ i_s_table_cache_t* table_cache, /*!< out: table cache */
+ size_t row_size) /*!< in: the size of a
row */
{
ulint i;
@@ -221,19 +237,39 @@ table_cache_init(
}
}
-/***********************************************************************
+/*******************************************************************//**
+Frees a table cache. */
+static
+void
+table_cache_free(
+/*=============*/
+ i_s_table_cache_t* table_cache) /*!< in/out: table cache */
+{
+ ulint i;
+
+ for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) {
+
+ /* the memory is actually allocated in
+ table_cache_create_empty_row() */
+ if (table_cache->chunks[i].base) {
+ mem_free(table_cache->chunks[i].base);
+ table_cache->chunks[i].base = NULL;
+ }
+ }
+}
+
+/*******************************************************************//**
Returns an empty row from a table cache. The row is allocated if no more
empty rows are available. The number of used rows is incremented.
If the memory limit is hit then NULL is returned and nothing is
-allocated. */
+allocated.
+@return empty row, or NULL if out of memory */
static
void*
table_cache_create_empty_row(
/*=========================*/
- /* out: empty row, or
- NULL if out of memory */
- i_s_table_cache_t* table_cache, /* in/out: table cache */
- trx_i_s_cache_t* cache) /* in/out: cache to record
+ i_s_table_cache_t* table_cache, /*!< in/out: table cache */
+ trx_i_s_cache_t* cache) /*!< in/out: cache to record
how many bytes are
allocated */
{
@@ -365,25 +401,24 @@ table_cache_create_empty_row(
return(row);
}
-/***********************************************************************
+/*******************************************************************//**
Fills i_s_trx_row_t object.
-If memory can not be allocated then FALSE is returned. */
+If memory can not be allocated then FALSE is returned.
+@return FALSE if allocation fails */
static
ibool
fill_trx_row(
/*=========*/
- /* out: FALSE if
- allocation fails */
- i_s_trx_row_t* row, /* out: result object
+ i_s_trx_row_t* row, /*!< out: result object
that's filled */
- const trx_t* trx, /* in: transaction to
+ const trx_t* trx, /*!< in: transaction to
get data from */
- const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
+ const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the
corresponding row in
innodb_locks if trx is
waiting or NULL if trx
is not waiting */
- trx_i_s_cache_t* cache) /* in/out: cache into
+ trx_i_s_cache_t* cache) /*!< in/out: cache into
which to copy volatile
strings */
{
@@ -451,21 +486,21 @@ fill_trx_row(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Format the nth field of "rec" and put it in "buf". The result is always
-'\0'-terminated. Returns the number of bytes that were written to "buf"
-(including the terminating '\0'). */
+NUL-terminated. Returns the number of bytes that were written to "buf"
+(including the terminating NUL).
+@return end of the result */
static
ulint
put_nth_field(
/*==========*/
- /* out: end of the result */
- char* buf, /* out: buffer */
- ulint buf_size,/* in: buffer size in bytes */
- 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
+ char* buf, /*!< out: buffer */
+ ulint buf_size,/*!< in: buffer size in bytes */
+ 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
by rec_get_offsets() */
{
const byte* data;
@@ -510,18 +545,18 @@ put_nth_field(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Fills the "lock_data" member of i_s_locks_row_t object.
-If memory can not be allocated then FALSE is returned. */
+If memory can not be allocated then FALSE is returned.
+@return FALSE if allocation fails */
static
ibool
fill_lock_data(
/*===========*/
- /* out: FALSE if allocation fails */
- const char** lock_data,/* out: "lock_data" to fill */
- const lock_t* lock, /* in: lock used to find the data */
- ulint heap_no,/* in: rec num used to find the data */
- trx_i_s_cache_t* cache) /* in/out: cache where to store
+ const char** lock_data,/*!< out: "lock_data" to fill */
+ const lock_t* lock, /*!< in: lock used to find the data */
+ ulint heap_no,/*!< in: rec num used to find the data */
+ trx_i_s_cache_t* cache) /*!< in/out: cache where to store
volatile data */
{
mtr_t mtr;
@@ -619,20 +654,20 @@ fill_lock_data(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Fills i_s_locks_row_t object. Returns its first argument.
-If memory can not be allocated then FALSE is returned. */
+If memory can not be allocated then FALSE is returned.
+@return FALSE if allocation fails */
static
ibool
fill_locks_row(
/*===========*/
- /* out: FALSE if allocation fails */
- i_s_locks_row_t* row, /* out: result object that's filled */
- const lock_t* lock, /* in: lock to get data from */
- ulint heap_no,/* in: lock's record number
+ i_s_locks_row_t* row, /*!< out: result object that's filled */
+ const lock_t* lock, /*!< in: lock to get data from */
+ ulint heap_no,/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
- trx_i_s_cache_t* cache) /* in/out: cache into which to copy
+ trx_i_s_cache_t* cache) /*!< in/out: cache into which to copy
volatile strings */
{
row->lock_trx_id = lock_get_trx_id(lock);
@@ -693,20 +728,19 @@ fill_locks_row(
return(TRUE);
}
-/***********************************************************************
-Fills i_s_lock_waits_row_t object. Returns its first argument. */
+/*******************************************************************//**
+Fills i_s_lock_waits_row_t object. Returns its first argument.
+@return result object that's filled */
static
i_s_lock_waits_row_t*
fill_lock_waits_row(
/*================*/
- /* out: result object
- that's filled */
- i_s_lock_waits_row_t* row, /* out: result object
+ i_s_lock_waits_row_t* row, /*!< out: result object
that's filled */
- const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
+ const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the
relevant requested lock
row in innodb_locks */
- const i_s_locks_row_t* blocking_lock_row)/* in: pointer to the
+ const i_s_locks_row_t* blocking_lock_row)/*!< in: pointer to the
relevant blocking lock
row in innodb_locks */
{
@@ -716,18 +750,18 @@ fill_lock_waits_row(
return(row);
}
-/***********************************************************************
+/*******************************************************************//**
Calculates a hash fold for a lock. For a record lock the fold is
calculated from 4 elements, which uniquely identify a lock at a given
point in time: transaction id, space id, page number, record number.
-For a table lock the fold is table's id. */
+For a table lock the fold is table's id.
+@return fold */
static
ulint
fold_lock(
/*======*/
- /* out: fold */
- const lock_t* lock, /* in: lock object to fold */
- ulint heap_no)/* in: lock's record number
+ const lock_t* lock, /*!< in: lock object to fold */
+ ulint heap_no)/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
{
@@ -768,16 +802,16 @@ fold_lock(
#endif
}
-/***********************************************************************
-Checks whether i_s_locks_row_t object represents a lock_t object. */
+/*******************************************************************//**
+Checks whether i_s_locks_row_t object represents a lock_t object.
+@return TRUE if they match */
static
ibool
locks_row_eq_lock(
/*==============*/
- /* out: TRUE if they match */
- const i_s_locks_row_t* row, /* in: innodb_locks row */
- const lock_t* lock, /* in: lock object */
- ulint heap_no)/* in: lock's record number
+ const i_s_locks_row_t* row, /*!< in: innodb_locks row */
+ const lock_t* lock, /*!< in: lock object */
+ ulint heap_no)/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
{
@@ -809,18 +843,18 @@ locks_row_eq_lock(
#endif
}
-/***********************************************************************
+/*******************************************************************//**
Searches for a row in the innodb_locks cache that has a specified id.
This happens in O(1) time since a hash table is used. Returns pointer to
-the row or NULL if none is found. */
+the row or NULL if none is found.
+@return row or NULL */
static
i_s_locks_row_t*
search_innodb_locks(
/*================*/
- /* out: row or NULL */
- trx_i_s_cache_t* cache, /* in: cache */
- const lock_t* lock, /* in: lock to search for */
- ulint heap_no)/* in: lock's record number
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ const lock_t* lock, /*!< in: lock to search for */
+ ulint heap_no)/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
{
@@ -851,19 +885,19 @@ search_innodb_locks(
return(hash_chain->value);
}
-/***********************************************************************
+/*******************************************************************//**
Adds new element to the locks cache, enlarging it if necessary.
Returns a pointer to the added row. If the row is already present then
no row is added and a pointer to the existing row is returned.
-If row can not be allocated then NULL is returned. */
+If row can not be allocated then NULL is returned.
+@return row */
static
i_s_locks_row_t*
add_lock_to_cache(
/*==============*/
- /* out: row */
- trx_i_s_cache_t* cache, /* in/out: cache */
- const lock_t* lock, /* in: the element to add */
- ulint heap_no)/* in: lock's record number
+ trx_i_s_cache_t* cache, /*!< in/out: cache */
+ const lock_t* lock, /*!< in: the element to add */
+ ulint heap_no)/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
{
@@ -918,20 +952,19 @@ add_lock_to_cache(
return(dst_row);
}
-/***********************************************************************
+/*******************************************************************//**
Adds new pair of locks to the lock waits cache.
-If memory can not be allocated then FALSE is returned. */
+If memory can not be allocated then FALSE is returned.
+@return FALSE if allocation fails */
static
ibool
add_lock_wait_to_cache(
/*===================*/
- /* out: FALSE if
- allocation fails */
- trx_i_s_cache_t* cache, /* in/out: cache */
- const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
+ trx_i_s_cache_t* cache, /*!< in/out: cache */
+ const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the
relevant requested lock
row in innodb_locks */
- const i_s_locks_row_t* blocking_lock_row)/* in: pointer to the
+ const i_s_locks_row_t* blocking_lock_row)/*!< in: pointer to the
relevant blocking lock
row in innodb_locks */
{
@@ -952,21 +985,21 @@ add_lock_wait_to_cache(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Adds transaction's relevant (important) locks to cache.
If the transaction is waiting, then the wait lock is added to
innodb_locks and a pointer to the added row is returned in
requested_lock_row, otherwise requested_lock_row is set to NULL.
If rows can not be allocated then FALSE is returned and the value of
-requested_lock_row is undefined. */
+requested_lock_row is undefined.
+@return FALSE if allocation fails */
static
ibool
add_trx_relevant_locks_to_cache(
/*============================*/
- /* out: FALSE if allocation fails */
- trx_i_s_cache_t* cache, /* in/out: cache */
- const trx_t* trx, /* in: transaction */
- i_s_locks_row_t** requested_lock_row)/* out: pointer to the
+ trx_i_s_cache_t* cache, /*!< in/out: cache */
+ const trx_t* trx, /*!< in: transaction */
+ i_s_locks_row_t** requested_lock_row)/*!< out: pointer to the
requested lock row, or NULL or
undefined */
{
@@ -1046,22 +1079,23 @@ add_trx_relevant_locks_to_cache(
return(TRUE);
}
-/***********************************************************************
-Checks if the cache can safely be updated. */
+/** The minimum time that a cache must not be updated after it has been
+read for the last time; measured in microseconds. We use this technique
+to ensure that SELECTs which join several INFORMATION SCHEMA tables read
+the same version of the cache. */
+#define CACHE_MIN_IDLE_TIME_US 100000 /* 0.1 sec */
+
+/*******************************************************************//**
+Checks if the cache can safely be updated.
+@return TRUE if can be updated */
static
ibool
can_cache_be_updated(
/*=================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
ullint now;
-/* The minimum time that a cache must not be updated after it has been
-read for the last time; measured in microseconds. We use this technique
-to ensure that SELECTs which join several INFORMATION SCHEMA tables read
-the same version of the cache. */
-#define CACHE_MIN_IDLE_TIME_US 100000 /* 0.1 sec */
-
/* Here we read cache->last_read without acquiring its mutex
because last_read is only updated when a shared rw lock on the
whole cache is being held (see trx_i_s_cache_end_read()) and
@@ -1082,14 +1116,14 @@ the same version of the cache. */
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Declare a cache empty, preparing it to be filled up. Not all resources
are freed because they can be reused. */
static
void
trx_i_s_cache_clear(
/*================*/
- trx_i_s_cache_t* cache) /* out: cache to clear */
+ trx_i_s_cache_t* cache) /*!< out: cache to clear */
{
cache->innodb_trx.rows_used = 0;
cache->innodb_locks.rows_used = 0;
@@ -1100,14 +1134,14 @@ trx_i_s_cache_clear(
ha_storage_empty(&cache->storage);
}
-/***********************************************************************
+/*******************************************************************//**
Fetches the data needed to fill the 3 INFORMATION SCHEMA tables into the
table cache buffer. Cache must be locked for write. */
static
void
fetch_data_into_cache(
/*==================*/
- trx_i_s_cache_t* cache) /* in/out: cache */
+ trx_i_s_cache_t* cache) /*!< in/out: cache */
{
trx_t* trx;
i_s_trx_row_t* trx_row;
@@ -1156,15 +1190,15 @@ fetch_data_into_cache(
cache->is_truncated = FALSE;
}
-/***********************************************************************
+/*******************************************************************//**
Update the transactions cache if it has not been read for some time.
-Called from handler/i_s.cc. */
+Called from handler/i_s.cc.
+@return 0 - fetched, 1 - not */
UNIV_INTERN
int
trx_i_s_possibly_fetch_data_into_cache(
/*===================================*/
- /* out: 0 - fetched, 1 - not */
- trx_i_s_cache_t* cache) /* in/out: cache */
+ trx_i_s_cache_t* cache) /*!< in/out: cache */
{
if (!can_cache_be_updated(cache)) {
@@ -1186,26 +1220,26 @@ trx_i_s_possibly_fetch_data_into_cache(
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if the data in the cache is truncated due to the memory
-limit posed by TRX_I_S_MEM_LIMIT. */
+limit posed by TRX_I_S_MEM_LIMIT.
+@return TRUE if truncated */
UNIV_INTERN
ibool
trx_i_s_cache_is_truncated(
/*=======================*/
- /* out: TRUE if truncated */
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
return(cache->is_truncated);
}
-/***********************************************************************
+/*******************************************************************//**
Initialize INFORMATION SCHEMA trx related cache. */
UNIV_INTERN
void
trx_i_s_cache_init(
/*===============*/
- trx_i_s_cache_t* cache) /* out: cache to init */
+ trx_i_s_cache_t* cache) /*!< out: cache to init */
{
/* The latching is done in the following order:
acquire trx_i_s_cache_t::rw_lock, X
@@ -1238,24 +1272,40 @@ trx_i_s_cache_init(
cache->is_truncated = FALSE;
}
-/***********************************************************************
+/*******************************************************************//**
+Free the INFORMATION SCHEMA trx related cache. */
+UNIV_INTERN
+void
+trx_i_s_cache_free(
+/*===============*/
+ trx_i_s_cache_t* cache) /*!< in, own: cache to free */
+{
+ hash_table_free(cache->locks_hash);
+ ha_storage_free(cache->storage);
+ table_cache_free(&cache->innodb_trx);
+ table_cache_free(&cache->innodb_locks);
+ table_cache_free(&cache->innodb_lock_waits);
+ memset(cache, 0, sizeof *cache);
+}
+
+/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_start_read(
/*=====================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
rw_lock_s_lock(&cache->rw_lock);
}
-/***********************************************************************
+/*******************************************************************//**
Release a shared/read lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_end_read(
/*===================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
ullint now;
@@ -1272,24 +1322,24 @@ trx_i_s_cache_end_read(
rw_lock_s_unlock(&cache->rw_lock);
}
-/***********************************************************************
+/*******************************************************************//**
Issue an exclusive/write lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_start_write(
/*======================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
rw_lock_x_lock(&cache->rw_lock);
}
-/***********************************************************************
+/*******************************************************************//**
Release an exclusive/write lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_end_write(
/*====================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
#ifdef UNIV_SYNC_DEBUG
ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX));
@@ -1298,15 +1348,15 @@ trx_i_s_cache_end_write(
rw_lock_x_unlock(&cache->rw_lock);
}
-/***********************************************************************
-Selects a INFORMATION SCHEMA table cache from the whole cache. */
+/*******************************************************************//**
+Selects a INFORMATION SCHEMA table cache from the whole cache.
+@return table cache */
static
i_s_table_cache_t*
cache_select_table(
/*===============*/
- /* out: table cache */
- trx_i_s_cache_t* cache, /* in: whole cache */
- enum i_s_table table) /* in: which table */
+ trx_i_s_cache_t* cache, /*!< in: whole cache */
+ enum i_s_table table) /*!< in: which table */
{
i_s_table_cache_t* table_cache;
@@ -1332,16 +1382,16 @@ cache_select_table(
return(table_cache);
}
-/***********************************************************************
+/*******************************************************************//**
Retrieves the number of used rows in the cache for a given
-INFORMATION SCHEMA table. */
+INFORMATION SCHEMA table.
+@return number of rows */
UNIV_INTERN
ulint
trx_i_s_cache_get_rows_used(
/*========================*/
- /* out: number of rows */
- trx_i_s_cache_t* cache, /* in: cache */
- enum i_s_table table) /* in: which table */
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ enum i_s_table table) /*!< in: which table */
{
i_s_table_cache_t* table_cache;
@@ -1350,17 +1400,17 @@ trx_i_s_cache_get_rows_used(
return(table_cache->rows_used);
}
-/***********************************************************************
+/*******************************************************************//**
Retrieves the nth row (zero-based) in the cache for a given
-INFORMATION SCHEMA table. */
+INFORMATION SCHEMA table.
+@return row */
UNIV_INTERN
void*
trx_i_s_cache_get_nth_row(
/*======================*/
- /* out: row */
- trx_i_s_cache_t* cache, /* in: cache */
- enum i_s_table table, /* in: which table */
- ulint n) /* in: row number */
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ enum i_s_table table, /*!< in: which table */
+ ulint n) /*!< in: row number */
{
i_s_table_cache_t* table_cache;
ulint i;
@@ -1389,19 +1439,19 @@ trx_i_s_cache_get_nth_row(
return(row);
}
-/***********************************************************************
+/*******************************************************************//**
Crafts a lock id string from a i_s_locks_row_t object. Returns its
second argument. This function aborts if there is not enough space in
lock_id. Be sure to provide at least TRX_I_S_LOCK_ID_MAX_LEN + 1 if you
-want to be 100% sure that it will not abort. */
+want to be 100% sure that it will not abort.
+@return resulting lock id */
UNIV_INTERN
char*
trx_i_s_create_lock_id(
/*===================*/
- /* out: resulting lock id */
- const i_s_locks_row_t* row, /* in: innodb_locks row */
- char* lock_id,/* out: resulting lock_id */
- ulint lock_id_size)/* in: size of the lock id
+ const i_s_locks_row_t* row, /*!< in: innodb_locks row */
+ char* lock_id,/*!< out: resulting lock_id */
+ ulint lock_id_size)/*!< in: size of the lock id
buffer */
{
int res_len;
diff --git a/storage/xtradb/trx/trx0purge.c b/storage/xtradb/trx/trx0purge.c
index 7a2a27a94ff..41e16b35e85 100644
--- a/storage/xtradb/trx/trx0purge.c
+++ b/storage/xtradb/trx/trx0purge.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0purge.c
Purge old versions
Created 3/26/1996 Heikki Tuuri
@@ -30,6 +31,7 @@ Created 3/26/1996 Heikki Tuuri
#include "fsp0fsp.h"
#include "mach0data.h"
+#include "mtr0log.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "trx0roll.h"
@@ -42,24 +44,24 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0que.h"
#include "os0thread.h"
-/* The global data structure coordinating a purge */
+/** The global data structure coordinating a purge */
UNIV_INTERN trx_purge_t* purge_sys = NULL;
-/* A dummy undo record used as a return value when we have a whole undo log
+/** A dummy undo record used as a return value when we have a whole undo log
which needs no purge */
UNIV_INTERN trx_undo_rec_t trx_purge_dummy_rec;
-/*********************************************************************
+/*****************************************************************//**
Checks if trx_id is >= purge_view: then it is guaranteed that its update
-undo log still exists in the system. */
+undo log still exists in the system.
+@return TRUE if is sure that it is preserved, also if the function
+returns FALSE, it is possible that the undo log still exists in the
+system */
UNIV_INTERN
ibool
trx_purge_update_undo_must_exist(
/*=============================*/
- /* out: TRUE if is sure that it is preserved, also
- if the function returns FALSE, it is possible that
- the undo log still exists in the system */
- dulint trx_id) /* in: transaction id */
+ trx_id_t trx_id) /*!< in: transaction id */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
@@ -75,15 +77,15 @@ trx_purge_update_undo_must_exist(
/*=================== PURGE RECORD ARRAY =============================*/
-/***********************************************************************
-Stores info of an undo log record during a purge. */
+/*******************************************************************//**
+Stores info of an undo log record during a purge.
+@return pointer to the storage cell */
static
trx_undo_inf_t*
trx_purge_arr_store_info(
/*=====================*/
- /* out: pointer to the storage cell */
- dulint trx_no, /* in: transaction number */
- dulint undo_no)/* in: undo number */
+ trx_id_t trx_no, /*!< in: transaction number */
+ undo_no_t undo_no)/*!< in: undo number */
{
trx_undo_inf_t* cell;
trx_undo_arr_t* arr;
@@ -107,13 +109,13 @@ trx_purge_arr_store_info(
}
}
-/***********************************************************************
+/*******************************************************************//**
Removes info of an undo log record during a purge. */
UNIV_INLINE
void
trx_purge_arr_remove_info(
/*======================*/
- trx_undo_inf_t* cell) /* in: pointer to the storage cell */
+ trx_undo_inf_t* cell) /*!< in: pointer to the storage cell */
{
trx_undo_arr_t* arr;
@@ -126,20 +128,20 @@ trx_purge_arr_remove_info(
arr->n_used--;
}
-/***********************************************************************
+/*******************************************************************//**
Gets the biggest pair of a trx number and an undo number in a purge array. */
static
void
trx_purge_arr_get_biggest(
/*======================*/
- trx_undo_arr_t* arr, /* in: purge array */
- dulint* trx_no, /* out: transaction number: ut_dulint_zero
+ trx_undo_arr_t* arr, /*!< in: purge array */
+ trx_id_t* trx_no, /*!< out: transaction number: ut_dulint_zero
if array is empty */
- dulint* undo_no)/* out: undo number */
+ undo_no_t* undo_no)/*!< out: undo number */
{
trx_undo_inf_t* cell;
- dulint pair_trx_no;
- dulint pair_undo_no;
+ trx_id_t pair_trx_no;
+ undo_no_t pair_undo_no;
int trx_cmp;
ulint n_used;
ulint i;
@@ -176,14 +178,15 @@ trx_purge_arr_get_biggest(
}
}
-/********************************************************************
+/****************************************************************//**
Builds a purge 'query' graph. The actual purge is performed by executing
-this query graph. */
+this query graph.
+@return own: the query graph */
static
que_t*
-trx_purge_graph_build(void)
+trx_purge_graph_build(
/*=======================*/
- /* out, own: the query graph */
+ trx_t* trx)
{
mem_heap_t* heap;
que_fork_t* fork;
@@ -192,7 +195,7 @@ trx_purge_graph_build(void)
heap = mem_heap_create(512);
fork = que_fork_create(NULL, NULL, QUE_FORK_PURGE, heap);
- fork->trx = purge_sys->trx;
+ fork->trx = trx;
thr = que_thr_create(fork, heap);
@@ -205,7 +208,7 @@ trx_purge_graph_build(void)
return(fork);
}
-/************************************************************************
+/********************************************************************//**
Creates the global purge system control structure and inits the history
mutex. */
UNIV_INTERN
@@ -241,25 +244,88 @@ trx_purge_sys_create(void)
ut_a(trx_start_low(purge_sys->trx, ULINT_UNDEFINED));
- purge_sys->query = trx_purge_graph_build();
+ purge_sys->query = trx_purge_graph_build(purge_sys->trx);
purge_sys->view = read_view_oldest_copy_or_open_new(ut_dulint_zero,
purge_sys->heap);
+
+ purge_sys->n_worker = 0;
+ if (srv_use_purge_thread > 1) {
+ /* Use worker threads */
+ ulint i;
+
+ purge_sys->n_worker = srv_use_purge_thread - 1;
+
+ purge_sys->sess_arr = mem_alloc(sizeof(sess_t*) * purge_sys->n_worker);
+ purge_sys->trx_arr = mem_alloc(sizeof(trx_t*) * purge_sys->n_worker);
+ purge_sys->query_arr = mem_alloc(sizeof(que_t*) * purge_sys->n_worker);
+
+ purge_sys->worker_event = os_event_create(NULL);
+ os_event_reset(purge_sys->worker_event);
+
+ for (i = 0; i < purge_sys->n_worker; i++) {
+ purge_sys->sess_arr[i] = sess_open();
+
+ purge_sys->trx_arr[i] = purge_sys->sess_arr[i]->trx;
+ purge_sys->trx_arr[i]->is_purge = 1;
+ ut_a(trx_start_low(purge_sys->trx_arr[i], ULINT_UNDEFINED));
+
+ purge_sys->query_arr[i] = trx_purge_graph_build(purge_sys->trx_arr[i]);
+ }
+ }
+}
+
+/************************************************************************
+Frees the global purge system control structure. */
+UNIV_INTERN
+void
+trx_purge_sys_close(void)
+/*======================*/
+{
+ ut_ad(!mutex_own(&kernel_mutex));
+
+ que_graph_free(purge_sys->query);
+
+ ut_a(purge_sys->sess->trx->is_purge);
+ purge_sys->sess->trx->conc_state = TRX_NOT_STARTED;
+ sess_close(purge_sys->sess);
+ purge_sys->sess = NULL;
+
+ if (purge_sys->view != NULL) {
+ /* Because acquiring the kernel mutex is a pre-condition
+ of read_view_close(). We don't really need it here. */
+ mutex_enter(&kernel_mutex);
+
+ read_view_close(purge_sys->view);
+ purge_sys->view = NULL;
+
+ mutex_exit(&kernel_mutex);
+ }
+
+ trx_undo_arr_free(purge_sys->arr);
+
+ rw_lock_free(&purge_sys->latch);
+ mutex_free(&purge_sys->mutex);
+
+ mem_heap_free(purge_sys->heap);
+ mem_free(purge_sys);
+
+ purge_sys = NULL;
}
/*================ UNDO LOG HISTORY LIST =============================*/
-/************************************************************************
+/********************************************************************//**
Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */
UNIV_INTERN
void
trx_purge_add_update_undo_to_history(
/*=================================*/
- trx_t* trx, /* in: transaction */
- page_t* undo_page, /* in: update undo log header page,
+ trx_t* trx, /*!< in: transaction */
+ page_t* undo_page, /*!< in: update undo log header page,
x-latched */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_undo_t* undo;
trx_rseg_t* rseg;
@@ -330,16 +396,16 @@ trx_purge_add_update_undo_to_history(
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees an undo log segment which is in the history list. Cuts the end of the
history list at the youngest undo log in this segment. */
static
void
trx_purge_free_segment(
/*===================*/
- trx_rseg_t* rseg, /* in: rollback segment */
- fil_addr_t hdr_addr, /* in: the file address of log_hdr */
- ulint n_removed_logs) /* in: count of how many undo logs we
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ fil_addr_t hdr_addr, /*!< in: the file address of log_hdr */
+ ulint n_removed_logs) /*!< in: count of how many undo logs we
will cut off from the end of the
history list */
{
@@ -436,16 +502,16 @@ loop:
mtr_commit(&mtr);
}
-/************************************************************************
+/********************************************************************//**
Removes unnecessary history data from a rollback segment. */
static
void
trx_purge_truncate_rseg_history(
/*============================*/
- trx_rseg_t* rseg, /* in: rollback segment */
- dulint limit_trx_no, /* in: remove update undo logs whose
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ trx_id_t limit_trx_no, /*!< in: remove update undo logs whose
trx number is < limit_trx_no */
- dulint limit_undo_no) /* in: if transaction number is equal
+ undo_no_t limit_undo_no) /*!< in: if transaction number is equal
to limit_trx_no, truncate undo records
with undo number < limit_undo_no */
{
@@ -540,7 +606,7 @@ loop:
goto loop;
}
-/************************************************************************
+/********************************************************************//**
Removes unnecessary history data from rollback segments. NOTE that when this
function is called, the caller must not have any latches on undo log pages! */
static
@@ -549,8 +615,8 @@ trx_purge_truncate_history(void)
/*============================*/
{
trx_rseg_t* rseg;
- dulint limit_trx_no;
- dulint limit_undo_no;
+ trx_id_t limit_trx_no;
+ undo_no_t limit_undo_no;
ut_ad(mutex_own(&(purge_sys->mutex)));
@@ -583,14 +649,14 @@ trx_purge_truncate_history(void)
}
}
-/************************************************************************
+/********************************************************************//**
Does a truncate if the purge array is empty. NOTE that when this function is
-called, the caller must not have any latches on undo log pages! */
+called, the caller must not have any latches on undo log pages!
+@return TRUE if array empty */
UNIV_INLINE
ibool
trx_purge_truncate_if_arr_empty(void)
/*=================================*/
- /* out: TRUE if array empty */
{
ut_ad(mutex_own(&(purge_sys->mutex)));
@@ -604,20 +670,20 @@ trx_purge_truncate_if_arr_empty(void)
return(FALSE);
}
-/***************************************************************************
+/***********************************************************************//**
Updates the last not yet purged history log info in rseg when we have purged
a whole undo log. Advances also purge_sys->purge_trx_no past the purged log. */
static
void
trx_purge_rseg_get_next_history_log(
/*================================*/
- trx_rseg_t* rseg) /* in: rollback segment */
+ trx_rseg_t* rseg) /*!< in: rollback segment */
{
page_t* undo_page;
trx_ulogf_t* log_hdr;
trx_usegf_t* seg_hdr;
fil_addr_t prev_log_addr;
- dulint trx_no;
+ trx_id_t trx_no;
ibool del_marks;
mtr_t mtr;
@@ -705,7 +771,7 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
}
-/***************************************************************************
+/***********************************************************************//**
Chooses the next undo log to purge and updates the info in purge_sys. This
function is used to initialize purge_sys when the next record to purge is
not known, and also to update the purge system info on the next record when
@@ -718,7 +784,7 @@ trx_purge_choose_next_log(void)
trx_undo_rec_t* rec;
trx_rseg_t* rseg;
trx_rseg_t* min_rseg;
- dulint min_trx_no;
+ trx_id_t min_trx_no;
ulint space = 0; /* remove warning (??? bug ???) */
ulint zip_size = 0;
ulint page_no = 0; /* remove warning (??? bug ???) */
@@ -804,15 +870,14 @@ trx_purge_choose_next_log(void)
mtr_commit(&mtr);
}
-/***************************************************************************
-Gets the next record to purge and updates the info in the purge system. */
+/***********************************************************************//**
+Gets the next record to purge and updates the info in the purge system.
+@return copy of an undo log record or pointer to the dummy undo log record */
static
trx_undo_rec_t*
trx_purge_get_next_rec(
/*===================*/
- /* out: copy of an undo log record or
- pointer to the dummy undo log record */
- mem_heap_t* heap) /* in: memory heap where copied */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
trx_undo_rec_t* rec;
trx_undo_rec_t* rec_copy;
@@ -927,21 +992,19 @@ trx_purge_get_next_rec(
return(rec_copy);
}
-/************************************************************************
+/********************************************************************//**
Fetches the next undo log record from the history list to purge. It must be
-released with the corresponding release function. */
+released with the corresponding release function.
+@return copy of an undo log record or pointer to trx_purge_dummy_rec,
+if the whole undo log can skipped in purge; NULL if none left */
UNIV_INTERN
trx_undo_rec_t*
trx_purge_fetch_next_rec(
/*=====================*/
- /* out: copy of an undo log record or
- pointer to the dummy undo log record
- &trx_purge_dummy_rec, if the whole undo log
- can skipped in purge; NULL if none left */
- dulint* roll_ptr,/* out: roll pointer to undo record */
- trx_undo_inf_t** cell, /* out: storage cell for the record in the
+ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */
+ trx_undo_inf_t** cell, /*!< out: storage cell for the record in the
purge array */
- mem_heap_t* heap) /* in: memory heap where copied */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
trx_undo_rec_t* undo_rec;
@@ -1023,13 +1086,13 @@ trx_purge_fetch_next_rec(
return(undo_rec);
}
-/***********************************************************************
+/*******************************************************************//**
Releases a reserved purge undo record. */
UNIV_INTERN
void
trx_purge_rec_release(
/*==================*/
- trx_undo_inf_t* cell) /* in: storage cell */
+ trx_undo_inf_t* cell) /*!< in: storage cell */
{
trx_undo_arr_t* arr;
@@ -1042,14 +1105,13 @@ trx_purge_rec_release(
mutex_exit(&(purge_sys->mutex));
}
-/***********************************************************************
-This function runs a purge batch. */
+/*******************************************************************//**
+This function runs a purge batch.
+@return number of undo log pages handled in the batch */
UNIV_INTERN
ulint
trx_purge(void)
/*===========*/
- /* out: number of undo log pages handled in
- the batch */
{
que_thr_t* thr;
/* que_thr_t* thr2; */
@@ -1112,7 +1174,7 @@ trx_purge(void)
/* Handle at most 20 undo log pages in one purge batch */
- purge_sys->handle_limit = purge_sys->n_pages_handled + 20;
+ purge_sys->handle_limit = purge_sys->n_pages_handled + 20 * (srv_use_purge_thread + 1);
old_pages_handled = purge_sys->n_pages_handled;
@@ -1131,6 +1193,9 @@ trx_purge(void)
mutex_exit(&kernel_mutex);
+ if (purge_sys->n_worker)
+ os_event_set(purge_sys->worker_event);
+
/* srv_que_task_enqueue(thr2); */
if (srv_print_thread_releases) {
@@ -1140,6 +1205,9 @@ trx_purge(void)
que_run_threads(thr);
+ if (purge_sys->n_worker)
+ os_event_reset(purge_sys->worker_event);
+
if (srv_print_thread_releases) {
fprintf(stderr,
@@ -1151,6 +1219,52 @@ trx_purge(void)
}
/**********************************************************************
+This function runs a purge worker batch */
+UNIV_INTERN
+void
+trx_purge_worker(
+/*=============*/
+ ulint worker_id)
+{
+ que_thr_t* thr;
+
+ mutex_enter(&kernel_mutex);
+
+ thr = que_fork_start_command(purge_sys->query_arr[worker_id]);
+
+ ut_ad(thr);
+
+ mutex_exit(&kernel_mutex);
+
+ que_run_threads(thr);
+
+ if (purge_sys->state == TRX_STOP_PURGE) { /* optimistic */
+ os_event_reset(purge_sys->worker_event);
+ }
+}
+
+/**********************************************************************
+This function waits the event for worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wait(void)
+/*=======================*/
+{
+ os_event_wait(purge_sys->worker_event);
+}
+
+/**********************************************************************
+This function wakes the waiting worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wake(void)
+/*=======================*/
+{
+ if (purge_sys->n_worker)
+ os_event_set(purge_sys->worker_event);
+}
+
+/******************************************************************//**
Prints information of the purge system to stderr. */
UNIV_INTERN
void
diff --git a/storage/xtradb/trx/trx0rec.c b/storage/xtradb/trx/trx0rec.c
index 148f93cdbe7..5097cf18dcd 100644
--- a/storage/xtradb/trx/trx0rec.c
+++ b/storage/xtradb/trx/trx0rec.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0rec.c
Transaction undo log record
Created 3/26/1996 Heikki Tuuri
@@ -30,30 +31,31 @@ Created 3/26/1996 Heikki Tuuri
#include "fsp0fsp.h"
#include "mach0data.h"
-#include "trx0rseg.h"
-#include "trx0trx.h"
#include "trx0undo.h"
+#include "mtr0log.h"
+#ifndef UNIV_HOTBACKUP
#include "dict0dict.h"
#include "ut0mem.h"
#include "row0ext.h"
#include "row0upd.h"
#include "que0que.h"
#include "trx0purge.h"
+#include "trx0rseg.h"
#include "row0row.h"
/*=========== UNDO LOG RECORD CREATION AND DECODING ====================*/
-/**************************************************************************
+/**********************************************************************//**
Writes the mtr log entry of the inserted undo log record on the undo log
page. */
UNIV_INLINE
void
trx_undof_page_add_undo_rec_log(
/*============================*/
- page_t* undo_page, /* in: undo log page */
- ulint old_free, /* in: start offset of the inserted entry */
- ulint new_free, /* in: end offset of the entry */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log page */
+ ulint old_free, /*!< in: start offset of the inserted entry */
+ ulint new_free, /*!< in: end offset of the entry */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
const byte* log_end;
@@ -82,17 +84,18 @@ trx_undof_page_add_undo_rec_log(
mlog_catenate_string(mtr, undo_page + old_free + 2, len);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of adding an undo log record. */
+/***********************************************************//**
+Parses a redo log record of adding an undo log record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_add_undo_rec(
/*========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page) /* in: page or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page) /*!< in: page or NULL */
{
ulint len;
byte* rec;
@@ -130,15 +133,16 @@ trx_undo_parse_add_undo_rec(
return(ptr + len);
}
-/**************************************************************************
-Calculates the free space left for extending an undo log record. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Calculates the free space left for extending an undo log record.
+@return bytes left */
UNIV_INLINE
ulint
trx_undo_left(
/*==========*/
- /* out: bytes left */
- const page_t* page, /* in: undo log page */
- const byte* ptr) /* in: pointer to page */
+ const page_t* page, /*!< in: undo log page */
+ const byte* ptr) /*!< in: pointer to page */
{
/* The '- 10' is a safety margin, in case we have some small
calculation error below */
@@ -146,23 +150,22 @@ trx_undo_left(
return(UNIV_PAGE_SIZE - (ptr - page) - 10 - FIL_PAGE_DATA_END);
}
-/**************************************************************************
+/**********************************************************************//**
Set the next and previous pointers in the undo page for the undo record
that was written to ptr. Update the first free value by the number of bytes
-written for this undo record.*/
+written for this undo record.
+@return offset of the inserted entry on the page if succeeded, 0 if fail */
static
ulint
trx_undo_page_set_next_prev_and_add(
/*================================*/
- /* out: offset of the inserted entry
- on the page if succeeded, 0 if fail */
- page_t* undo_page, /* in/out: undo log page */
- byte* ptr, /* in: ptr up to where data has been
+ page_t* undo_page, /*!< in/out: undo log page */
+ byte* ptr, /*!< in: ptr up to where data has been
written on this undo page. */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
- ulint first_free; /* offset within undo_page */
- ulint end_of_rec; /* offset within undo_page */
+ ulint first_free; /*!< offset within undo_page */
+ ulint end_of_rec; /*!< offset within undo_page */
byte* ptr_to_first_free;
/* pointer within undo_page
that points to the next free
@@ -199,20 +202,19 @@ trx_undo_page_set_next_prev_and_add(
return(first_free);
}
-/**************************************************************************
-Reports in the undo log of an insert of a clustered index record. */
+/**********************************************************************//**
+Reports in the undo log of an insert of a clustered index record.
+@return offset of the inserted entry on the page if succeed, 0 if fail */
static
ulint
trx_undo_page_report_insert(
/*========================*/
- /* out: offset of the inserted entry
- on the page if succeed, 0 if fail */
- page_t* undo_page, /* in: undo log page */
- trx_t* trx, /* in: transaction */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* clust_entry, /* in: index entry which will be
+ page_t* undo_page, /*!< in: undo log page */
+ trx_t* trx, /*!< in: transaction */
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* clust_entry, /*!< in: index entry which will be
inserted to the clustered index */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint first_free;
byte* ptr;
@@ -272,23 +274,22 @@ trx_undo_page_report_insert(
return(trx_undo_page_set_next_prev_and_add(undo_page, ptr, mtr));
}
-/**************************************************************************
-Reads from an undo log record the general parameters. */
+/**********************************************************************//**
+Reads from an undo log record the general parameters.
+@return remaining part of undo log record after reading these values */
UNIV_INTERN
byte*
trx_undo_rec_get_pars(
/*==================*/
- /* out: remaining part of undo log
- record after reading these values */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- ulint* type, /* out: undo record type:
+ trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ ulint* type, /*!< out: undo record type:
TRX_UNDO_INSERT_REC, ... */
- ulint* cmpl_info, /* out: compiler info, relevant only
+ ulint* cmpl_info, /*!< out: compiler info, relevant only
for update type records */
- ibool* updated_extern, /* out: TRUE if we updated an
+ ibool* updated_extern, /*!< out: TRUE if we updated an
externally stored fild */
- dulint* undo_no, /* out: undo log record number */
- dulint* table_id) /* out: table id */
+ undo_no_t* undo_no, /*!< out: undo log record number */
+ dulint* table_id) /*!< out: table id */
{
byte* ptr;
ulint type_cmpl;
@@ -317,18 +318,17 @@ trx_undo_rec_get_pars(
return(ptr);
}
-/**************************************************************************
-Reads from an undo log record a stored column value. */
+/**********************************************************************//**
+Reads from an undo log record a stored column value.
+@return remaining part of undo log record after reading these values */
static
byte*
trx_undo_rec_get_col_val(
/*=====================*/
- /* out: remaining part of undo log record after
- reading these values */
- byte* ptr, /* in: pointer to remaining part of undo log record */
- byte** field, /* out: pointer to stored field */
- ulint* len, /* out: length of the field, or UNIV_SQL_NULL */
- ulint* orig_len)/* out: original length of the locally
+ byte* ptr, /*!< in: pointer to remaining part of undo log record */
+ byte** field, /*!< out: pointer to stored field */
+ ulint* len, /*!< out: length of the field, or UNIV_SQL_NULL */
+ ulint* orig_len)/*!< out: original length of the locally
stored part of an externally stored column, or 0 */
{
*len = mach_read_compressed(ptr);
@@ -367,23 +367,22 @@ trx_undo_rec_get_col_val(
return(ptr);
}
-/***********************************************************************
-Builds a row reference from an undo log record. */
+/*******************************************************************//**
+Builds a row reference from an undo log record.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_get_row_ref(
/*=====================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part of a copy of an undo log
+ byte* ptr, /*!< in: remaining part of a copy of an undo log
record, at the start of the row reference;
NOTE that this copy of the undo log record must
be preserved as long as the row reference is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- dtuple_t** ref, /* out, own: row reference */
- mem_heap_t* heap) /* in: memory heap from which the memory
+ dict_index_t* index, /*!< in: clustered index */
+ dtuple_t** ref, /*!< out, own: row reference */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
{
ulint ref_len;
@@ -414,17 +413,16 @@ trx_undo_rec_get_row_ref(
return(ptr);
}
-/***********************************************************************
-Skips a row reference from an undo log record. */
+/*******************************************************************//**
+Skips a row reference from an undo log record.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_skip_row_ref(
/*======================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record, at the start of the row reference */
- dict_index_t* index) /* in: clustered index */
+ dict_index_t* index) /*!< in: clustered index */
{
ulint ref_len;
ulint i;
@@ -445,21 +443,21 @@ trx_undo_rec_skip_row_ref(
return(ptr);
}
-/**************************************************************************
+/**********************************************************************//**
Fetch a prefix of an externally stored column, for writing to the undo log
-of an update or delete marking of a clustered index record. */
+of an update or delete marking of a clustered index record.
+@return ext_buf */
static
byte*
trx_undo_page_fetch_ext(
/*====================*/
- /* out: ext_buf */
- byte* ext_buf, /* in: a buffer of
+ byte* ext_buf, /*!< in: a buffer of
REC_MAX_INDEX_COL_LEN
+ BTR_EXTERN_FIELD_REF_SIZE */
- ulint zip_size, /* compressed page size in bytes,
+ ulint zip_size, /*!< compressed page size in bytes,
or 0 for uncompressed BLOB */
- const byte* field, /* in: an externally stored column */
- ulint* len) /* in: length of field;
+ const byte* field, /*!< in: an externally stored column */
+ ulint* len) /*!< in: length of field;
out: used length of ext_buf */
{
/* Fetch the BLOB. */
@@ -475,25 +473,25 @@ trx_undo_page_fetch_ext(
return(ext_buf);
}
-/**************************************************************************
-Writes to the undo log a prefix of an externally stored column. */
+/**********************************************************************//**
+Writes to the undo log a prefix of an externally stored column.
+@return undo log position */
static
byte*
trx_undo_page_report_modify_ext(
/*============================*/
- /* out: undo log position */
- byte* ptr, /* in: undo log position,
+ byte* ptr, /*!< in: undo log position,
at least 15 bytes must be available */
- byte* ext_buf, /* in: a buffer of
+ byte* ext_buf, /*!< in: a buffer of
REC_MAX_INDEX_COL_LEN
+ BTR_EXTERN_FIELD_REF_SIZE,
or NULL when should not fetch
a longer prefix */
- ulint zip_size, /* compressed page size in bytes,
+ ulint zip_size, /*!< compressed page size in bytes,
or 0 for uncompressed BLOB */
- const byte** field, /* in/out: the locally stored part of
+ const byte** field, /*!< in/out: the locally stored part of
the externally stored column */
- ulint* len) /* in/out: length of field, in bytes */
+ ulint* len) /*!< in/out: length of field, in bytes */
{
if (ext_buf) {
/* If an ordering column is externally stored, we will
@@ -516,29 +514,28 @@ trx_undo_page_report_modify_ext(
return(ptr);
}
-/**************************************************************************
+/**********************************************************************//**
Reports in the undo log of an update or delete marking of a clustered index
-record. */
+record.
+@return byte offset of the inserted undo log entry on the page if
+succeed, 0 if fail */
static
ulint
trx_undo_page_report_modify(
/*========================*/
- /* out: byte offset of the inserted
- undo log entry on the page if succeed,
- 0 if fail */
- page_t* undo_page, /* in: undo log page */
- trx_t* trx, /* in: transaction */
- dict_index_t* index, /* in: clustered index where update or
+ page_t* undo_page, /*!< in: undo log page */
+ trx_t* trx, /*!< in: transaction */
+ dict_index_t* index, /*!< in: clustered index where update or
delete marking is done */
- const rec_t* rec, /* in: clustered index record which
+ const rec_t* rec, /*!< in: clustered index record which
has NOT yet been modified */
- const ulint* offsets, /* in: rec_get_offsets(rec, index) */
- const upd_t* update, /* in: update vector which tells the
+ const ulint* 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 */
- ulint cmpl_info, /* in: compiler info on secondary
+ ulint cmpl_info, /*!< in: compiler info on secondary
index updates */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_table_t* table;
ulint first_free;
@@ -549,7 +546,7 @@ trx_undo_page_report_modify(
ulint type_cmpl;
byte* type_cmpl_ptr;
ulint i;
- dulint trx_id;
+ trx_id_t trx_id;
ibool ignore_prefix = FALSE;
byte ext_buf[REC_MAX_INDEX_COL_LEN
+ BTR_EXTERN_FIELD_REF_SIZE];
@@ -825,21 +822,20 @@ trx_undo_page_report_modify(
return(first_free);
}
-/**************************************************************************
+/**********************************************************************//**
Reads from an undo log update record the system field values of the old
-version. */
+version.
+@return remaining part of undo log record after reading these values */
UNIV_INTERN
byte*
trx_undo_update_rec_get_sys_cols(
/*=============================*/
- /* out: remaining part of undo log
- record after reading these values */
- byte* ptr, /* in: remaining part of undo log
- record after reading general
- parameters */
- dulint* trx_id, /* out: trx id */
- dulint* roll_ptr, /* out: roll ptr */
- ulint* info_bits) /* out: info bits state */
+ byte* ptr, /*!< in: remaining part of undo
+ log record after reading
+ general parameters */
+ trx_id_t* trx_id, /*!< out: trx id */
+ roll_ptr_t* roll_ptr, /*!< out: roll ptr */
+ ulint* info_bits) /*!< out: info bits state */
{
/* Read the state of the info bits */
*info_bits = mach_read_from_1(ptr);
@@ -856,16 +852,15 @@ trx_undo_update_rec_get_sys_cols(
return(ptr);
}
-/**************************************************************************
-Reads from an update undo log record the number of updated fields. */
+/**********************************************************************//**
+Reads from an update undo log record the number of updated fields.
+@return remaining part of undo log record after reading this value */
UNIV_INLINE
byte*
trx_undo_update_rec_get_n_upd_fields(
/*=================================*/
- /* out: remaining part of undo log record after
- reading this value */
- byte* ptr, /* in: pointer to remaining part of undo log record */
- ulint* n) /* out: number of fields */
+ byte* ptr, /*!< in: pointer to remaining part of undo log record */
+ ulint* n) /*!< out: number of fields */
{
*n = mach_read_compressed(ptr);
ptr += mach_get_compressed_size(*n);
@@ -873,16 +868,15 @@ trx_undo_update_rec_get_n_upd_fields(
return(ptr);
}
-/**************************************************************************
-Reads from an update undo log record a stored field number. */
+/**********************************************************************//**
+Reads from an update undo log record a stored field number.
+@return remaining part of undo log record after reading this value */
UNIV_INLINE
byte*
trx_undo_update_rec_get_field_no(
/*=============================*/
- /* out: remaining part of undo log record after
- reading this value */
- byte* ptr, /* in: pointer to remaining part of undo log record */
- ulint* field_no)/* out: field number */
+ byte* ptr, /*!< in: pointer to remaining part of undo log record */
+ ulint* field_no)/*!< out: field number */
{
*field_no = mach_read_compressed(ptr);
ptr += mach_get_compressed_size(*field_no);
@@ -890,34 +884,33 @@ trx_undo_update_rec_get_field_no(
return(ptr);
}
-/***********************************************************************
-Builds an update vector based on a remaining part of an undo log record. */
+/*******************************************************************//**
+Builds an update vector based on a remaining part of an undo log record.
+@return remaining part of the record, NULL if an error detected, which
+means that the record is corrupted */
UNIV_INTERN
byte*
trx_undo_update_rec_get_update(
/*===========================*/
- /* out: remaining part of the record,
- NULL if an error detected, which means that
- the record is corrupted */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record, after reading the row reference
NOTE that this copy of the undo log record must
be preserved as long as the update vector is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- ulint type, /* in: TRX_UNDO_UPD_EXIST_REC,
+ dict_index_t* index, /*!< in: clustered index */
+ ulint type, /*!< in: TRX_UNDO_UPD_EXIST_REC,
TRX_UNDO_UPD_DEL_REC, or
TRX_UNDO_DEL_MARK_REC; in the last case,
only trx id and roll ptr fields are added to
the update vector */
- dulint trx_id, /* in: transaction id from this undo record */
- dulint roll_ptr,/* in: roll pointer from this undo record */
- ulint info_bits,/* in: info bits from this undo record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap, /* in: memory heap from which the memory
+ trx_id_t trx_id, /*!< in: transaction id from this undo record */
+ roll_ptr_t roll_ptr,/*!< in: roll pointer from this undo record */
+ ulint info_bits,/*!< in: info bits from this undo record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
- upd_t** upd) /* out, own: update vector */
+ upd_t** upd) /*!< out, own: update vector */
{
upd_field_t* upd_field;
upd_t* update;
@@ -1012,28 +1005,27 @@ trx_undo_update_rec_get_update(
return(ptr);
}
-/***********************************************************************
+/*******************************************************************//**
Builds a partial row from an update undo log record. It contains the
-columns which occur as ordering in any index of the table. */
+columns which occur as ordering in any index of the table.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_get_partial_row(
/*=========================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record of a suitable type, at the start of
the stored index columns;
NOTE that this copy of the undo log record must
be preserved as long as the partial row is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- dtuple_t** row, /* out, own: partial row */
- ibool ignore_prefix, /* in: flag to indicate if we
+ dict_index_t* index, /*!< in: clustered index */
+ dtuple_t** row, /*!< out, own: partial row */
+ ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
only in the assertion. */
- mem_heap_t* heap) /* in: memory heap from which the memory
+ mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
{
const byte* end_ptr;
@@ -1092,15 +1084,16 @@ trx_undo_rec_get_partial_row(
return(ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
+/***********************************************************************//**
Erases the unused undo log page end. */
static
void
trx_undo_erase_page_end(
/*====================*/
- page_t* undo_page, /* in: undo page whose end to erase */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo page whose end to erase */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint first_free;
@@ -1112,17 +1105,17 @@ trx_undo_erase_page_end(
mlog_write_initial_log_record(undo_page, MLOG_UNDO_ERASE_END, mtr);
}
-/***************************************************************
-Parses a redo log record of erasing of an undo page end. */
+/***********************************************************//**
+Parses a redo log record of erasing of an undo page end.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_erase_page_end(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(ptr && end_ptr);
@@ -1136,33 +1129,34 @@ trx_undo_parse_erase_page_end(
return(ptr);
}
-/***************************************************************************
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
Writes information to an undo log about an insert, update, or a delete marking
of a clustered index record. This information is used in a rollback of the
transaction and in consistent reads that must look to the history of this
-transaction. */
+transaction.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
trx_undo_report_row_operation(
/*==========================*/
- /* out: DB_SUCCESS or error code */
- ulint flags, /* in: if BTR_NO_UNDO_LOG_FLAG bit is
+ ulint flags, /*!< in: if BTR_NO_UNDO_LOG_FLAG bit is
set, does nothing */
- ulint op_type, /* in: TRX_UNDO_INSERT_OP or
+ ulint op_type, /*!< in: TRX_UNDO_INSERT_OP or
TRX_UNDO_MODIFY_OP */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* clust_entry, /* in: in the case of an insert,
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* clust_entry, /*!< in: in the case of an insert,
index entry to insert into the
clustered index, otherwise NULL */
- const upd_t* update, /* in: in the case of an update,
+ const upd_t* update, /*!< in: in the case of an update,
the update vector, otherwise NULL */
- ulint cmpl_info, /* in: compiler info on secondary
+ ulint cmpl_info, /*!< in: compiler info on secondary
index updates */
- const rec_t* rec, /* in: in case of an update or delete
+ const rec_t* rec, /*!< in: in case of an update or delete
marking, the record in the clustered
index, otherwise NULL */
- dulint* roll_ptr) /* out: rollback pointer to the
+ roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the
inserted undo log record,
ut_dulint_zero if BTR_NO_UNDO_LOG
flag was specified */
@@ -1324,22 +1318,22 @@ trx_undo_report_row_operation(
/*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*/
-/**********************************************************************
+/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
-the undo log record exists. */
+the undo log record exists.
+@return own: copy of the record */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_undo_rec_low(
/*======================*/
- /* out, own: copy of the record */
- dulint roll_ptr, /* in: roll pointer to record */
- mem_heap_t* heap) /* in: memory heap where copied */
+ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
trx_undo_rec_t* undo_rec;
ulint rseg_id;
ulint page_no;
ulint offset;
- page_t* undo_page;
+ const page_t* undo_page;
trx_rseg_t* rseg;
ibool is_insert;
mtr_t mtr;
@@ -1360,24 +1354,24 @@ trx_undo_get_undo_rec_low(
return(undo_rec);
}
-/**********************************************************************
-Copies an undo record to heap. */
+/******************************************************************//**
+Copies an undo record to heap.
+
+NOTE: the caller must have latches on the clustered index page and
+purge_view.
+
+@return DB_SUCCESS, or DB_MISSING_HISTORY if the undo log has been
+truncated and we cannot fetch the old version */
UNIV_INTERN
ulint
trx_undo_get_undo_rec(
/*==================*/
- /* out: DB_SUCCESS, or
- DB_MISSING_HISTORY if the undo log
- has been truncated and we cannot
- fetch the old version; NOTE: the
- caller must have latches on the
- clustered index page and purge_view */
- dulint roll_ptr, /* in: roll pointer to record */
- dulint trx_id, /* in: id of the trx that generated
+ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
+ trx_id_t trx_id, /*!< in: id of the trx that generated
the roll pointer: it points to an
undo log of this transaction */
- trx_undo_rec_t** undo_rec, /* out, own: copy of the record */
- mem_heap_t* heap) /* in: memory heap where copied */
+ trx_undo_rec_t** undo_rec, /*!< out, own: copy of the record */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
@@ -1396,30 +1390,29 @@ trx_undo_get_undo_rec(
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Build a previous version of a clustered index record. This function checks
that the caller has a latch on the index page of the clustered index record
and an s-latch on the purge_view. This guarantees that the stack of versions
-is locked all the way down to the purge_view. */
+is locked all the way down to the purge_view.
+@return DB_SUCCESS, or DB_MISSING_HISTORY if the previous version is
+earlier than purge_view, which means that it may have been removed,
+DB_ERROR if corrupted record */
UNIV_INTERN
ulint
trx_undo_prev_version_build(
/*========================*/
- /* out: DB_SUCCESS, or DB_MISSING_HISTORY if
- the previous version is not >= purge_view,
- which means that it may have been removed,
- DB_ERROR if corrupted record */
- const rec_t* index_rec,/* in: clustered index record in the
+ const rec_t* index_rec,/*!< in: clustered index record in the
index tree */
mtr_t* index_mtr __attribute__((unused)),
- /* in: mtr which contains the latch to
+ /*!< in: mtr which contains the latch to
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: rec_get_offsets(rec, index) */
- mem_heap_t* heap, /* in: memory heap from which the memory
+ const rec_t* rec, /*!< in: version of a clustered index record */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint* offsets,/*!< in: 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
+ rec_t** old_vers)/*!< out, own: previous version, or NULL if
rec is the first inserted version, or if
history data has been deleted (an error),
or if the purge COULD have removed the version
@@ -1427,13 +1420,13 @@ trx_undo_prev_version_build(
{
trx_undo_rec_t* undo_rec = NULL;
dtuple_t* entry;
- dulint rec_trx_id;
+ trx_id_t rec_trx_id;
ulint type;
- dulint undo_no;
+ undo_no_t undo_no;
dulint table_id;
- dulint trx_id;
- dulint roll_ptr;
- dulint old_roll_ptr;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
+ roll_ptr_t old_roll_ptr;
upd_t* update;
byte* ptr;
ulint info_bits;
@@ -1579,7 +1572,7 @@ trx_undo_prev_version_build(
/* We have to set the appropriate extern storage bits in the
old version of the record: the extern bits in rec for those
- fields that update does NOT update, as well as the the bits for
+ fields that update does NOT update, as well as the bits for
those fields that update updates to become externally stored
fields. Store the info: */
@@ -1605,3 +1598,4 @@ trx_undo_prev_version_build(
return(DB_SUCCESS);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/trx/trx0roll.c b/storage/xtradb/trx/trx0roll.c
index 5f3cb15a254..c925478cdf4 100644
--- a/storage/xtradb/trx/trx0roll.c
+++ b/storage/xtradb/trx/trx0roll.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0roll.c
Transaction rollback
Created 3/26/1996 Heikki Tuuri
@@ -43,32 +44,32 @@ Created 3/26/1996 Heikki Tuuri
#include "lock0lock.h"
#include "pars0pars.h"
-/* This many pages must be undone before a truncate is tried within rollback */
+/** This many pages must be undone before a truncate is tried within
+rollback */
#define TRX_ROLL_TRUNC_THRESHOLD 1
-/* In crash recovery, the current trx to be rolled back */
+/** In crash recovery, the current trx to be rolled back */
static trx_t* trx_roll_crash_recv_trx = NULL;
-/* In crash recovery we set this to the undo n:o of the current trx to be
+/** In crash recovery we set this to the undo n:o of the current trx to be
rolled back. Then we can print how many % the rollback has progressed. */
static ib_int64_t trx_roll_max_undo_no;
-/* Auxiliary variable which tells the previous progress % we printed */
+/** Auxiliary variable which tells the previous progress % we printed */
static ulint trx_roll_progress_printed_pct;
-/***********************************************************************
-Rollback a transaction used in MySQL. */
+/*******************************************************************//**
+Rollback a transaction used in MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_general_rollback_for_mysql(
/*===========================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- ibool partial,/* in: TRUE if partial rollback requested */
- trx_savept_t* savept) /* in: pointer to savepoint undo number, if
- partial rollback requested */
+ trx_t* trx, /*!< in: transaction handle */
+ trx_savept_t* savept) /*!< in: pointer to savepoint undo number, if
+ partial rollback requested, or NULL for
+ complete rollback */
{
-#ifndef UNIV_HOTBACKUP
mem_heap_t* heap;
que_thr_t* thr;
roll_node_t* roll_node;
@@ -84,9 +85,8 @@ trx_general_rollback_for_mysql(
roll_node = roll_node_create(heap);
- roll_node->partial = partial;
-
- if (partial) {
+ if (savept) {
+ roll_node->partial = TRUE;
roll_node->savept = *savept;
}
@@ -120,23 +120,16 @@ trx_general_rollback_for_mysql(
srv_active_wake_master_thread();
return((int) trx->error_state);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(DB_FAIL);
-#endif /* UNIV_HOTBACKUP */
}
-/***********************************************************************
-Rollback a transaction used in MySQL. */
+/*******************************************************************//**
+Rollback a transaction used in MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_rollback_for_mysql(
/*===================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
int err;
@@ -151,21 +144,21 @@ trx_rollback_for_mysql(
the transaction object does not have an InnoDB session object, and we
set a dummy session that we use for all MySQL transactions. */
- err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ err = trx_general_rollback_for_mysql(trx, NULL);
trx->op_info = "";
return(err);
}
-/***********************************************************************
-Rollback the latest SQL statement for MySQL. */
+/*******************************************************************//**
+Rollback the latest SQL statement for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_rollback_last_sql_stat_for_mysql(
/*=================================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
int err;
@@ -176,8 +169,7 @@ trx_rollback_last_sql_stat_for_mysql(
trx->op_info = "rollback of SQL statement";
- err = trx_general_rollback_for_mysql(trx, TRUE,
- &(trx->last_sql_stat_start));
+ err = trx_general_rollback_for_mysql(trx, &trx->last_sql_stat_start);
/* The following call should not be needed, but we play safe: */
trx_mark_sql_stat_end(trx);
@@ -186,14 +178,14 @@ trx_rollback_last_sql_stat_for_mysql(
return(err);
}
-/***********************************************************************
+/*******************************************************************//**
Frees a single savepoint struct. */
UNIV_INTERN
void
trx_roll_savepoint_free(
/*=====================*/
- trx_t* trx, /* in: transaction handle */
- trx_named_savept_t* savep) /* in: savepoint to free */
+ trx_t* trx, /*!< in: transaction handle */
+ trx_named_savept_t* savep) /*!< in: savepoint to free */
{
ut_a(savep != NULL);
ut_a(UT_LIST_GET_LEN(trx->trx_savepoints) > 0);
@@ -203,15 +195,15 @@ trx_roll_savepoint_free(
mem_free(savep);
}
-/***********************************************************************
+/*******************************************************************//**
Frees savepoint structs starting from savep, if savep == NULL then
free all savepoints. */
-
+UNIV_INTERN
void
trx_roll_savepoints_free(
/*=====================*/
- trx_t* trx, /* in: transaction handle */
- trx_named_savept_t* savep) /* in: free all savepoints > this one;
+ trx_t* trx, /*!< in: transaction handle */
+ trx_named_savept_t* savep) /*!< in: free all savepoints > this one;
if this is NULL, free all savepoints
of trx */
{
@@ -232,24 +224,22 @@ trx_roll_savepoints_free(
}
}
-/***********************************************************************
+/*******************************************************************//**
Rolls back a transaction back to a named savepoint. Modifications after the
savepoint are undone but InnoDB does NOT release the corresponding locks
which are stored in memory. If a lock is 'implicit', that is, a new inserted
row holds a lock where the lock information is carried by the trx id stored in
the row, these locks are naturally released in the rollback. Savepoints which
-were set after this savepoint are deleted. */
+were set after this savepoint are deleted.
+@return if no savepoint of the name found then DB_NO_SAVEPOINT,
+otherwise DB_SUCCESS */
UNIV_INTERN
ulint
trx_rollback_to_savepoint_for_mysql(
/*================================*/
- /* out: if no savepoint
- of the name found then
- DB_NO_SAVEPOINT,
- otherwise DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name, /* in: savepoint name */
- ib_int64_t* mysql_binlog_cache_pos) /* out: the MySQL binlog cache
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name, /*!< in: savepoint name */
+ ib_int64_t* mysql_binlog_cache_pos) /*!< out: the MySQL binlog cache
position corresponding to this
savepoint; MySQL needs this
information to remove the
@@ -290,7 +280,7 @@ trx_rollback_to_savepoint_for_mysql(
trx->op_info = "rollback to a savepoint";
- err = trx_general_rollback_for_mysql(trx, TRUE, &(savep->savept));
+ err = trx_general_rollback_for_mysql(trx, &savep->savept);
/* Store the current undo_no of the transaction so that we know where
to roll back if we have to roll back the next SQL statement: */
@@ -302,19 +292,19 @@ trx_rollback_to_savepoint_for_mysql(
return(err);
}
-/***********************************************************************
+/*******************************************************************//**
Creates a named savepoint. If the transaction is not yet started, starts it.
If there is already a savepoint of the same name, this call erases that old
savepoint and replaces it with a new. Savepoints are deleted in a transaction
-commit or rollback. */
+commit or rollback.
+@return always DB_SUCCESS */
UNIV_INTERN
ulint
trx_savepoint_for_mysql(
/*====================*/
- /* out: always DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name, /* in: savepoint name */
- ib_int64_t binlog_cache_pos) /* in: MySQL binlog cache
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name, /*!< in: savepoint name */
+ ib_int64_t binlog_cache_pos) /*!< in: MySQL binlog cache
position corresponding to this
connection at the time of the
savepoint */
@@ -360,19 +350,17 @@ trx_savepoint_for_mysql(
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Releases only the named savepoint. Savepoints which were set after this
-savepoint are left as is. */
+savepoint are left as is.
+@return if no savepoint of the name found then DB_NO_SAVEPOINT,
+otherwise DB_SUCCESS */
UNIV_INTERN
ulint
trx_release_savepoint_for_mysql(
/*============================*/
- /* out: if no savepoint
- of the name found then
- DB_NO_SAVEPOINT,
- otherwise DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name) /* in: savepoint name */
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name) /*!< in: savepoint name */
{
trx_named_savept_t* savep;
@@ -390,29 +378,28 @@ trx_release_savepoint_for_mysql(
return(DB_NO_SAVEPOINT);
}
-/***********************************************************************
+/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
-in crash recovery. */
+in crash recovery.
+@return TRUE if trx is an incomplete transaction that is being rolled
+back in crash recovery */
UNIV_INTERN
ibool
trx_is_recv(
/*========*/
- /* out: TRUE if trx is an incomplete
- transaction that is being rolled back
- in crash recovery */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
{
return(trx == trx_roll_crash_recv_trx);
}
-/***********************************************************************
-Returns a transaction savepoint taken at this point in time. */
+/*******************************************************************//**
+Returns a transaction savepoint taken at this point in time.
+@return savepoint */
UNIV_INTERN
trx_savept_t
trx_savept_take(
/*============*/
- /* out: savepoint */
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
trx_savept_t savept;
@@ -421,13 +408,13 @@ trx_savept_take(
return(savept);
}
-/***********************************************************************
+/*******************************************************************//**
Roll back an active transaction. */
static
void
trx_rollback_active(
/*================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
mem_heap_t* heap;
que_fork_t* fork;
@@ -541,32 +528,30 @@ trx_rollback_active(
trx_roll_crash_recv_trx = NULL;
}
-/***********************************************************************
+/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
-transaction was not yet committed, then we roll it back.
-Note: this is done in a background thread. */
+transaction was not yet committed, then we roll it back. */
UNIV_INTERN
-os_thread_ret_t
-trx_rollback_or_clean_all_recovered(
-/*================================*/
- /* out: a dummy parameter */
- void* arg __attribute__((unused)))
- /* in: a dummy parameter required by
- os_thread_create */
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+ ibool all) /*!< in: FALSE=roll back dictionary transactions;
+ TRUE=roll back all non-PREPARED transactions */
{
trx_t* trx;
mutex_enter(&kernel_mutex);
- if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+ if (!UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+ goto leave_function;
+ }
+ if (all) {
fprintf(stderr,
"InnoDB: Starting in background the rollback"
" of uncommitted transactions\n");
- } else {
- goto leave_function;
}
mutex_exit(&kernel_mutex);
@@ -595,18 +580,42 @@ loop:
goto loop;
case TRX_ACTIVE:
- mutex_exit(&kernel_mutex);
- trx_rollback_active(trx);
- goto loop;
+ if (all || trx_get_dict_operation(trx)
+ != TRX_DICT_OP_NONE) {
+ mutex_exit(&kernel_mutex);
+ trx_rollback_active(trx);
+ goto loop;
+ }
}
}
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Rollback of non-prepared transactions completed\n");
+ if (all) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Rollback of non-prepared"
+ " transactions completed\n");
+ }
leave_function:
mutex_exit(&kernel_mutex);
+}
+
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery. If the transaction already was
+committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back.
+Note: this is done in a background thread.
+@return a dummy parameter */
+UNIV_INTERN
+os_thread_ret_t
+trx_rollback_or_clean_all_recovered(
+/*================================*/
+ void* arg __attribute__((unused)))
+ /*!< in: a dummy parameter required by
+ os_thread_create */
+{
+ trx_rollback_or_clean_recovered(TRUE);
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
@@ -616,8 +625,9 @@ leave_function:
OS_THREAD_DUMMY_RETURN;
}
-/***********************************************************************
-Creates an undo number array. */
+/*******************************************************************//**
+Creates an undo number array.
+@return own: undo number array */
UNIV_INTERN
trx_undo_arr_t*
trx_undo_arr_create(void)
@@ -646,29 +656,28 @@ trx_undo_arr_create(void)
return(arr);
}
-/***********************************************************************
+/*******************************************************************//**
Frees an undo number array. */
UNIV_INTERN
void
trx_undo_arr_free(
/*==============*/
- trx_undo_arr_t* arr) /* in: undo number array */
+ trx_undo_arr_t* arr) /*!< in: undo number array */
{
ut_ad(arr->n_used == 0);
mem_heap_free(arr->heap);
}
-/***********************************************************************
-Stores info of an undo log record to the array if it is not stored yet. */
+/*******************************************************************//**
+Stores info of an undo log record to the array if it is not stored yet.
+@return FALSE if the record already existed in the array */
static
ibool
trx_undo_arr_store_info(
/*====================*/
- /* out: FALSE if the record already existed in the
- array */
- trx_t* trx, /* in: transaction */
- dulint undo_no)/* in: undo number */
+ trx_t* trx, /*!< in: transaction */
+ undo_no_t undo_no)/*!< in: undo number */
{
trx_undo_inf_t* cell;
trx_undo_inf_t* stored_here;
@@ -721,14 +730,14 @@ trx_undo_arr_store_info(
}
}
-/***********************************************************************
+/*******************************************************************//**
Removes an undo number from the array. */
static
void
trx_undo_arr_remove_info(
/*=====================*/
- trx_undo_arr_t* arr, /* in: undo number array */
- dulint undo_no)/* in: undo number */
+ trx_undo_arr_t* arr, /*!< in: undo number array */
+ undo_no_t undo_no)/*!< in: undo number */
{
trx_undo_inf_t* cell;
ulint n_used;
@@ -755,19 +764,18 @@ trx_undo_arr_remove_info(
}
}
-/***********************************************************************
-Gets the biggest undo number in an array. */
+/*******************************************************************//**
+Gets the biggest undo number in an array.
+@return biggest value, ut_dulint_zero if the array is empty */
static
-dulint
+undo_no_t
trx_undo_arr_get_biggest(
/*=====================*/
- /* out: biggest value, ut_dulint_zero if
- the array is empty */
- trx_undo_arr_t* arr) /* in: undo number array */
+ trx_undo_arr_t* arr) /*!< in: undo number array */
{
trx_undo_inf_t* cell;
ulint n_used;
- dulint biggest;
+ undo_no_t biggest;
ulint n;
ulint i;
@@ -792,17 +800,17 @@ trx_undo_arr_get_biggest(
}
}
-/***************************************************************************
+/***********************************************************************//**
Tries truncate the undo logs. */
UNIV_INTERN
void
trx_roll_try_truncate(
/*==================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
trx_undo_arr_t* arr;
- dulint limit;
- dulint biggest;
+ undo_no_t limit;
+ undo_no_t biggest;
ut_ad(mutex_own(&(trx->undo_mutex)));
ut_ad(mutex_own(&((trx->rseg)->mutex)));
@@ -831,17 +839,17 @@ trx_roll_try_truncate(
}
}
-/***************************************************************************
+/***********************************************************************//**
Pops the topmost undo log record in a single undo log and updates the info
-about the topmost record in the undo log memory struct. */
+about the topmost record in the undo log memory struct.
+@return undo log record, the page s-latched */
static
trx_undo_rec_t*
trx_roll_pop_top_rec(
/*=================*/
- /* out: undo log record, the page s-latched */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log */
- mtr_t* mtr) /* in: mtr */
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* undo_page;
ulint offset;
@@ -880,30 +888,29 @@ trx_roll_pop_top_rec(
return(undo_page + offset);
}
-/************************************************************************
+/********************************************************************//**
Pops the topmost record when the two undo logs of a transaction are seen
as a single stack of records ordered by their undo numbers. Inserts the
undo number of the popped undo record to the array of currently processed
undo numbers in the transaction. When the query thread finishes processing
-of this undo record, it must be released with trx_undo_rec_release. */
+of this undo record, it must be released with trx_undo_rec_release.
+@return undo log record copied to heap, NULL if none left, or if the
+undo number of the top record would be less than the limit */
UNIV_INTERN
trx_undo_rec_t*
trx_roll_pop_top_rec_of_trx(
/*========================*/
- /* out: undo log record copied to heap, NULL
- if none left, or if the undo number of the
- top record would be less than the limit */
- trx_t* trx, /* in: transaction */
- dulint limit, /* in: least undo number we need */
- dulint* roll_ptr,/* out: roll pointer to undo record */
- mem_heap_t* heap) /* in: memory heap where copied */
+ trx_t* trx, /*!< in: transaction */
+ undo_no_t limit, /*!< in: least undo number we need */
+ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
trx_undo_t* undo;
trx_undo_t* ins_undo;
trx_undo_t* upd_undo;
trx_undo_rec_t* undo_rec;
trx_undo_rec_t* undo_rec_copy;
- dulint undo_no;
+ undo_no_t undo_no;
ibool is_insert;
trx_rseg_t* rseg;
ulint progress_pct;
@@ -1013,17 +1020,17 @@ try_again:
return(undo_rec_copy);
}
-/************************************************************************
+/********************************************************************//**
Reserves an undo log record for a query thread to undo. This should be
called if the query thread gets the undo log record not using the pop
-function above. */
+function above.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
trx_undo_rec_reserve(
/*=================*/
- /* out: TRUE if succeeded */
- trx_t* trx, /* in: transaction */
- dulint undo_no)/* in: undo number of the record */
+ trx_t* trx, /*!< in/out: transaction */
+ undo_no_t undo_no)/*!< in: undo number of the record */
{
ibool ret;
@@ -1036,14 +1043,14 @@ trx_undo_rec_reserve(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Releases a reserved undo record. */
UNIV_INTERN
void
trx_undo_rec_release(
/*=================*/
- trx_t* trx, /* in: transaction */
- dulint undo_no)/* in: undo number */
+ trx_t* trx, /*!< in/out: transaction */
+ undo_no_t undo_no)/*!< in: undo number */
{
trx_undo_arr_t* arr;
@@ -1056,15 +1063,15 @@ trx_undo_rec_release(
mutex_exit(&(trx->undo_mutex));
}
-/*************************************************************************
+/*********************************************************************//**
Starts a rollback operation. */
UNIV_INTERN
void
trx_rollback(
/*=========*/
- trx_t* trx, /* in: transaction */
- trx_sig_t* sig, /* in: signal starting the rollback */
- que_thr_t** next_thr)/* in/out: next query thread to run;
+ trx_t* trx, /*!< in: transaction */
+ trx_sig_t* sig, /*!< in: signal starting the rollback */
+ que_thr_t** next_thr)/*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1127,17 +1134,17 @@ trx_rollback(
}
}
-/********************************************************************
+/****************************************************************//**
Builds an undo 'query' graph for a transaction. The actual rollback is
performed by executing this query graph like a query subprocedure call.
The reply about the completion of the rollback will be sent by this
-graph. */
+graph.
+@return own: the query graph */
UNIV_INTERN
que_t*
trx_roll_graph_build(
/*=================*/
- /* out, own: the query graph */
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
mem_heap_t* heap;
que_fork_t* fork;
@@ -1159,14 +1166,14 @@ trx_roll_graph_build(
return(fork);
}
-/*************************************************************************
+/*********************************************************************//**
Finishes error processing after the necessary partial rollback has been
done. */
static
void
trx_finish_error_processing(
/*========================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
trx_sig_t* sig;
trx_sig_t* next_sig;
@@ -1189,14 +1196,14 @@ trx_finish_error_processing(
trx->que_state = TRX_QUE_RUNNING;
}
-/*************************************************************************
+/*********************************************************************//**
Finishes a partial rollback operation. */
static
void
trx_finish_partial_rollback_off_kernel(
/*===================================*/
- trx_t* trx, /* in: transaction */
- que_thr_t** next_thr)/* in/out: next query thread to run;
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t** next_thr)/*!< in/out: next query thread to run;
if the value which is passed in is a pointer
to a NULL pointer, then the calling function
can start running a new query thread; if this
@@ -1217,15 +1224,15 @@ trx_finish_partial_rollback_off_kernel(
trx->que_state = TRX_QUE_RUNNING;
}
-/********************************************************************
+/****************************************************************//**
Finishes a transaction rollback. */
UNIV_INTERN
void
trx_finish_rollback_off_kernel(
/*===========================*/
- que_t* graph, /* in: undo graph which can now be freed */
- trx_t* trx, /* in: transaction */
- que_thr_t** next_thr)/* in/out: next query thread to run;
+ que_t* graph, /*!< in: undo graph which can now be freed */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t** next_thr)/*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1285,14 +1292,14 @@ trx_finish_rollback_off_kernel(
}
}
-/*************************************************************************
-Creates a rollback command node struct. */
+/*********************************************************************//**
+Creates a rollback command node struct.
+@return own: rollback node struct */
UNIV_INTERN
roll_node_t*
roll_node_create(
/*=============*/
- /* out, own: rollback node struct */
- mem_heap_t* heap) /* in: mem heap where created */
+ mem_heap_t* heap) /*!< in: mem heap where created */
{
roll_node_t* node;
@@ -1305,14 +1312,14 @@ roll_node_create(
return(node);
}
-/***************************************************************
-Performs an execution step for a rollback command node in a query graph. */
+/***********************************************************//**
+Performs an execution step for a rollback command node in a query graph.
+@return query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_rollback_step(
/*==============*/
- /* out: query thread to run next, or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
roll_node_t* node;
ulint sig_no;
diff --git a/storage/xtradb/trx/trx0rseg.c b/storage/xtradb/trx/trx0rseg.c
index db5efd65eb3..8d754788e2a 100644
--- a/storage/xtradb/trx/trx0rseg.c
+++ b/storage/xtradb/trx/trx0rseg.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0rseg.c
Rollback segment
Created 3/26/1996 Heikki Tuuri
@@ -33,14 +34,14 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "trx0purge.h"
-/**********************************************************************
-Looks for a rollback segment, based on the rollback segment id. */
+/******************************************************************//**
+Looks for a rollback segment, based on the rollback segment id.
+@return rollback segment */
UNIV_INTERN
trx_rseg_t*
trx_rseg_get_on_id(
/*===============*/
- /* out: rollback segment */
- ulint id) /* in: rollback segment id */
+ ulint id) /*!< in: rollback segment id */
{
trx_rseg_t* rseg;
@@ -55,21 +56,20 @@ trx_rseg_get_on_id(
return(rseg);
}
-/********************************************************************
+/****************************************************************//**
Creates a rollback segment header. This function is called only when
-a new rollback segment is created in the database. */
+a new rollback segment is created in the database.
+@return page number of the created segment, FIL_NULL if fail */
UNIV_INTERN
ulint
trx_rseg_header_create(
/*===================*/
- /* out: page number of the created segment,
- FIL_NULL if fail */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint max_size, /* in: max size in pages */
- ulint* slot_no, /* out: rseg id == slot number in trx sys */
- mtr_t* mtr) /* in: mtr */
+ ulint max_size, /*!< in: max size in pages */
+ ulint* slot_no, /*!< out: rseg id == slot number in trx sys */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint page_no;
trx_rsegf_t* rsegf;
@@ -131,22 +131,65 @@ trx_rseg_header_create(
return(page_no);
}
+/***********************************************************************//**
+Free's an instance of the rollback segment in memory. */
+UNIV_INTERN
+void
+trx_rseg_mem_free(
+/*==============*/
+ trx_rseg_t* rseg) /* in, own: instance to free */
+{
+ trx_undo_t* undo;
+
+ mutex_free(&rseg->mutex);
+
+ /* There can't be any active transactions. */
+ ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0);
+ ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0);
+
+ undo = UT_LIST_GET_FIRST(rseg->update_undo_cached);
+
+ while (undo != NULL) {
+ trx_undo_t* prev_undo = undo;
+
+ undo = UT_LIST_GET_NEXT(undo_list, undo);
+ UT_LIST_REMOVE(undo_list, rseg->update_undo_cached, prev_undo);
+
+ trx_undo_mem_free(prev_undo);
+ }
+
+ undo = UT_LIST_GET_FIRST(rseg->insert_undo_cached);
+
+ while (undo != NULL) {
+ trx_undo_t* prev_undo = undo;
+
+ undo = UT_LIST_GET_NEXT(undo_list, undo);
+ UT_LIST_REMOVE(undo_list, rseg->insert_undo_cached, prev_undo);
+
+ trx_undo_mem_free(prev_undo);
+ }
+
+ trx_sys_set_nth_rseg(trx_sys, rseg->id, NULL);
+
+ mem_free(rseg);
+}
+
/***************************************************************************
Creates and initializes a rollback segment object. The values for the
fields are read from the header. The object is inserted to the rseg
list of the trx system object and a pointer is inserted in the rseg
-array in the trx system object. */
+array in the trx system object.
+@return own: rollback segment object */
static
trx_rseg_t*
trx_rseg_mem_create(
/*================*/
- /* out, own: rollback segment object */
- ulint id, /* in: rollback segment id */
- ulint space, /* in: space where the segment placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint id, /*!< in: rollback segment id */
+ ulint space, /*!< in: space where the segment placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the segment header */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number of the segment header */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_rsegf_t* rseg_header;
trx_rseg_t* rseg;
@@ -207,15 +250,15 @@ trx_rseg_mem_create(
return(rseg);
}
-/*************************************************************************
+/*********************************************************************//**
Creates the memory copies for rollback segments and initializes the
rseg list and array in trx_sys at a database startup. */
UNIV_INTERN
void
trx_rseg_list_and_array_init(
/*=========================*/
- trx_sysf_t* sys_header, /* in: trx system header */
- mtr_t* mtr) /* in: mtr */
+ trx_sysf_t* sys_header, /*!< in: trx system header */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
ulint page_no;
@@ -244,18 +287,17 @@ trx_rseg_list_and_array_init(
}
}
-/********************************************************************
-Creates a new rollback segment to the database. */
+/****************************************************************//**
+Creates a new rollback segment to the database.
+@return the created segment object, NULL if fail */
UNIV_INTERN
trx_rseg_t*
trx_rseg_create(
/*============*/
- /* out: the created segment object, NULL if
- fail */
- ulint space, /* in: space id */
- ulint max_size, /* in: max size in pages */
- ulint* id, /* out: rseg id */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space id */
+ ulint max_size, /*!< in: max size in pages */
+ ulint* id, /*!< out: rseg id */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint flags;
ulint zip_size;
diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c
index b80a50738c0..8ea34a8c81c 100644
--- a/storage/xtradb/trx/trx0sys.c
+++ b/storage/xtradb/trx/trx0sys.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0sys.c
Transaction system
Created 3/26/1996 Heikki Tuuri
@@ -28,62 +29,74 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0sys.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#include "fsp0fsp.h"
-#include "mtr0mtr.h"
+#include "mtr0log.h"
+#include "mtr0log.h"
#include "trx0trx.h"
#include "trx0rseg.h"
#include "trx0undo.h"
#include "srv0srv.h"
#include "trx0purge.h"
#include "log0log.h"
+#include "log0recv.h"
#include "os0file.h"
+#include "read0read.h"
-/* The file format tag structure with id and name. */
+/** The file format tag structure with id and name. */
struct file_format_struct {
- ulint id; /* id of the file format */
- const char* name; /* text representation of the
+ ulint id; /*!< id of the file format */
+ const char* name; /*!< text representation of the
file format */
- mutex_t mutex; /* covers changes to the above
+ mutex_t mutex; /*!< covers changes to the above
fields */
};
+/** The file format tag */
typedef struct file_format_struct file_format_t;
-/* The transaction system */
+/** The transaction system */
UNIV_INTERN trx_sys_t* trx_sys = NULL;
+/** The doublewrite buffer */
UNIV_INTERN trx_doublewrite_t* trx_doublewrite = NULL;
-/* The following is set to TRUE when we are upgrading from the old format data
-files to the new >= 4.1.x format multiple tablespaces format data files */
-
+/** The following is set to TRUE when we are upgrading from pre-4.1
+format data files to the multiple tablespaces format data files */
UNIV_INTERN ibool trx_doublewrite_must_reset_space_ids = FALSE;
+/** Set to TRUE when the doublewrite buffer is being created */
+UNIV_INTERN ibool trx_doublewrite_buf_is_being_created = FALSE;
-/* The following is TRUE when we are using the database in the new format,
-i.e., we have successfully upgraded, or have created a new database
-installation */
-
+/** The following is TRUE when we are using the database in the
+post-4.1 format, i.e., we have successfully upgraded, or have created
+a new database installation */
UNIV_INTERN ibool trx_sys_multiple_tablespace_format = FALSE;
-/* In a MySQL replication slave, in crash recovery we store the master log
-file name and position here. We have successfully got the updates to InnoDB
-up to this position. If .._pos is -1, it means no crash recovery was needed,
-or there was no master log position info inside InnoDB. */
-
+/** In a MySQL replication slave, in crash recovery we store the master log
+file name and position here. */
+/* @{ */
+/** Master binlog file name */
UNIV_INTERN char trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
+/** Master binlog file position. We have successfully got the updates
+up to this position. -1 means that no crash recovery was needed, or
+there was no master log position info inside InnoDB.*/
UNIV_INTERN ib_int64_t trx_sys_mysql_master_log_pos = -1;
+/* @} */
UNIV_INTERN char trx_sys_mysql_relay_log_name[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
UNIV_INTERN ib_int64_t trx_sys_mysql_relay_log_pos = -1;
-/* If this MySQL server uses binary logging, after InnoDB has been inited
+/** If this MySQL server uses binary logging, after InnoDB has been inited
and if it has done a crash recovery, we store the binlog file name and position
-here. If .._pos is -1, it means there was no binlog position info inside
-InnoDB. */
-
+here. */
+/* @{ */
+/** Binlog file name */
UNIV_INTERN char trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
+/** Binlog file position, or -1 if unknown */
UNIV_INTERN ib_int64_t trx_sys_mysql_bin_log_pos = -1;
+/* @} */
+#endif /* !UNIV_HOTBACKUP */
-/* List of animal names representing file format. */
+/** List of animal names representing file format. */
static const char* file_format_name_map[] = {
"Antelope",
"Barracuda",
@@ -113,24 +126,25 @@ static const char* file_format_name_map[] = {
"Zebra"
};
-/* The number of elements in the file format name array. */
+/** The number of elements in the file format name array. */
static const ulint FILE_FORMAT_NAME_N
= sizeof(file_format_name_map) / sizeof(file_format_name_map[0]);
-/* This is used to track the maximum file format id known to InnoDB. It's
+#ifndef UNIV_HOTBACKUP
+/** This is used to track the maximum file format id known to InnoDB. It's
updated via SET GLOBAL innodb_file_format_check = 'x' or when we open
or create a table. */
static file_format_t file_format_max;
-/********************************************************************
-Determines if a page number is located inside the doublewrite buffer. */
+/****************************************************************//**
+Determines if a page number is located inside the doublewrite buffer.
+@return TRUE if the location is inside the two blocks of the
+doublewrite buffer */
UNIV_INTERN
ibool
trx_doublewrite_page_inside(
/*========================*/
- /* out: TRUE if the location is inside
- the two blocks of the doublewrite buffer */
- ulint page_no) /* in: page number */
+ ulint page_no) /*!< in: page number */
{
if (trx_doublewrite == NULL) {
@@ -152,13 +166,13 @@ trx_doublewrite_page_inside(
return(FALSE);
}
-/********************************************************************
+/****************************************************************//**
Creates or initialializes the doublewrite buffer at a database start. */
static
void
trx_doublewrite_init(
/*=================*/
- byte* doublewrite) /* in: pointer to the doublewrite buf
+ byte* doublewrite) /*!< in: pointer to the doublewrite buf
header on trx sys page */
{
trx_doublewrite = mem_alloc(sizeof(trx_doublewrite_t));
@@ -186,7 +200,7 @@ trx_doublewrite_init(
2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * sizeof(void*));
}
-/********************************************************************
+/****************************************************************//**
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
multiple tablespace format. */
UNIV_INTERN
@@ -221,7 +235,7 @@ trx_sys_mark_upgraded_to_multiple_tablespaces(void)
trx_sys_multiple_tablespace_format = TRUE;
}
-/********************************************************************
+/****************************************************************//**
Creates the doublewrite buffer to a new InnoDB installation. The header of the
doublewrite buffer is placed on the trx system header page. */
UNIV_INTERN
@@ -247,6 +261,7 @@ trx_sys_create_doublewrite_buf(void)
start_again:
mtr_start(&mtr);
+ trx_doublewrite_buf_is_being_created = TRUE;
block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
RW_X_LATCH, &mtr);
@@ -262,6 +277,7 @@ start_again:
trx_doublewrite_init(doublewrite);
mtr_commit(&mtr);
+ trx_doublewrite_buf_is_being_created = FALSE;
} else {
fprintf(stderr,
"InnoDB: Doublewrite buffer not found:"
@@ -337,15 +353,8 @@ start_again:
buf_block_dbg_add_level(new_block,
SYNC_NO_ORDER_CHECK);
- /* Make a dummy change to the page to ensure it will
- be written to disk in a flush */
-
- mlog_write_ulint(buf_block_get_frame(new_block)
- + FIL_PAGE_DATA,
- TRX_SYS_DOUBLEWRITE_MAGIC_N,
- MLOG_4BYTES, &mtr);
-
if (i == FSP_EXTENT_SIZE / 2) {
+ ut_a(page_no == FSP_EXTENT_SIZE);
mlog_write_ulint(doublewrite
+ TRX_SYS_DOUBLEWRITE_BLOCK1,
page_no, MLOG_4BYTES, &mtr);
@@ -355,6 +364,7 @@ start_again:
page_no, MLOG_4BYTES, &mtr);
} else if (i == FSP_EXTENT_SIZE / 2
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
+ ut_a(page_no == 2 * FSP_EXTENT_SIZE);
mlog_write_ulint(doublewrite
+ TRX_SYS_DOUBLEWRITE_BLOCK2,
page_no, MLOG_4BYTES, &mtr);
@@ -394,7 +404,7 @@ start_again:
}
}
-/********************************************************************
+/****************************************************************//**
At a database startup initializes the doublewrite buffer memory structure if
we already have a doublewrite buffer created in the data files. If we are
upgrading to an InnoDB version which supports multiple tablespaces, then this
@@ -405,7 +415,7 @@ UNIV_INTERN
void
trx_sys_doublewrite_init_or_restore_pages(
/*======================================*/
- ibool restore_corrupt_pages)
+ ibool restore_corrupt_pages) /*!< in: TRUE=restore pages */
{
byte* buf;
byte* read_buf;
@@ -544,6 +554,12 @@ trx_sys_doublewrite_init_or_restore_pages(
zip_size ? zip_size : UNIV_PAGE_SIZE,
read_buf, NULL);
+ if (srv_recovery_stats && recv_recovery_is_on()) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_doublewrite_check_pages++;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
/* Check if the page is corrupt */
if (UNIV_UNLIKELY
@@ -591,6 +607,13 @@ trx_sys_doublewrite_init_or_restore_pages(
zip_size, page_no, 0,
zip_size ? zip_size : UNIV_PAGE_SIZE,
page, NULL);
+
+ if (srv_recovery_stats && recv_recovery_is_on()) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_doublewrite_overwrite_pages++;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
fprintf(stderr,
"InnoDB: Recovered the page from"
" the doublewrite buffer.\n");
@@ -606,14 +629,14 @@ leave_func:
ut_free(unaligned_read_buf);
}
-/********************************************************************
-Checks that trx is in the trx list. */
+/****************************************************************//**
+Checks that trx is in the trx list.
+@return TRUE if is in */
UNIV_INTERN
ibool
trx_in_trx_list(
/*============*/
- /* out: TRUE if is in */
- trx_t* in_trx) /* in: trx */
+ trx_t* in_trx) /*!< in: trx */
{
trx_t* trx;
@@ -634,7 +657,7 @@ trx_in_trx_list(
return(FALSE);
}
-/*********************************************************************
+/*****************************************************************//**
Writes the value of max_trx_id to the file based trx system header. */
UNIV_INTERN
void
@@ -655,7 +678,7 @@ trx_sys_flush_max_trx_id(void)
mtr_commit(&mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Updates the offset information about the end of the MySQL binlog entry
which corresponds to the transaction just being committed. In a MySQL
replication slave updates the latest master binlog position up to which
@@ -664,11 +687,11 @@ UNIV_INTERN
void
trx_sys_update_mysql_binlog_offset(
/*===============================*/
- const char* file_name_in,/* in: MySQL log file name */
- ib_int64_t offset, /* in: position in that log file */
- ulint field, /* in: offset of the MySQL log info field in
+ const char* file_name_in,/*!< in: MySQL log file name */
+ ib_int64_t offset, /*!< in: position in that log file */
+ ulint field, /*!< in: offset of the MySQL log info field in
the trx sys header */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_sysf_t* sys_header;
const char* file_name;
@@ -721,42 +744,7 @@ trx_sys_update_mysql_binlog_offset(
MLOG_4BYTES, mtr);
}
-#ifdef UNIV_HOTBACKUP
-/*********************************************************************
-Prints to stderr the MySQL binlog info in the system header if the
-magic number shows it valid. */
-UNIV_INTERN
-void
-trx_sys_print_mysql_binlog_offset_from_page(
-/*========================================*/
- const byte* page) /* in: buffer containing the trx
- system header page, i.e., page number
- TRX_SYS_PAGE_NO in the tablespace */
-{
- const trx_sysf_t* sys_header;
-
- sys_header = page + TRX_SYS;
-
- if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
- == TRX_SYS_MYSQL_LOG_MAGIC_N) {
-
- fprintf(stderr,
- "ibbackup: Last MySQL binlog file position %lu %lu,"
- " file name %s\n",
- (ulong) mach_read_from_4(
- sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
- (ulong) mach_read_from_4(
- sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
- sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_NAME);
- }
-}
-#endif /* UNIV_HOTBACKUP */
-
-/*********************************************************************
+/*****************************************************************//**
Stores the MySQL binlog offset info in the trx system header if
the magic number shows it valid, and print the info to stderr */
UNIV_INTERN
@@ -806,7 +794,7 @@ trx_sys_print_mysql_binlog_offset(void)
mtr_commit(&mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Prints to stderr the MySQL master log offset info in the trx system header if
the magic number shows it valid. */
UNIV_INTERN
@@ -886,14 +874,14 @@ trx_sys_print_mysql_master_log_pos(void)
mtr_commit(&mtr);
}
-/********************************************************************
-Looks for a free slot for a rollback segment in the trx system file copy. */
+/****************************************************************//**
+Looks for a free slot for a rollback segment in the trx system file copy.
+@return slot index or ULINT_UNDEFINED if not found */
UNIV_INTERN
ulint
trx_sysf_rseg_find_free(
/*====================*/
- /* out: slot index or ULINT_UNDEFINED if not found */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_sysf_t* sys_header;
ulint page_no;
@@ -916,14 +904,14 @@ trx_sysf_rseg_find_free(
return(ULINT_UNDEFINED);
}
-/*********************************************************************
+/*****************************************************************//**
Creates the file page for the transaction system. This function is called only
at the database creation, before trx_sys_init. */
static
void
trx_sysf_create(
/*============*/
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_sysf_t* sys_header;
ulint slot_no;
@@ -993,7 +981,7 @@ trx_sysf_create(
mutex_exit(&kernel_mutex);
}
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the central memory structures for the transaction
system. This is called when the database is started. */
UNIV_INTERN
@@ -1081,7 +1069,7 @@ trx_sys_init_at_db_start(void)
mtr_commit(&mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the transaction system at the database creation. */
UNIV_INTERN
void
@@ -1124,15 +1112,15 @@ trx_sys_create_extra_rseg(
mtr_commit(&mtr);
}
-/*********************************************************************
-Update the file format tag. */
+/*****************************************************************//**
+Update the file format tag.
+@return always TRUE */
static
ibool
trx_sys_file_format_max_write(
/*==========================*/
- /* out: always TRUE */
- ulint format_id, /* in: file format id */
- const char** name) /* out: max file format name, can
+ ulint format_id, /*!< in: file format id */
+ const char** name) /*!< out: max file format name, can
be NULL */
{
mtr_t mtr;
@@ -1166,14 +1154,13 @@ trx_sys_file_format_max_write(
return(TRUE);
}
-/*********************************************************************
-Read the file format tag. */
+/*****************************************************************//**
+Read the file format tag.
+@return the file format or ULINT_UNDEFINED if not set. */
static
ulint
trx_sys_file_format_max_read(void)
/*==============================*/
- /* out: the file format or
- ULINT_UNDEFINED if not set. */
{
mtr_t mtr;
const byte* ptr;
@@ -1205,29 +1192,29 @@ trx_sys_file_format_max_read(void)
return(format_id);
}
-/*********************************************************************
-Get the name representation of the file format from its id. */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
UNIV_INTERN
const char*
trx_sys_file_format_id_to_name(
/*===========================*/
- /* out: pointer to the name */
- const ulint id) /* in: id of the file format */
+ const ulint id) /*!< in: id of the file format */
{
ut_a(id < FILE_FORMAT_NAME_N);
return(file_format_name_map[id]);
}
-/*********************************************************************
+/*****************************************************************//**
Check for the max file format tag stored on disk. Note: If max_format_id
-is == DICT_TF_FORMAT_MAX + 1 then we only print a warning. */
+is == DICT_TF_FORMAT_MAX + 1 then we only print a warning.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
trx_sys_file_format_max_check(
/*==========================*/
- /* out: DB_SUCCESS or error code */
- ulint max_format_id) /* in: max format id to check */
+ ulint max_format_id) /*!< in: max format id to check */
{
ulint format_id;
@@ -1273,16 +1260,16 @@ trx_sys_file_format_max_check(
return(DB_SUCCESS);
}
-/*********************************************************************
+/*****************************************************************//**
Set the file format id unconditionally except if it's already the
-same value. */
+same value.
+@return TRUE if value updated */
UNIV_INTERN
ibool
trx_sys_file_format_max_set(
/*========================*/
- /* out: TRUE if value updated */
- ulint format_id, /* in: file format id */
- const char** name) /* out: max file format name or
+ ulint format_id, /*!< in: file format id */
+ const char** name) /*!< out: max file format name or
NULL if not needed. */
{
ibool ret = FALSE;
@@ -1302,7 +1289,7 @@ trx_sys_file_format_max_set(
return(ret);
}
-/************************************************************************
+/********************************************************************//**
Tags the system table space with minimum format id if it has not been
tagged yet.
WARNING: This function is only called during the startup and AFTER the
@@ -1322,17 +1309,16 @@ trx_sys_file_format_tag_init(void)
}
}
-/************************************************************************
+/********************************************************************//**
Update the file format tag in the system tablespace only if the given
-format id is greater than the known max id. */
+format id is greater than the known max id.
+@return TRUE if format_id was bigger than the known max id */
UNIV_INTERN
ibool
trx_sys_file_format_max_upgrade(
/*============================*/
- /* out: TRUE if format_id was
- bigger than the known max id */
- const char** name, /* out: max file format name */
- ulint format_id) /* in: file format identifier */
+ const char** name, /*!< out: max file format name */
+ ulint format_id) /*!< in: file format identifier */
{
ibool ret = FALSE;
@@ -1352,18 +1338,18 @@ trx_sys_file_format_max_upgrade(
return(ret);
}
-/*********************************************************************
-Get the name representation of the file format from its id. */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the max format name */
UNIV_INTERN
const char*
trx_sys_file_format_max_get(void)
/*=============================*/
- /* out: pointer to the max format name */
{
return(file_format_max.name);
}
-/*********************************************************************
+/*****************************************************************//**
Initializes the tablespace tag system. */
UNIV_INTERN
void
@@ -1380,7 +1366,7 @@ trx_sys_file_format_init(void)
file_format_max.id);
}
-/*********************************************************************
+/*****************************************************************//**
Closes the tablespace tag system. */
UNIV_INTERN
void
@@ -1389,3 +1375,312 @@ trx_sys_file_format_close(void)
{
/* Does nothing at the moment */
}
+#else /* !UNIV_HOTBACKUP */
+/*****************************************************************//**
+Prints to stderr the MySQL binlog info in the system header if the
+magic number shows it valid. */
+UNIV_INTERN
+void
+trx_sys_print_mysql_binlog_offset_from_page(
+/*========================================*/
+ const byte* page) /*!< in: buffer containing the trx
+ system header page, i.e., page number
+ TRX_SYS_PAGE_NO in the tablespace */
+{
+ const trx_sysf_t* sys_header;
+
+ sys_header = page + TRX_SYS;
+
+ if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
+ == TRX_SYS_MYSQL_LOG_MAGIC_N) {
+
+ fprintf(stderr,
+ "ibbackup: Last MySQL binlog file position %lu %lu,"
+ " file name %s\n",
+ (ulong) mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
+ (ulong) mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_NAME);
+ }
+}
+
+
+/* THESE ARE COPIED FROM NON-HOTBACKUP PART OF THE INNODB SOURCE TREE
+ (This code duplicaton should be fixed at some point!)
+*/
+
+#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
+/* The offset of the file format tag on the trx system header page */
+#define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
+/* We use these random constants to reduce the probability of reading
+garbage (from previous versions) that maps to an actual format id. We
+use these as bit masks at the time of reading and writing from/to disk. */
+#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
+#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
+
+/* END OF COPIED DEFINITIONS */
+
+
+/*****************************************************************//**
+Reads the file format id from the first system table space file.
+Even if the call succeeds and returns TRUE, the returned format id
+may be ULINT_UNDEFINED signalling that the format id was not present
+in the data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_file_format_id(
+/*========================*/
+ const char *pathname, /*!< in: pathname of the first system
+ table space file */
+ ulint *format_id) /*!< out: file format of the system table
+ space */
+{
+ os_file_t file;
+ ibool success;
+ byte buf[UNIV_PAGE_SIZE * 2];
+ page_t* page = ut_align(buf, UNIV_PAGE_SIZE);
+ const byte* ptr;
+ dulint file_format_id;
+
+ *format_id = ULINT_UNDEFINED;
+
+ file = os_file_create_simple_no_error_handling(
+ pathname,
+ OS_FILE_OPEN,
+ OS_FILE_READ_ONLY,
+ &success
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read system tablespace file format,\n"
+" ibbackup: but could not open the tablespace file %s!\n",
+ pathname
+ );
+ return(FALSE);
+ }
+
+ /* Read the page on which file format is stored */
+
+ success = os_file_read_no_error_handling(
+ file, page, TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE, 0, UNIV_PAGE_SIZE
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read system table space file format,\n"
+" ibbackup: but failed to read the tablespace file %s!\n",
+ pathname
+ );
+ os_file_close(file);
+ return(FALSE);
+ }
+ os_file_close(file);
+
+ /* get the file format from the page */
+ ptr = page + TRX_SYS_FILE_FORMAT_TAG;
+ file_format_id = mach_read_from_8(ptr);
+
+ *format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
+
+ if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
+ || *format_id >= FILE_FORMAT_NAME_N) {
+
+ /* Either it has never been tagged, or garbage in it. */
+ *format_id = ULINT_UNDEFINED;
+ return(TRUE);
+ }
+
+ return(TRUE);
+}
+
+
+/*****************************************************************//**
+Reads the file format id from the given per-table data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_pertable_file_format_id(
+/*=================================*/
+ const char *pathname, /*!< in: pathname of a per-table
+ datafile */
+ ulint *format_id) /*!< out: file format of the per-table
+ data file */
+{
+ os_file_t file;
+ ibool success;
+ byte buf[UNIV_PAGE_SIZE * 2];
+ page_t* page = ut_align(buf, UNIV_PAGE_SIZE);
+ const byte* ptr;
+ ib_uint32_t flags;
+
+ *format_id = ULINT_UNDEFINED;
+
+ file = os_file_create_simple_no_error_handling(
+ pathname,
+ OS_FILE_OPEN,
+ OS_FILE_READ_ONLY,
+ &success
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read per-table tablespace format,\n"
+" ibbackup: but could not open the tablespace file %s!\n",
+ pathname
+ );
+ return(FALSE);
+ }
+
+ /* Read the first page of the per-table datafile */
+
+ success = os_file_read_no_error_handling(
+ file, page, 0, 0, UNIV_PAGE_SIZE
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to per-table data file format,\n"
+" ibbackup: but failed to read the tablespace file %s!\n",
+ pathname
+ );
+ os_file_close(file);
+ return(FALSE);
+ }
+ os_file_close(file);
+
+ /* get the file format from the page */
+ ptr = page + 54;
+ flags = mach_read_from_4(ptr);
+ if (flags == 0) {
+ /* file format is Antelope */
+ *format_id = 0;
+ return (TRUE);
+ } else if (flags & 1) {
+ /* tablespace flags are ok */
+ *format_id = (flags / 32) % 128;
+ return (TRUE);
+ } else {
+ /* bad tablespace flags */
+ return(FALSE);
+ }
+}
+
+
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
+UNIV_INTERN
+const char*
+trx_sys_file_format_id_to_name(
+/*===========================*/
+ const ulint id) /*!< in: id of the file format */
+{
+ if (!(id < FILE_FORMAT_NAME_N)) {
+ /* unknown id */
+ return ("Unknown");
+ }
+
+ return(file_format_name_map[id]);
+}
+
+#endif /* !UNIV_HOTBACKUP */
+
+/*********************************************************************
+Shutdown/Close the transaction system. */
+UNIV_INTERN
+void
+trx_sys_close(void)
+/*===============*/
+{
+ trx_rseg_t* rseg;
+ read_view_t* view;
+
+ ut_ad(trx_sys != NULL);
+
+ /* Check that all read views are closed except read view owned
+ by a purge. */
+
+ if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
+ fprintf(stderr,
+ "InnoDB: Error: all read views were not closed"
+ " before shutdown:\n"
+ "InnoDB: %lu read views open \n",
+ UT_LIST_GET_LEN(trx_sys->view_list) - 1);
+ }
+
+ sess_close(trx_dummy_sess);
+ trx_dummy_sess = NULL;
+
+ trx_purge_sys_close();
+
+ mutex_enter(&kernel_mutex);
+
+ /* Free the double write data structures. */
+ ut_a(trx_doublewrite != NULL);
+ ut_free(trx_doublewrite->write_buf_unaligned);
+ trx_doublewrite->write_buf_unaligned = NULL;
+
+ mem_free(trx_doublewrite->buf_block_arr);
+ trx_doublewrite->buf_block_arr = NULL;
+
+ mutex_free(&trx_doublewrite->mutex);
+ mem_free(trx_doublewrite);
+ trx_doublewrite = NULL;
+
+ /* There can't be any active transactions. */
+ rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
+
+ while (rseg != NULL) {
+ trx_rseg_t* prev_rseg = rseg;
+
+ rseg = UT_LIST_GET_NEXT(rseg_list, prev_rseg);
+ UT_LIST_REMOVE(rseg_list, trx_sys->rseg_list, prev_rseg);
+
+ trx_rseg_mem_free(prev_rseg);
+ }
+
+ view = UT_LIST_GET_FIRST(trx_sys->view_list);
+
+ while (view != NULL) {
+ read_view_t* prev_view = view;
+
+ view = UT_LIST_GET_NEXT(view_list, prev_view);
+
+ /* Views are allocated from the trx_sys->global_read_view_heap.
+ So, we simply remove the element here. */
+ UT_LIST_REMOVE(view_list, trx_sys->view_list, prev_view);
+ }
+
+ ut_a(UT_LIST_GET_LEN(trx_sys->trx_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->rseg_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
+
+ mem_free(trx_sys);
+
+ trx_sys = NULL;
+ mutex_exit(&kernel_mutex);
+}
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index 0f81bba0427..69bc5c6b18b 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0trx.c
The transaction
Created 3/26/1996 Heikki Tuuri
@@ -43,47 +44,47 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0xa.h"
#include "ha_prototypes.h"
-/* Dummy session used currently in MySQL interface */
+/** Dummy session used currently in MySQL interface */
UNIV_INTERN sess_t* trx_dummy_sess = NULL;
-/* Number of transactions currently allocated for MySQL: protected by
+/** Number of transactions currently allocated for MySQL: protected by
the kernel mutex */
UNIV_INTERN ulint trx_n_mysql_transactions = 0;
-/*****************************************************************
+/*************************************************************//**
Set detailed error message for the transaction. */
UNIV_INTERN
void
trx_set_detailed_error(
/*===================*/
- trx_t* trx, /* in: transaction struct */
- const char* msg) /* in: detailed error message */
+ trx_t* trx, /*!< in: transaction struct */
+ const char* msg) /*!< in: detailed error message */
{
ut_strlcpy(trx->detailed_error, msg, sizeof(trx->detailed_error));
}
-/*****************************************************************
+/*************************************************************//**
Set detailed error message for the transaction from a file. Note that the
file is rewinded before reading from it. */
UNIV_INTERN
void
trx_set_detailed_error_from_file(
/*=============================*/
- trx_t* trx, /* in: transaction struct */
- FILE* file) /* in: file to read message from */
+ trx_t* trx, /*!< in: transaction struct */
+ FILE* file) /*!< in: file to read message from */
{
os_file_read_string(file, trx->detailed_error,
sizeof(trx->detailed_error));
}
-/********************************************************************
-Creates and initializes a transaction object. */
+/****************************************************************//**
+Creates and initializes a transaction object.
+@return own: the transaction */
UNIV_INTERN
trx_t*
trx_create(
/*=======*/
- /* out, own: the transaction */
- sess_t* sess) /* in: session */
+ sess_t* sess) /*!< in: session */
{
trx_t* trx;
@@ -177,6 +178,15 @@ trx_create(
trx->global_read_view = NULL;
trx->read_view = NULL;
+ trx->io_reads = 0;
+ trx->io_read = 0;
+ trx->io_reads_wait_timer = 0;
+ trx->lock_que_wait_timer = 0;
+ trx->innodb_que_wait_timer = 0;
+ trx->distinct_page_access = 0;
+ trx->distinct_page_access_hash = NULL;
+ trx->take_stats = FALSE;
+
/* Set X/Open XA transaction identification to NULL */
memset(&trx->xid, 0, sizeof(trx->xid));
trx->xid.formatID = -1;
@@ -190,13 +200,13 @@ trx_create(
return(trx);
}
-/************************************************************************
-Creates a transaction object for MySQL. */
+/********************************************************************//**
+Creates a transaction object for MySQL.
+@return own: transaction object */
UNIV_INTERN
trx_t*
trx_allocate_for_mysql(void)
/*========================*/
- /* out, own: transaction object */
{
trx_t* trx;
@@ -214,16 +224,21 @@ trx_allocate_for_mysql(void)
trx->mysql_process_no = os_proc_get_number();
+ if (innobase_get_slow_log() && trx->take_stats) {
+ trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
+ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
+ }
+
return(trx);
}
-/************************************************************************
-Creates a transaction object for background operations by the master thread. */
+/********************************************************************//**
+Creates a transaction object for background operations by the master thread.
+@return own: transaction object */
UNIV_INTERN
trx_t*
trx_allocate_for_background(void)
/*=============================*/
- /* out, own: transaction object */
{
trx_t* trx;
@@ -236,13 +251,13 @@ trx_allocate_for_background(void)
return(trx);
}
-/************************************************************************
+/********************************************************************//**
Releases the search latch if trx has reserved it. */
UNIV_INTERN
void
trx_search_latch_release_if_reserved(
/*=================================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
if (trx->has_search_latch) {
rw_lock_s_unlock(&btr_search_latch);
@@ -251,13 +266,13 @@ trx_search_latch_release_if_reserved(
}
}
-/************************************************************************
+/********************************************************************//**
Frees a transaction object. */
UNIV_INTERN
void
trx_free(
/*=====*/
- trx_t* trx) /* in, own: trx object */
+ trx_t* trx) /*!< in, own: trx object */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -337,14 +352,20 @@ trx_free(
mem_free(trx);
}
-/************************************************************************
+/********************************************************************//**
Frees a transaction object for MySQL. */
UNIV_INTERN
void
trx_free_for_mysql(
/*===============*/
- trx_t* trx) /* in, own: trx object */
+ trx_t* trx) /*!< in, own: trx object */
{
+ if (trx->distinct_page_access_hash)
+ {
+ mem_free(trx->distinct_page_access_hash);
+ trx->distinct_page_access_hash= NULL;
+ }
+
mutex_enter(&kernel_mutex);
UT_LIST_REMOVE(mysql_trx_list, trx_sys->mysql_trx_list, trx);
@@ -358,14 +379,20 @@ trx_free_for_mysql(
mutex_exit(&kernel_mutex);
}
-/************************************************************************
+/********************************************************************//**
Frees a transaction object of a background operation of the master thread. */
UNIV_INTERN
void
trx_free_for_background(
/*====================*/
- trx_t* trx) /* in, own: trx object */
+ trx_t* trx) /*!< in, own: trx object */
{
+ if (trx->distinct_page_access_hash)
+ {
+ mem_free(trx->distinct_page_access_hash);
+ trx->distinct_page_access_hash= NULL;
+ }
+
mutex_enter(&kernel_mutex);
trx_free(trx);
@@ -373,7 +400,7 @@ trx_free_for_background(
mutex_exit(&kernel_mutex);
}
-/********************************************************************
+/****************************************************************//**
Inserts the trx handle in the trx system trx list in the right position.
The list is sorted on the trx id so that the biggest id is at the list
start. This function is used at the database startup to insert incomplete
@@ -382,7 +409,7 @@ static
void
trx_list_insert_ordered(
/*====================*/
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
trx_t* trx2;
@@ -413,7 +440,7 @@ trx_list_insert_ordered(
}
}
-/********************************************************************
+/****************************************************************//**
Creates trx objects for transactions and initializes the trx list of
trx_sys at database start. Rollback segment and undo log lists must
already exist when this function is called, because the lists of
@@ -601,14 +628,14 @@ trx_lists_init_at_db_start(void)
}
}
-/**********************************************************************
+/******************************************************************//**
Assigns a rollback segment to a transaction in a round-robin fashion.
-Skips the SYSTEM rollback segment if another is available. */
+Skips the SYSTEM rollback segment if another is available.
+@return assigned rollback segment id */
UNIV_INLINE
ulint
trx_assign_rseg(void)
/*=================*/
- /* out: assigned rollback segment id */
{
trx_rseg_t* rseg = trx_sys->latest_rseg;
@@ -635,15 +662,15 @@ loop:
return(rseg->id);
}
-/********************************************************************
-Starts a new transaction. */
+/****************************************************************//**
+Starts a new transaction.
+@return TRUE */
UNIV_INTERN
ibool
trx_start_low(
/*==========*/
- /* out: TRUE */
- trx_t* trx, /* in: transaction */
- ulint rseg_id)/* in: rollback segment id; if ULINT_UNDEFINED
+ trx_t* trx, /*!< in: transaction */
+ ulint rseg_id)/*!< in: rollback segment id; if ULINT_UNDEFINED
is passed, the system chooses the rollback segment
automatically in a round-robin fashion */
{
@@ -686,15 +713,15 @@ trx_start_low(
return(TRUE);
}
-/********************************************************************
-Starts a new transaction. */
+/****************************************************************//**
+Starts a new transaction.
+@return TRUE */
UNIV_INTERN
ibool
trx_start(
/*======*/
- /* out: TRUE */
- trx_t* trx, /* in: transaction */
- ulint rseg_id)/* in: rollback segment id; if ULINT_UNDEFINED
+ trx_t* trx, /*!< in: transaction */
+ ulint rseg_id)/*!< in: rollback segment id; if ULINT_UNDEFINED
is passed, the system chooses the rollback segment
automatically in a round-robin fashion */
{
@@ -717,13 +744,13 @@ trx_start(
return(ret);
}
-/********************************************************************
+/****************************************************************//**
Commits a transaction. */
UNIV_INTERN
void
trx_commit_off_kernel(
/*==================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
page_t* update_hdr_page;
ib_uint64_t lsn = 0;
@@ -819,7 +846,7 @@ trx_commit_off_kernel(
in exactly the same order as commit lsn's, if the transactions
have different rollback segments. To get exactly the same
order we should hold the kernel mutex up to this point,
- adding to to the contention of the kernel mutex. However, if
+ adding to the contention of the kernel mutex. However, if
a transaction T2 is able to see modifications made by
a transaction T1, T2 will always get a bigger transaction
number and a bigger commit lsn than T1. */
@@ -907,11 +934,11 @@ trx_commit_off_kernel(
there are > 2 users in the database. Then at least 2 users can
gather behind one doing the physical log write to disk.
- If we are calling trx_commit() under MySQL's binlog mutex, we
+ If we are calling trx_commit() under prepare_commit_mutex, we
will delay possible log write and flush to a separate function
trx_commit_complete_for_mysql(), which is only called when the
- thread has released the binlog mutex. This is to make the
- group commit algorithm to work. Otherwise, the MySQL binlog
+ thread has released the mutex. This is to make the
+ group commit algorithm to work. Otherwise, the prepare_commit
mutex would serialize all commits and prevent a group of
transactions from gathering. */
@@ -963,15 +990,15 @@ trx_commit_off_kernel(
UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
}
-/********************************************************************
+/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
UNIV_INTERN
void
trx_cleanup_at_db_startup(
/*======================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
if (trx->insert_undo != NULL) {
@@ -986,16 +1013,16 @@ trx_cleanup_at_db_startup(
UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
}
-/************************************************************************
+/********************************************************************//**
Assigns a read view for a consistent read query. All the consistent reads
within the same transaction will get the same read view, which is created
-when this function is first called for a new started transaction. */
+when this function is first called for a new started transaction.
+@return consistent read view */
UNIV_INTERN
read_view_t*
trx_assign_read_view(
/*=================*/
- /* out: consistent read view */
- trx_t* trx) /* in: active transaction */
+ trx_t* trx) /*!< in: active transaction */
{
ut_ad(trx->conc_state == TRX_ACTIVE);
@@ -1016,14 +1043,14 @@ trx_assign_read_view(
return(trx->read_view);
}
-/********************************************************************
+/****************************************************************//**
Commits a transaction. NOTE that the kernel mutex is temporarily released. */
static
void
trx_handle_commit_sig_off_kernel(
/*=============================*/
- trx_t* trx, /* in: transaction */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1060,7 +1087,7 @@ trx_handle_commit_sig_off_kernel(
trx->que_state = TRX_QUE_RUNNING;
}
-/***************************************************************
+/***********************************************************//**
The transaction must be in the TRX_QUE_LOCK_WAIT state. Puts it to
the TRX_QUE_RUNNING state and releases query threads which were
waiting for a lock in the wait_thrs list. */
@@ -1068,9 +1095,12 @@ UNIV_INTERN
void
trx_end_lock_wait(
/*==============*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
que_thr_t* thr;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t now;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
@@ -1085,19 +1115,27 @@ trx_end_lock_wait(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ now = (ib_uint64_t)sec * 1000000 + ms;
+ trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
+ }
trx->que_state = TRX_QUE_RUNNING;
}
-/***************************************************************
+/***********************************************************//**
Moves the query threads in the lock wait list to the SUSPENDED state and puts
the transaction to the TRX_QUE_RUNNING state. */
static
void
trx_lock_wait_to_suspended(
/*=======================*/
- trx_t* trx) /* in: transaction in the TRX_QUE_LOCK_WAIT state */
+ trx_t* trx) /*!< in: transaction in the TRX_QUE_LOCK_WAIT state */
{
que_thr_t* thr;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t now;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
@@ -1112,17 +1150,22 @@ trx_lock_wait_to_suspended(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ now = (ib_uint64_t)sec * 1000000 + ms;
+ trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
+ }
trx->que_state = TRX_QUE_RUNNING;
}
-/***************************************************************
+/***********************************************************//**
Moves the query threads in the sig reply wait list of trx to the SUSPENDED
state. */
static
void
trx_sig_reply_wait_to_suspended(
/*============================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
trx_sig_t* sig;
que_thr_t* thr;
@@ -1146,17 +1189,17 @@ trx_sig_reply_wait_to_suspended(
}
}
-/*********************************************************************
+/*****************************************************************//**
Checks the compatibility of a new signal with the other signals in the
-queue. */
+queue.
+@return TRUE if the signal can be queued */
static
ibool
trx_sig_is_compatible(
/*==================*/
- /* out: TRUE if the signal can be queued */
- trx_t* trx, /* in: trx handle */
- ulint type, /* in: signal type */
- ulint sender) /* in: TRX_SIG_SELF or TRX_SIG_OTHER_SESS */
+ trx_t* trx, /*!< in: trx handle */
+ ulint type, /*!< in: signal type */
+ ulint sender) /*!< in: TRX_SIG_SELF or TRX_SIG_OTHER_SESS */
{
trx_sig_t* sig;
@@ -1220,22 +1263,22 @@ trx_sig_is_compatible(
}
}
-/********************************************************************
+/****************************************************************//**
Sends a signal to a trx object. */
UNIV_INTERN
void
trx_sig_send(
/*=========*/
- trx_t* trx, /* in: trx handle */
- ulint type, /* in: signal type */
- ulint sender, /* in: TRX_SIG_SELF or
+ trx_t* trx, /*!< in: trx handle */
+ ulint type, /*!< in: signal type */
+ ulint sender, /*!< in: TRX_SIG_SELF or
TRX_SIG_OTHER_SESS */
- que_thr_t* receiver_thr, /* in: query thread which wants the
+ que_thr_t* receiver_thr, /*!< in: query thread which wants the
reply, or NULL; if type is
TRX_SIG_END_WAIT, this must be NULL */
- trx_savept_t* savept, /* in: possible rollback savepoint, or
+ trx_savept_t* savept, /*!< in: possible rollback savepoint, or
NULL */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1304,7 +1347,7 @@ trx_sig_send(
}
}
-/********************************************************************
+/****************************************************************//**
Ends signal handling. If the session is in the error state, and
trx->graph_before_signal_handling != NULL, then returns control to the error
handling routine of the graph (currently just returns the control to the
@@ -1313,7 +1356,7 @@ UNIV_INTERN
void
trx_end_signal_handling(
/*====================*/
- trx_t* trx) /* in: trx */
+ trx_t* trx) /*!< in: trx */
{
ut_ad(mutex_own(&kernel_mutex));
ut_ad(trx->handling_signals == TRUE);
@@ -1328,14 +1371,14 @@ trx_end_signal_handling(
}
}
-/********************************************************************
+/****************************************************************//**
Starts handling of a trx signal. */
UNIV_INTERN
void
trx_sig_start_handle(
/*=================*/
- trx_t* trx, /* in: trx handle */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ trx_t* trx, /*!< in: trx handle */
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1433,15 +1476,15 @@ loop:
goto loop;
}
-/********************************************************************
+/****************************************************************//**
Send the reply message when a signal in the queue of the trx has been
handled. */
UNIV_INTERN
void
trx_sig_reply(
/*==========*/
- trx_sig_t* sig, /* in: signal */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ trx_sig_t* sig, /*!< in: signal */
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1468,14 +1511,14 @@ trx_sig_reply(
}
}
-/********************************************************************
+/****************************************************************//**
Removes a signal object from the trx signal queue. */
UNIV_INTERN
void
trx_sig_remove(
/*===========*/
- trx_t* trx, /* in: trx handle */
- trx_sig_t* sig) /* in, own: signal */
+ trx_t* trx, /*!< in: trx handle */
+ trx_sig_t* sig) /*!< in, own: signal */
{
ut_ad(trx && sig);
ut_ad(mutex_own(&kernel_mutex));
@@ -1490,14 +1533,14 @@ trx_sig_remove(
}
}
-/*************************************************************************
-Creates a commit command node struct. */
+/*********************************************************************//**
+Creates a commit command node struct.
+@return own: commit node struct */
UNIV_INTERN
commit_node_t*
commit_node_create(
/*===============*/
- /* out, own: commit node struct */
- mem_heap_t* heap) /* in: mem heap where created */
+ mem_heap_t* heap) /*!< in: mem heap where created */
{
commit_node_t* node;
@@ -1508,14 +1551,14 @@ commit_node_create(
return(node);
}
-/***************************************************************
-Performs an execution step for a commit type node in a query graph. */
+/***********************************************************//**
+Performs an execution step for a commit type node in a query graph.
+@return query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_commit_step(
/*============*/
- /* out: query thread to run next, or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
commit_node_t* node;
que_thr_t* next_thr;
@@ -1556,14 +1599,14 @@ trx_commit_step(
return(thr);
}
-/**************************************************************************
-Does the transaction commit for MySQL. */
+/**********************************************************************//**
+Does the transaction commit for MySQL.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
trx_commit_for_mysql(
/*=================*/
- /* out: DB_SUCCESS or error number */
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
/* Because we do not do the commit by sending an Innobase
sig to the transaction, we must here make sure that trx has been
@@ -1586,15 +1629,15 @@ trx_commit_for_mysql(
return(DB_SUCCESS);
}
-/**************************************************************************
+/**********************************************************************//**
If required, flushes the log to disk if we called trx_commit_for_mysql()
-with trx->flush_log_later == TRUE. */
+with trx->flush_log_later == TRUE.
+@return 0 or error number */
UNIV_INTERN
ulint
trx_commit_complete_for_mysql(
/*==========================*/
- /* out: 0 or error number */
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
ib_uint64_t lsn = trx->commit_lsn;
@@ -1633,13 +1676,13 @@ trx_commit_complete_for_mysql(
return(0);
}
-/**************************************************************************
+/**********************************************************************//**
Marks the latest SQL statement ended. */
UNIV_INTERN
void
trx_mark_sql_stat_end(
/*==================*/
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
ut_a(trx);
@@ -1650,7 +1693,7 @@ trx_mark_sql_stat_end(
trx->last_sql_stat_start.least_undo_no = trx->undo_no;
}
-/**************************************************************************
+/**********************************************************************//**
Prints info about a transaction to the given file. The caller must own the
kernel mutex and must have called
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
@@ -1659,9 +1702,9 @@ UNIV_INTERN
void
trx_print(
/*======*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ulint max_query_len) /* in: max query length to print, or 0 to
+ FILE* f, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ ulint max_query_len) /*!< in: max query length to print, or 0 to
use the default max length */
{
ibool newline;
@@ -1765,17 +1808,17 @@ trx_print(
}
}
-/***********************************************************************
+/*******************************************************************//**
Compares the "weight" (or size) of two transactions. Transactions that
have edited non-transactional tables are considered heavier than ones
-that have not. */
+that have not.
+@return <0, 0 or >0; similar to strcmp(3) */
UNIV_INTERN
int
trx_weight_cmp(
/*===========*/
- /* out: <0, 0 or >0; similar to strcmp(3) */
- const trx_t* a, /* in: the first transaction to be compared */
- const trx_t* b) /* in: the second transaction to be compared */
+ const trx_t* a, /*!< in: the first transaction to be compared */
+ const trx_t* b) /*!< in: the second transaction to be compared */
{
ibool a_notrans_edit;
ibool b_notrans_edit;
@@ -1816,13 +1859,13 @@ trx_weight_cmp(
return(ut_dulint_cmp(TRX_WEIGHT(a), TRX_WEIGHT(b)));
}
-/********************************************************************
+/****************************************************************//**
Prepares a transaction. */
UNIV_INTERN
void
trx_prepare_off_kernel(
/*===================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
page_t* update_hdr_page;
trx_rseg_t* rseg;
@@ -1926,14 +1969,14 @@ trx_prepare_off_kernel(
}
}
-/**************************************************************************
-Does the transaction prepare for MySQL. */
+/**********************************************************************//**
+Does the transaction prepare for MySQL.
+@return 0 or error number */
UNIV_INTERN
ulint
trx_prepare_for_mysql(
/*==================*/
- /* out: 0 or error number */
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
/* Because we do not do the prepare by sending an Innobase
sig to the transaction, we must here make sure that trx has been
@@ -1956,17 +1999,16 @@ trx_prepare_for_mysql(
return(0);
}
-/**************************************************************************
+/**********************************************************************//**
This function is used to find number of prepared transactions and
-their transaction objects for a recovery. */
+their transaction objects for a recovery.
+@return number of prepared transactions stored in xid_list */
UNIV_INTERN
int
trx_recover_for_mysql(
/*==================*/
- /* out: number of prepared transactions
- stored in xid_list */
- XID* xid_list, /* in/out: prepared transactions */
- ulint len) /* in: number of slots in xid_list */
+ XID* xid_list, /*!< in/out: prepared transactions */
+ ulint len) /*!< in: number of slots in xid_list */
{
trx_t* trx;
ulint count = 0;
@@ -2028,15 +2070,15 @@ trx_recover_for_mysql(
return ((int) count);
}
-/***********************************************************************
+/*******************************************************************//**
This function is used to find one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return trx or NULL */
UNIV_INTERN
trx_t*
trx_get_trx_by_xid(
/*===============*/
- /* out: trx or NULL */
- XID* xid) /* in: X/Open XA transaction identification */
+ XID* xid) /*!< in: X/Open XA transaction identification */
{
trx_t* trx;
diff --git a/storage/xtradb/trx/trx0undo.c b/storage/xtradb/trx/trx0undo.c
index bb5710aeba9..063a2f2b8a6 100644
--- a/storage/xtradb/trx/trx0undo.c
+++ b/storage/xtradb/trx/trx0undo.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0undo.c
Transaction undo log
Created 3/26/1996 Heikki Tuuri
@@ -29,13 +30,14 @@ Created 3/26/1996 Heikki Tuuri
#endif
#include "fsp0fsp.h"
+#ifndef UNIV_HOTBACKUP
#include "mach0data.h"
+#include "mtr0log.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "srv0srv.h"
#include "trx0rec.h"
#include "trx0purge.h"
-#include "trx0xa.h"
/* How should the old versions in the history list be managed?
----------------------------------------------------------
@@ -91,68 +93,71 @@ it until a truncate operation occurs, which can remove undo logs from the end
of the list and release undo log segments. In stepping through the list,
s-latches on the undo log pages are enough, but in a truncate, x-latches must
be obtained on the rollback segment and individual pages. */
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Initializes the fields in an undo log segment page. */
static
void
trx_undo_page_init(
/*===============*/
- page_t* undo_page, /* in: undo log segment page */
- ulint type, /* in: undo log segment type */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
-Creates and initializes an undo log memory object. */
+ page_t* undo_page, /*!< in: undo log segment page */
+ ulint type, /*!< in: undo log segment type */
+ mtr_t* mtr); /*!< in: mtr */
+
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Creates and initializes an undo log memory object.
+@return own: the undo log memory object */
static
trx_undo_t*
trx_undo_mem_create(
/*================*/
- /* out, own: the undo log memory object */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- ulint id, /* in: slot index within rseg */
- ulint type, /* in: type of the log: TRX_UNDO_INSERT or
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ ulint id, /*!< in: slot index within rseg */
+ ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is created */
- const XID* xid, /* in: X/Open XA transaction identification*/
- ulint page_no,/* in: undo log header page number */
- ulint offset);/* in: undo log header byte offset on page */
-/*******************************************************************
+ const XID* xid, /*!< in: X/Open XA transaction identification*/
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset);/*!< in: undo log header byte offset on page */
+#endif /* !UNIV_HOTBACKUP */
+/***************************************************************//**
Initializes a cached insert undo log header page for new use. NOTE that this
function has its own log record type MLOG_UNDO_HDR_REUSE. You must NOT change
-the operation of this function! */
+the operation of this function!
+@return undo log header byte offset on page */
static
ulint
trx_undo_insert_header_reuse(
/*=========================*/
- /* out: undo log header byte offset on page */
- page_t* undo_page, /* in: insert undo log segment header page,
- x-latched */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ page_t* undo_page, /*!< in/out: insert undo log segment
+ header page, x-latched */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
If an update undo log can be discarded immediately, this function frees the
space, resetting the page to the proper state for caching. */
static
void
trx_undo_discard_latest_update_undo(
/*================================*/
- page_t* undo_page, /* in: header page of an undo log of size 1 */
- mtr_t* mtr); /* in: mtr */
-
+ page_t* undo_page, /*!< in: header page of an undo log of size 1 */
+ mtr_t* mtr); /*!< in: mtr */
-/***************************************************************************
-Gets the previous record in an undo log from the previous page. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Gets the previous record in an undo log from the previous page.
+@return undo log record, the page s-latched, NULL if none */
static
trx_undo_rec_t*
trx_undo_get_prev_rec_from_prev_page(
/*=================================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr) /* in: mtr */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -180,18 +185,17 @@ trx_undo_get_prev_rec_from_prev_page(
return(trx_undo_page_get_last_rec(prev_page, page_no, offset));
}
-/***************************************************************************
-Gets the previous record in an undo log. */
+/***********************************************************************//**
+Gets the previous record in an undo log.
+@return undo log record, the page s-latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_prev_rec(
/*==================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr) /* in: mtr */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_undo_rec_t* prev_rec;
@@ -209,22 +213,21 @@ trx_undo_get_prev_rec(
mtr));
}
-/***************************************************************************
-Gets the next record in an undo log from the next page. */
+/***********************************************************************//**
+Gets the next record in an undo log from the next page.
+@return undo log record, the page latched, NULL if none */
static
trx_undo_rec_t*
trx_undo_get_next_rec_from_next_page(
/*=================================*/
- /* out: undo log record, the page latched, NULL if
- none */
- ulint space, /* in: undo log header space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: undo log header space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- page_t* undo_page, /* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- ulint mode, /* in: latch mode: RW_S_LATCH or RW_X_LATCH */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ ulint mode, /*!< in: latch mode: RW_S_LATCH or RW_X_LATCH */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_ulogf_t* log_hdr;
ulint next_page_no;
@@ -262,18 +265,17 @@ trx_undo_get_next_rec_from_next_page(
return(trx_undo_page_get_first_rec(next_page, page_no, offset));
}
-/***************************************************************************
-Gets the next record in an undo log. */
+/***********************************************************************//**
+Gets the next record in an undo log.
+@return undo log record, the page s-latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_next_rec(
/*==================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr) /* in: mtr */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -294,21 +296,20 @@ trx_undo_get_next_rec(
RW_S_LATCH, mtr));
}
-/***************************************************************************
-Gets the first record in an undo log. */
+/***********************************************************************//**
+Gets the first record in an undo log.
+@return undo log record, the page latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_first_rec(
/*===================*/
- /* out: undo log record, the page latched, NULL if
- none */
- ulint space, /* in: undo log header space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: undo log header space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- ulint mode, /* in: latching mode: RW_S_LATCH or RW_X_LATCH */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ ulint mode, /*!< in: latching mode: RW_S_LATCH or RW_X_LATCH */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* undo_page;
trx_undo_rec_t* rec;
@@ -333,32 +334,35 @@ trx_undo_get_first_rec(
/*============== UNDO LOG FILE COPY CREATION AND FREEING ==================*/
-/**************************************************************************
+/**********************************************************************//**
Writes the mtr log entry of an undo log page initialization. */
UNIV_INLINE
void
trx_undo_page_init_log(
/*===================*/
- page_t* undo_page, /* in: undo log page */
- ulint type, /* in: undo log type */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log page */
+ ulint type, /*!< in: undo log type */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(undo_page, MLOG_UNDO_INIT, mtr);
mlog_catenate_ulint_compressed(mtr, type);
}
+#else /* !UNIV_HOTBACKUP */
+# define trx_undo_page_init_log(undo_page,type,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses the redo log entry of an undo log page initialization. */
+/***********************************************************//**
+Parses the redo log entry of an undo log page initialization.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_page_init(
/*=====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ulint type;
@@ -376,15 +380,15 @@ trx_undo_parse_page_init(
return(ptr);
}
-/************************************************************************
+/********************************************************************//**
Initializes the fields in an undo log segment page. */
static
void
trx_undo_page_init(
/*===============*/
- page_t* undo_page, /* in: undo log segment page */
- ulint type, /* in: undo log segment type */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log segment page */
+ ulint type, /*!< in: undo log segment type */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_upagef_t* page_hdr;
@@ -402,26 +406,25 @@ trx_undo_page_init(
trx_undo_page_init_log(undo_page, type, mtr);
}
-/*******************************************************************
-Creates a new undo log segment in file. */
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
+Creates a new undo log segment in file.
+@return DB_SUCCESS if page creation OK possible error codes are:
+DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE */
static
ulint
trx_undo_seg_create(
/*================*/
- /* out: DB_SUCCESS if page creation OK
- possible error codes are:
- DB_TOO_MANY_CONCURRENT_TRXS
- DB_OUT_OF_FILE_SPACE */
- trx_rseg_t* rseg __attribute__((unused)),/* in: rollback segment */
- trx_rsegf_t* rseg_hdr,/* in: rollback segment header, page
+ trx_rseg_t* rseg __attribute__((unused)),/*!< in: rollback segment */
+ trx_rsegf_t* rseg_hdr,/*!< in: rollback segment header, page
x-latched */
- ulint type, /* in: type of the segment: TRX_UNDO_INSERT or
+ ulint type, /*!< in: type of the segment: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- ulint* id, /* out: slot index within rseg header */
+ ulint* id, /*!< out: slot index within rseg header */
page_t** undo_page,
- /* out: segment header page x-latched, NULL
+ /*!< out: segment header page x-latched, NULL
if there was an error */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint slot_no;
ulint space;
@@ -500,36 +503,40 @@ trx_undo_seg_create(
return(err);
}
-/**************************************************************************
+/**********************************************************************//**
Writes the mtr log entry of an undo log header initialization. */
UNIV_INLINE
void
trx_undo_header_create_log(
/*=======================*/
- page_t* undo_page, /* in: undo log header page */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr) /* in: mtr */
+ const page_t* undo_page, /*!< in: undo log header page */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_CREATE, mtr);
mlog_catenate_dulint_compressed(mtr, trx_id);
}
+#else /* !UNIV_HOTBACKUP */
+# define trx_undo_header_create_log(undo_page,trx_id,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Creates a new undo log header in file. NOTE that this function has its own
log record type MLOG_UNDO_HDR_CREATE. You must NOT change the operation of
-this function! */
+this function!
+@return header byte offset on page */
static
ulint
trx_undo_header_create(
/*===================*/
- /* out: header byte offset on page */
- page_t* undo_page, /* in: undo log segment header page,
- x-latched; it is assumed that there are
- TRX_UNDO_LOG_XA_HDR_SIZE bytes free space
- on it */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in/out: undo log segment
+ header page, x-latched; it is
+ assumed that there is
+ TRX_UNDO_LOG_XA_HDR_SIZE bytes
+ free space on it */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_upagef_t* page_hdr;
trx_usegf_t* seg_hdr;
@@ -587,15 +594,16 @@ trx_undo_header_create(
return(free);
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Write X/Open XA Transaction Identification (XID) to undo log header */
static
void
trx_undo_write_xid(
/*===============*/
- trx_ulogf_t* log_hdr,/* in: undo log header */
- const XID* xid, /* in: X/Open XA Transaction Identification */
- mtr_t* mtr) /* in: mtr */
+ trx_ulogf_t* log_hdr,/*!< in: undo log header */
+ const XID* xid, /*!< in: X/Open XA Transaction Identification */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_ulint(log_hdr + TRX_UNDO_XA_FORMAT,
(ulint)xid->formatID, MLOG_4BYTES, mtr);
@@ -610,14 +618,14 @@ trx_undo_write_xid(
XIDDATASIZE, mtr);
}
-/************************************************************************
+/********************************************************************//**
Read X/Open XA Transaction Identification (XID) from undo log header */
static
void
trx_undo_read_xid(
/*==============*/
- trx_ulogf_t* log_hdr,/* in: undo log header */
- XID* xid) /* out: X/Open XA Transaction Identification */
+ trx_ulogf_t* log_hdr,/*!< in: undo log header */
+ XID* xid) /*!< out: X/Open XA Transaction Identification */
{
xid->formatID = (long)mach_read_from_4(log_hdr + TRX_UNDO_XA_FORMAT);
@@ -629,15 +637,15 @@ trx_undo_read_xid(
memcpy(xid->data, log_hdr + TRX_UNDO_XA_XID, XIDDATASIZE);
}
-/*******************************************************************
+/***************************************************************//**
Adds space for the XA XID after an undo log old-style header. */
static
void
trx_undo_header_add_space_for_xid(
/*==============================*/
- page_t* undo_page,/* in: undo log segment header page */
- trx_ulogf_t* log_hdr,/* in: undo log header */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page,/*!< in: undo log segment header page */
+ trx_ulogf_t* log_hdr,/*!< in: undo log header */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_upagef_t* page_hdr;
ulint free;
@@ -667,35 +675,38 @@ trx_undo_header_add_space_for_xid(
MLOG_2BYTES, mtr);
}
-/**************************************************************************
+/**********************************************************************//**
Writes the mtr log entry of an undo log header reuse. */
UNIV_INLINE
void
trx_undo_insert_header_reuse_log(
/*=============================*/
- page_t* undo_page, /* in: undo log header page */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr) /* in: mtr */
+ const page_t* undo_page, /*!< in: undo log header page */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_REUSE, mtr);
mlog_catenate_dulint_compressed(mtr, trx_id);
}
+#else /* !UNIV_HOTBACKUP */
+# define trx_undo_insert_header_reuse_log(undo_page,trx_id,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses the redo log entry of an undo log page header create or reuse. */
+/***********************************************************//**
+Parses the redo log entry of an undo log page header create or reuse.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_page_header(
/*=======================*/
- /* out: end of log record or NULL */
- ulint type, /* in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ ulint type, /*!< in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
- dulint trx_id;
+ trx_id_t trx_id;
ptr = mach_dulint_parse_compressed(ptr, end_ptr, &trx_id);
@@ -716,19 +727,19 @@ trx_undo_parse_page_header(
return(ptr);
}
-/*******************************************************************
+/***************************************************************//**
Initializes a cached insert undo log header page for new use. NOTE that this
function has its own log record type MLOG_UNDO_HDR_REUSE. You must NOT change
-the operation of this function! */
+the operation of this function!
+@return undo log header byte offset on page */
static
ulint
trx_undo_insert_header_reuse(
/*=========================*/
- /* out: undo log header byte offset on page */
- page_t* undo_page, /* in: insert undo log segment header page,
- x-latched */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in/out: insert undo log segment
+ header page, x-latched */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_upagef_t* page_hdr;
trx_usegf_t* seg_hdr;
@@ -776,29 +787,33 @@ trx_undo_insert_header_reuse(
return(free);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Writes the redo log entry of an update undo log header discard. */
UNIV_INLINE
void
trx_undo_discard_latest_log(
/*========================*/
- page_t* undo_page, /* in: undo log header page */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log header page */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_DISCARD, mtr);
}
+#else /* !UNIV_HOTBACKUP */
+# define trx_undo_discard_latest_log(undo_page, mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses the redo log entry of an undo log page header discard. */
+/***********************************************************//**
+Parses the redo log entry of an undo log page header discard.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_discard_latest(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(end_ptr);
@@ -809,15 +824,15 @@ trx_undo_parse_discard_latest(
return(ptr);
}
-/**************************************************************************
+/**********************************************************************//**
If an update undo log can be discarded immediately, this function frees the
space, resetting the page to the proper state for caching. */
static
void
trx_undo_discard_latest_update_undo(
/*================================*/
- page_t* undo_page, /* in: header page of an undo log of size 1 */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: header page of an undo log of size 1 */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_usegf_t* seg_hdr;
trx_upagef_t* page_hdr;
@@ -851,17 +866,17 @@ trx_undo_discard_latest_update_undo(
trx_undo_discard_latest_log(undo_page, mtr);
}
-/************************************************************************
-Tries to add a page to the undo log segment where the undo log is placed. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Tries to add a page to the undo log segment where the undo log is placed.
+@return page number if success, else FIL_NULL */
UNIV_INTERN
ulint
trx_undo_add_page(
/*==============*/
- /* out: page number if success, else
- FIL_NULL */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory object */
- mtr_t* mtr) /* in: mtr which does not have a latch to any
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory object */
+ mtr_t* mtr) /*!< in: mtr which does not have a latch to any
undo log page; the caller must have reserved
the rollback segment mutex */
{
@@ -922,21 +937,21 @@ trx_undo_add_page(
return(page_no);
}
-/************************************************************************
-Frees an undo log page that is not the header page. */
+/********************************************************************//**
+Frees an undo log page that is not the header page.
+@return last page number in remaining log */
static
ulint
trx_undo_free_page(
/*===============*/
- /* out: last page number in remaining log */
- trx_rseg_t* rseg, /* in: rollback segment */
- ibool in_history, /* in: TRUE if the undo log is in the history
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ ibool in_history, /*!< in: TRUE if the undo log is in the history
list */
- ulint space, /* in: space */
- ulint hdr_page_no, /* in: header page number */
- ulint page_no, /* in: page number to free: must not be the
+ ulint space, /*!< in: space */
+ ulint hdr_page_no, /*!< in: header page number */
+ ulint page_no, /*!< in: page number to free: must not be the
header page */
- mtr_t* mtr) /* in: mtr which does not have a latch to any
+ mtr_t* mtr) /*!< in: mtr which does not have a latch to any
undo log page; the caller must have reserved
the rollback segment mutex */
{
@@ -981,18 +996,18 @@ trx_undo_free_page(
return(last_addr.page);
}
-/************************************************************************
+/********************************************************************//**
Frees an undo log page when there is also the memory object for the undo
log. */
static
void
trx_undo_free_page_in_rollback(
/*===========================*/
- trx_t* trx __attribute__((unused)), /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- ulint page_no,/* in: page number to free: must not be the
+ trx_t* trx __attribute__((unused)), /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ ulint page_no,/*!< in: page number to free: must not be the
header page */
- mtr_t* mtr) /* in: mtr which does not have a latch to any
+ mtr_t* mtr) /*!< in: mtr which does not have a latch to any
undo log page; the caller must have reserved
the rollback segment mutex */
{
@@ -1008,19 +1023,19 @@ trx_undo_free_page_in_rollback(
undo->size--;
}
-/************************************************************************
+/********************************************************************//**
Empties an undo log header page of undo records for that undo log. Other
undo logs may still have records on that page, if it is an update undo log. */
static
void
trx_undo_empty_header_page(
/*=======================*/
- ulint space, /* in: space */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint hdr_page_no, /* in: header page number */
- ulint hdr_offset, /* in: header offset */
- mtr_t* mtr) /* in: mtr */
+ ulint hdr_page_no, /*!< in: header page number */
+ ulint hdr_offset, /*!< in: header offset */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* header_page;
trx_ulogf_t* log_hdr;
@@ -1035,16 +1050,16 @@ trx_undo_empty_header_page(
mlog_write_ulint(log_hdr + TRX_UNDO_LOG_START, end, MLOG_2BYTES, mtr);
}
-/***************************************************************************
+/***********************************************************************//**
Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
trx_undo_truncate_end(
/*==================*/
- trx_t* trx, /* in: transaction whose undo log it is */
- trx_undo_t* undo, /* in: undo log */
- dulint limit) /* in: all undo records with undo number
+ trx_t* trx, /*!< in: transaction whose undo log it is */
+ trx_undo_t* undo, /*!< in: undo log */
+ undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
{
page_t* undo_page;
@@ -1110,22 +1125,24 @@ function_exit:
mtr_commit(&mtr);
}
-/***************************************************************************
+/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
operation. */
UNIV_INTERN
void
trx_undo_truncate_start(
/*====================*/
- trx_rseg_t* rseg, /* in: rollback segment */
- ulint space, /* in: space id of the log */
- ulint hdr_page_no, /* in: header page number */
- ulint hdr_offset, /* in: header offset on the page */
- dulint limit) /* in: all undo pages with undo numbers <
- this value should be truncated; NOTE that
- the function only frees whole pages; the
- header page is not freed, but emptied, if
- all the records there are < limit */
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ ulint space, /*!< in: space id of the log */
+ ulint hdr_page_no, /*!< in: header page number */
+ ulint hdr_offset, /*!< in: header offset on the page */
+ undo_no_t limit) /*!< in: all undo pages with
+ undo numbers < this value
+ should be truncated; NOTE that
+ the function only frees whole
+ pages; the header page is not
+ freed, but emptied, if all the
+ records there are < limit */
{
page_t* undo_page;
trx_undo_rec_t* rec;
@@ -1180,13 +1197,13 @@ loop:
goto loop;
}
-/**************************************************************************
+/**********************************************************************//**
Frees an undo log segment which is not in the history list. */
static
void
trx_undo_seg_free(
/*==============*/
- trx_undo_t* undo) /* in: undo log */
+ trx_undo_t* undo) /*!< in: undo log */
{
trx_rseg_t* rseg;
fseg_header_t* file_seg;
@@ -1229,19 +1246,19 @@ trx_undo_seg_free(
/*========== UNDO LOG MEMORY COPY INITIALIZATION =====================*/
-/************************************************************************
+/********************************************************************//**
Creates and initializes an undo log memory object according to the values
in the header in file, when the database is started. The memory object is
-inserted in the appropriate list of rseg. */
+inserted in the appropriate list of rseg.
+@return own: the undo log memory object */
static
trx_undo_t*
trx_undo_mem_create_at_db_start(
/*============================*/
- /* out, own: the undo log memory object */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- ulint id, /* in: slot index within rseg */
- ulint page_no,/* in: undo log segment page number */
- mtr_t* mtr) /* in: mtr */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ ulint id, /*!< in: slot index within rseg */
+ ulint page_no,/*!< in: undo log segment page number */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* undo_page;
trx_upagef_t* page_header;
@@ -1250,7 +1267,7 @@ trx_undo_mem_create_at_db_start(
trx_undo_t* undo;
ulint type;
ulint state;
- dulint trx_id;
+ trx_id_t trx_id;
ulint offset;
fil_addr_t last_addr;
page_t* last_page;
@@ -1353,17 +1370,16 @@ add_to_list:
return(undo);
}
-/************************************************************************
+/********************************************************************//**
Initializes the undo log lists for a rollback segment memory copy. This
function is only called when the database is started or a new rollback
-segment is created. */
+segment is created.
+@return the combined size of undo log segments in pages */
UNIV_INTERN
ulint
trx_undo_lists_init(
/*================*/
- /* out: the combined size of undo log segments
- in pages */
- trx_rseg_t* rseg) /* in: rollback segment memory object */
+ trx_rseg_t* rseg) /*!< in: rollback segment memory object */
{
ulint page_no;
trx_undo_t* undo;
@@ -1450,22 +1466,22 @@ trx_undo_lists_init(
return(size);
}
-/************************************************************************
-Creates and initializes an undo log memory object. */
+/********************************************************************//**
+Creates and initializes an undo log memory object.
+@return own: the undo log memory object */
static
trx_undo_t*
trx_undo_mem_create(
/*================*/
- /* out, own: the undo log memory object */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- ulint id, /* in: slot index within rseg */
- ulint type, /* in: type of the log: TRX_UNDO_INSERT or
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ ulint id, /*!< in: slot index within rseg */
+ ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is created */
- const XID* xid, /* in: X/Open transaction identification */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header byte offset on page */
+ const XID* xid, /*!< in: X/Open transaction identification */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header byte offset on page */
{
trx_undo_t* undo;
@@ -1509,17 +1525,17 @@ trx_undo_mem_create(
return(undo);
}
-/************************************************************************
+/********************************************************************//**
Initializes a cached undo log object for new use. */
static
void
trx_undo_mem_init_for_reuse(
/*========================*/
- trx_undo_t* undo, /* in: undo log to init */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_undo_t* undo, /*!< in: undo log to init */
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is created */
- const XID* xid, /* in: X/Open XA transaction identification*/
- ulint offset) /* in: undo log header byte offset on page */
+ const XID* xid, /*!< in: X/Open XA transaction identification*/
+ ulint offset) /*!< in: undo log header byte offset on page */
{
ut_ad(mutex_own(&((undo->rseg)->mutex)));
@@ -1542,13 +1558,13 @@ trx_undo_mem_init_for_reuse(
undo->empty = TRUE;
}
-/************************************************************************
+/********************************************************************//**
Frees an undo log memory copy. */
-static
+UNIV_INTERN
void
trx_undo_mem_free(
/*==============*/
- trx_undo_t* undo) /* in: the undo object to be freed */
+ trx_undo_t* undo) /*!< in: the undo object to be freed */
{
if (undo->id >= TRX_RSEG_N_SLOTS) {
fprintf(stderr,
@@ -1559,28 +1575,25 @@ trx_undo_mem_free(
mem_free(undo);
}
-/**************************************************************************
-Creates a new undo log. */
+/**********************************************************************//**
+Creates a new undo log.
+@return DB_SUCCESS if successful in creating the new undo lob object,
+possible error codes are: DB_TOO_MANY_CONCURRENT_TRXS
+DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY */
static
ulint
trx_undo_create(
/*============*/
- /* out: DB_SUCCESS if successful in creating
- the new undo lob object, possible error
- codes are:
- DB_TOO_MANY_CONCURRENT_TRXS
- DB_OUT_OF_FILE_SPACE
- DB_OUT_OF_MEMORY*/
- trx_t* trx, /* in: transaction */
- trx_rseg_t* rseg, /* in: rollback segment memory copy */
- ulint type, /* in: type of the log: TRX_UNDO_INSERT or
+ trx_t* trx, /*!< in: transaction */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory copy */
+ ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is created */
- const XID* xid, /* in: X/Open transaction identification*/
- trx_undo_t** undo, /* out: the new undo log object, undefined
+ const XID* xid, /*!< in: X/Open transaction identification*/
+ trx_undo_t** undo, /*!< out: the new undo log object, undefined
* if did not succeed */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_rsegf_t* rseg_header;
ulint page_no;
@@ -1633,22 +1646,21 @@ trx_undo_create(
/*================ UNDO LOG ASSIGNMENT AND CLEANUP =====================*/
-/************************************************************************
-Reuses a cached undo log. */
+/********************************************************************//**
+Reuses a cached undo log.
+@return the undo log memory object, NULL if none cached */
static
trx_undo_t*
trx_undo_reuse_cached(
/*==================*/
- /* out: the undo log memory object, NULL if
- none cached */
- trx_t* trx, /* in: transaction */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- ulint type, /* in: type of the log: TRX_UNDO_INSERT or
+ trx_t* trx, /*!< in: transaction */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is used */
- const XID* xid, /* in: X/Open XA transaction identification */
- mtr_t* mtr) /* in: mtr */
+ const XID* xid, /*!< in: X/Open XA transaction identification */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_undo_t* undo;
page_t* undo_page;
@@ -1714,16 +1726,16 @@ trx_undo_reuse_cached(
return(undo);
}
-/**************************************************************************
+/**********************************************************************//**
Marks an undo log header as a header of a data dictionary operation
transaction. */
static
void
trx_undo_mark_as_dict_operation(
/*============================*/
- trx_t* trx, /* in: dict op transaction */
- trx_undo_t* undo, /* in: assigned undo log */
- mtr_t* mtr) /* in: mtr */
+ trx_t* trx, /*!< in: dict op transaction */
+ trx_undo_t* undo, /*!< in: assigned undo log */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* hdr_page;
@@ -1752,19 +1764,18 @@ trx_undo_mark_as_dict_operation(
undo->dict_operation = TRUE;
}
-/**************************************************************************
+/**********************************************************************//**
Assigns an undo log for a transaction. A new undo log is created or a cached
-undo log reused. */
+undo log reused.
+@return DB_SUCCESS if undo log assign successful, possible error codes
+are: DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE
+DB_OUT_OF_MEMORY */
UNIV_INTERN
ulint
trx_undo_assign_undo(
/*=================*/
- /* out: DB_SUCCESS if undo log assign
- successful, possible error codes are:
- DB_TOO_MANY_CONCURRENT_TRXS
- DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/
- trx_t* trx, /* in: transaction */
- ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
+ trx_t* trx, /*!< in: transaction */
+ ulint type) /*!< in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
{
trx_rseg_t* rseg;
trx_undo_t* undo;
@@ -1816,18 +1827,17 @@ func_exit:
return err;
}
-/**********************************************************************
-Sets the state of the undo log segment at a transaction finish. */
+/******************************************************************//**
+Sets the state of the undo log segment at a transaction finish.
+@return undo log segment header page, x-latched */
UNIV_INTERN
page_t*
trx_undo_set_state_at_finish(
/*=========================*/
- /* out: undo log segment header page,
- x-latched */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- trx_t* trx __attribute__((unused)), /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- mtr_t* mtr) /* in: mtr */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ trx_t* trx __attribute__((unused)), /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_usegf_t* seg_hdr;
trx_upagef_t* page_hdr;
@@ -1884,17 +1894,16 @@ trx_undo_set_state_at_finish(
return(undo_page);
}
-/**********************************************************************
-Sets the state of the undo log segment at a transaction prepare. */
+/******************************************************************//**
+Sets the state of the undo log segment at a transaction prepare.
+@return undo log segment header page, x-latched */
UNIV_INTERN
page_t*
trx_undo_set_state_at_prepare(
/*==========================*/
- /* out: undo log segment header page,
- x-latched */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- mtr_t* mtr) /* in: mtr */
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_usegf_t* seg_hdr;
trx_upagef_t* page_hdr;
@@ -1936,7 +1945,7 @@ trx_undo_set_state_at_prepare(
return(undo_page);
}
-/**************************************************************************
+/**********************************************************************//**
Adds the update undo log header as the first in the history list, and
frees the memory object, or puts it to the list of cached update undo log
segments. */
@@ -1944,10 +1953,10 @@ UNIV_INTERN
void
trx_undo_update_cleanup(
/*====================*/
- trx_t* trx, /* in: trx owning the update undo log */
- page_t* undo_page, /* in: update undo log header page,
+ trx_t* trx, /*!< in: trx owning the update undo log */
+ page_t* undo_page, /*!< in: update undo log header page,
x-latched */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_rseg_t* rseg;
trx_undo_t* undo;
@@ -1973,7 +1982,7 @@ trx_undo_update_cleanup(
}
}
-/**********************************************************************
+/******************************************************************//**
Frees or caches an insert undo log after a transaction commit or rollback.
Knowledge of inserts is not needed after a commit or rollback, therefore
the data can be discarded. */
@@ -1981,7 +1990,7 @@ UNIV_INTERN
void
trx_undo_insert_cleanup(
/*====================*/
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
trx_undo_t* undo;
trx_rseg_t* rseg;
@@ -2019,3 +2028,4 @@ trx_undo_insert_cleanup(
mutex_exit(&(rseg->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/usr/usr0sess.c b/storage/xtradb/usr/usr0sess.c
index f45c43869ea..8087dcb4170 100644
--- a/storage/xtradb/usr/usr0sess.c
+++ b/storage/xtradb/usr/usr0sess.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file usr/usr0sess.c
Sessions
Created 6/25/1996 Heikki Tuuri
@@ -30,21 +31,13 @@ Created 6/25/1996 Heikki Tuuri
#include "trx0trx.h"
-/*************************************************************************
-Closes a session, freeing the memory occupied by it. */
-static
-void
-sess_close(
-/*=======*/
- sess_t* sess); /* in, own: session object */
-
-/*************************************************************************
-Opens a session. */
+/*********************************************************************//**
+Opens a session.
+@return own: session object */
UNIV_INTERN
sess_t*
sess_open(void)
/*===========*/
- /* out, own: session object */
{
sess_t* sess;
@@ -61,37 +54,18 @@ sess_open(void)
return(sess);
}
-/*************************************************************************
+/*********************************************************************//**
Closes a session, freeing the memory occupied by it. */
-static
+UNIV_INTERN
void
sess_close(
/*=======*/
- sess_t* sess) /* in, own: session object */
+ sess_t* sess) /*!< in, own: session object */
{
- ut_ad(mutex_own(&kernel_mutex));
- ut_ad(sess->trx == NULL);
+ ut_ad(!mutex_own(&kernel_mutex));
- mem_free(sess);
-}
+ ut_a(UT_LIST_GET_LEN(sess->graphs) == 0);
-/*************************************************************************
-Closes a session, freeing the memory occupied by it, if it is in a state
-where it should be closed. */
-UNIV_INTERN
-ibool
-sess_try_close(
-/*===========*/
- /* out: TRUE if closed */
- sess_t* sess) /* in, own: session object */
-{
- ut_ad(mutex_own(&kernel_mutex));
-
- if (UT_LIST_GET_LEN(sess->graphs) == 0) {
- sess_close(sess);
-
- return(TRUE);
- }
-
- return(FALSE);
+ trx_free_for_background(sess->trx);
+ mem_free(sess);
}
diff --git a/storage/xtradb/ut/ut0auxconf.c b/storage/xtradb/ut/ut0auxconf.c
deleted file mode 100644
index fd9433d16f6..00000000000
--- a/storage/xtradb/ut/ut0auxconf.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <pthread.h>
-
-int
-main(int argc, char** argv)
-{
- pthread_t x1;
- pthread_t x2;
- pthread_t x3;
-
- __sync_bool_compare_and_swap(&x1, x2, x3);
-
- return(0);
-}
diff --git a/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c
new file mode 100644
index 00000000000..30de5aa6f17
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c
@@ -0,0 +1,43 @@
+/*****************************************************************************
+
+Copyright (c) 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
+
+*****************************************************************************/
+
+/*****************************************************************************
+If this program compiles, then pthread_t objects can be used as arguments
+to GCC atomic builtin functions.
+
+Created March 5, 2009 Vasil Dimov
+*****************************************************************************/
+
+#include <pthread.h>
+#include <string.h>
+
+int
+main(int argc, char** argv)
+{
+ pthread_t x1;
+ pthread_t x2;
+ pthread_t x3;
+
+ memset(&x1, 0x0, sizeof(x1));
+ memset(&x2, 0x0, sizeof(x2));
+ memset(&x3, 0x0, sizeof(x3));
+
+ __sync_bool_compare_and_swap(&x1, x2, x3);
+
+ return(0);
+}
diff --git a/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c
new file mode 100644
index 00000000000..310603c7503
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c
@@ -0,0 +1,54 @@
+/*****************************************************************************
+
+Copyright (c) 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
+
+*****************************************************************************/
+
+/*****************************************************************************
+If this program compiles and returns 0, then pthread_t objects can be used as
+arguments to Solaris libc atomic functions.
+
+Created April 18, 2009 Vasil Dimov
+*****************************************************************************/
+
+#include <pthread.h>
+#include <string.h>
+
+int
+main(int argc, char** argv)
+{
+ pthread_t x1;
+ pthread_t x2;
+ pthread_t x3;
+
+ memset(&x1, 0x0, sizeof(x1));
+ memset(&x2, 0x0, sizeof(x2));
+ memset(&x3, 0x0, sizeof(x3));
+
+ if (sizeof(pthread_t) == 4) {
+
+ atomic_cas_32(&x1, x2, x3);
+
+ } else if (sizeof(pthread_t) == 8) {
+
+ atomic_cas_64(&x1, x2, x3);
+
+ } else {
+
+ return(1);
+ }
+
+ return(0);
+}
diff --git a/storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c b/storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c
new file mode 100644
index 00000000000..da5c13d7d79
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c
@@ -0,0 +1,61 @@
+/*****************************************************************************
+
+Copyright (c) 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
+
+*****************************************************************************/
+
+/*****************************************************************************
+If this program compiles and returns 0, then GCC atomic funcions are available.
+
+Created September 12, 2009 Vasil Dimov
+*****************************************************************************/
+
+int
+main(int argc, char** argv)
+{
+ long x;
+ long y;
+ long res;
+ char c;
+
+ x = 10;
+ y = 123;
+ res = __sync_bool_compare_and_swap(&x, x, y);
+ if (!res || x != y) {
+ return(1);
+ }
+
+ x = 10;
+ y = 123;
+ res = __sync_bool_compare_and_swap(&x, x + 1, y);
+ if (res || x != 10) {
+ return(1);
+ }
+
+ x = 10;
+ y = 123;
+ res = __sync_add_and_fetch(&x, y);
+ if (res != 123 + 10 || x != 123 + 10) {
+ return(1);
+ }
+
+ c = 10;
+ res = __sync_lock_test_and_set(&c, 123);
+ if (res != 10 || c != 123) {
+ return(1);
+ }
+
+ return(0);
+}
diff --git a/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c b/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c
new file mode 100644
index 00000000000..7eb704edd4b
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c
@@ -0,0 +1,39 @@
+/*****************************************************************************
+
+Copyright (c) 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
+
+*****************************************************************************/
+
+/*****************************************************************************
+If this program compiles, then Solaris libc atomic funcions are available.
+
+Created April 18, 2009 Vasil Dimov
+*****************************************************************************/
+#include <atomic.h>
+
+int
+main(int argc, char** argv)
+{
+ ulong_t ulong = 0;
+ uint32_t uint32 = 0;
+ uint64_t uint64 = 0;
+
+ atomic_cas_ulong(&ulong, 0, 1);
+ atomic_cas_32(&uint32, 0, 1);
+ atomic_cas_64(&uint64, 0, 1);
+ atomic_add_long(&ulong, 0);
+
+ return(0);
+}
diff --git a/storage/xtradb/ut/ut0auxconf_pause.c b/storage/xtradb/ut/ut0auxconf_pause.c
new file mode 100644
index 00000000000..54d63bdd9bc
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_pause.c
@@ -0,0 +1,32 @@
+/*****************************************************************************
+
+Copyright (c) 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
+
+*****************************************************************************/
+
+/*****************************************************************************
+If this program compiles and can be run and returns 0, then the pause
+instruction is available.
+
+Created Jul 21, 2009 Vasil Dimov
+*****************************************************************************/
+
+int
+main(int argc, char** argv)
+{
+ __asm__ __volatile__ ("pause");
+
+ return(0);
+}
diff --git a/storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c b/storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c
new file mode 100644
index 00000000000..96add4526ef
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c
@@ -0,0 +1,35 @@
+/*****************************************************************************
+
+Copyright (c) 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
+
+*****************************************************************************/
+
+/*****************************************************************************
+This program should compile and when run, print a single line like:
+#define SIZEOF_PTHREAD_T %d
+
+Created April 18, 2009 Vasil Dimov
+*****************************************************************************/
+
+#include <stdio.h>
+#include <pthread.h>
+
+int
+main(int argc, char** argv)
+{
+ printf("#define SIZEOF_PTHREAD_T %d\n", (int) sizeof(pthread_t));
+
+ return(0);
+}
diff --git a/storage/xtradb/ut/ut0byte.c b/storage/xtradb/ut/ut0byte.c
index 5e11e37d0b6..4e093f72ce2 100644
--- a/storage/xtradb/ut/ut0byte.c
+++ b/storage/xtradb/ut/ut0byte.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*******************************************************************
+/***************************************************************//**
+@file ut/ut0byte.c
Byte utilities
Created 5/11/1994 Heikki Tuuri
@@ -28,21 +29,25 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0byte.ic"
#endif
-/* Zero value for a dulint */
+/** Zero value for a dulint */
UNIV_INTERN const dulint ut_dulint_zero = {0, 0};
-/* Maximum value for a dulint */
+/** Maximum value for a dulint */
UNIV_INTERN const dulint ut_dulint_max = {0xFFFFFFFFUL, 0xFFFFFFFFUL};
#ifdef notdefined /* unused code */
#include "ut0sort.h"
-/****************************************************************
+/************************************************************//**
Sort function for dulint arrays. */
UNIV_INTERN
void
-ut_dulint_sort(dulint* arr, dulint* aux_arr, ulint low, ulint high)
-/*===============================================================*/
+ut_dulint_sort(
+/*===========*/
+ dulint* arr, /*!< in/out: array to be sorted */
+ dulint* aux_arr,/*!< in/out: auxiliary array (same size as arr) */
+ ulint low, /*!< in: low bound of sort interval, inclusive */
+ ulint high) /*!< in: high bound of sort interval, noninclusive */
{
UT_SORT_FUNCTION_BODY(ut_dulint_sort, arr, aux_arr, low, high,
ut_dulint_cmp);
diff --git a/storage/xtradb/ut/ut0dbg.c b/storage/xtradb/ut/ut0dbg.c
index 55dd457a177..4484e6c36de 100644
--- a/storage/xtradb/ut/ut0dbg.c
+++ b/storage/xtradb/ut/ut0dbg.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*********************************************************************
+/*****************************************************************//**
+@file ut/ut0dbg.c
Debug utilities for Innobase.
Created 1/30/1994 Heikki Tuuri
@@ -27,40 +28,45 @@ Created 1/30/1994 Heikki Tuuri
#if defined(__GNUC__) && (__GNUC__ > 2)
#else
-/* This is used to eliminate compiler warnings */
+/** This is used to eliminate compiler warnings */
UNIV_INTERN ulint ut_dbg_zero = 0;
#endif
#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/* If this is set to TRUE all threads will stop into the next assertion
-and assert */
+/** If this is set to TRUE by ut_dbg_assertion_failed(), all threads
+will stop at the next ut_a() or ut_ad(). */
UNIV_INTERN ibool ut_dbg_stop_threads = FALSE;
#endif
#ifdef __NETWARE__
-/* This is set to TRUE when on NetWare there happens an InnoDB
-assertion failure or other fatal error condition that requires an
-immediate shutdown. */
+/** Flag for ignoring further assertion failures. This is set to TRUE
+when on NetWare there happens an InnoDB assertion failure or other
+fatal error condition that requires an immediate shutdown. */
UNIV_INTERN ibool panic_shutdown = FALSE;
#elif !defined(UT_DBG_USE_ABORT)
-/* Null pointer used to generate memory trap */
+/** A null pointer that will be dereferenced to trigger a memory trap */
UNIV_INTERN ulint* ut_dbg_null_ptr = NULL;
#endif
-/*****************************************************************
+/*************************************************************//**
Report a failed assertion. */
UNIV_INTERN
void
ut_dbg_assertion_failed(
/*====================*/
- const char* expr, /* in: the failed assertion (optional) */
- const char* file, /* in: source file containing the assertion */
- ulint line) /* in: line number of the assertion */
+ const char* expr, /*!< in: the failed assertion (optional) */
+ const char* file, /*!< in: source file containing the assertion */
+ ulint line) /*!< in: line number of the assertion */
{
ut_print_timestamp(stderr);
+#ifdef UNIV_HOTBACKUP
+ fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n",
+ file, line);
+#else /* UNIV_HOTBACKUP */
fprintf(stderr,
" InnoDB: Assertion failure in thread %lu"
" in file %s line %lu\n",
os_thread_pf(os_thread_get_curr_id()), file, line);
+#endif /* UNIV_HOTBACKUP */
if (expr) {
fprintf(stderr,
"InnoDB: Failing assertion: %s\n", expr);
@@ -73,8 +79,7 @@ ut_dbg_assertion_failed(
" or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
ut_dbg_stop_threads = TRUE;
@@ -82,7 +87,7 @@ ut_dbg_assertion_failed(
}
#ifdef __NETWARE__
-/*****************************************************************
+/*************************************************************//**
Shut down MySQL/InnoDB after assertion failure. */
UNIV_INTERN
void
@@ -97,7 +102,7 @@ ut_dbg_panic(void)
}
#else /* __NETWARE__ */
# if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/*****************************************************************
+/*************************************************************//**
Stop a thread after assertion failure. */
UNIV_INTERN
void
@@ -106,9 +111,11 @@ ut_dbg_stop_thread(
const char* file,
ulint line)
{
+#ifndef UNIV_HOTBACKUP
fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
os_thread_pf(os_thread_get_curr_id()), file, line);
os_thread_sleep(1000000000);
+#endif /* !UNIV_HOTBACKUP */
}
# endif
#endif /* __NETWARE__ */
@@ -133,27 +140,27 @@ ut_dbg_stop_thread(
} while (0)
#endif /* timersub */
-/***********************************************************************
+/*******************************************************************//**
Resets a speedo (records the current time in it). */
UNIV_INTERN
void
speedo_reset(
/*=========*/
- speedo_t* speedo) /* out: speedo */
+ speedo_t* speedo) /*!< out: speedo */
{
gettimeofday(&speedo->tv, NULL);
getrusage(RUSAGE_SELF, &speedo->ru);
}
-/***********************************************************************
+/*******************************************************************//**
Shows the time elapsed and usage statistics since the last reset of a
speedo. */
UNIV_INTERN
void
speedo_show(
/*========*/
- const speedo_t* speedo) /* in: speedo */
+ const speedo_t* speedo) /*!< in: speedo */
{
struct rusage ru_now;
struct timeval tv_now;
diff --git a/storage/xtradb/ut/ut0list.c b/storage/xtradb/ut/ut0list.c
index c6250edb6cd..895a575c535 100644
--- a/storage/xtradb/ut/ut0list.c
+++ b/storage/xtradb/ut/ut0list.c
@@ -16,18 +16,25 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*******************************************************************//**
+@file ut/ut0list.c
+A double-linked list
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
#include "ut0list.h"
#ifdef UNIV_NONINL
#include "ut0list.ic"
#endif
-/********************************************************************
-Create a new list. */
+/****************************************************************//**
+Create a new list.
+@return list */
UNIV_INTERN
ib_list_t*
ib_list_create(void)
/*=================*/
- /* out: list */
{
ib_list_t* list = mem_alloc(sizeof(ib_list_t));
@@ -38,15 +45,15 @@ ib_list_create(void)
return(list);
}
-/********************************************************************
+/****************************************************************//**
Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
-lists created with this function. */
+lists created with this function.
+@return list */
UNIV_INTERN
ib_list_t*
ib_list_create_heap(
/*================*/
- /* out: list */
- mem_heap_t* heap) /* in: memory heap to use */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
ib_list_t* list = mem_heap_alloc(heap, sizeof(ib_list_t));
@@ -57,13 +64,13 @@ ib_list_create_heap(
return(list);
}
-/********************************************************************
+/****************************************************************//**
Free a list. */
UNIV_INTERN
void
ib_list_free(
/*=========*/
- ib_list_t* list) /* in: list */
+ ib_list_t* list) /*!< in: list */
{
ut_a(!list->is_heap_list);
@@ -74,46 +81,46 @@ ib_list_free(
mem_free(list);
}
-/********************************************************************
-Add the data to the start of the list. */
+/****************************************************************//**
+Add the data to the start of the list.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_first(
/*==============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- void* data, /* in: data */
- mem_heap_t* heap) /* in: memory heap to use */
+ ib_list_t* list, /*!< in: list */
+ void* data, /*!< in: data */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
return(ib_list_add_after(list, ib_list_get_first(list), data, heap));
}
-/********************************************************************
-Add the data to the end of the list. */
+/****************************************************************//**
+Add the data to the end of the list.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_last(
/*=============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- void* data, /* in: data */
- mem_heap_t* heap) /* in: memory heap to use */
+ ib_list_t* list, /*!< in: list */
+ void* data, /*!< in: data */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
return(ib_list_add_after(list, ib_list_get_last(list), data, heap));
}
-/********************************************************************
-Add the data after the indicated node. */
+/****************************************************************//**
+Add the data after the indicated node.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_after(
/*==============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- ib_list_node_t* prev_node, /* in: node preceding new node (can
+ ib_list_t* list, /*!< in: list */
+ ib_list_node_t* prev_node, /*!< in: node preceding new node (can
be NULL) */
- void* data, /* in: data */
- mem_heap_t* heap) /* in: memory heap to use */
+ void* data, /*!< in: data */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
ib_list_node_t* node = mem_heap_alloc(heap, sizeof(ib_list_node_t));
@@ -156,14 +163,14 @@ ib_list_add_after(
return(node);
}
-/********************************************************************
+/****************************************************************//**
Remove the node from the list. */
UNIV_INTERN
void
ib_list_remove(
/*===========*/
- ib_list_t* list, /* in: list */
- ib_list_node_t* node) /* in: node to remove */
+ ib_list_t* list, /*!< in: list */
+ ib_list_node_t* node) /*!< in: node to remove */
{
if (node->prev) {
node->prev->next = node->next;
diff --git a/storage/xtradb/ut/ut0mem.c b/storage/xtradb/ut/ut0mem.c
index c87a6a4b57e..35a325b9ccd 100644
--- a/storage/xtradb/ut/ut0mem.c
+++ b/storage/xtradb/ut/ut0mem.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file ut/ut0mem.c
Memory primitives
Created 5/11/1994 Heikki Tuuri
@@ -28,41 +29,47 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0mem.ic"
#endif
-#include "mem0mem.h"
-#include "os0thread.h"
-#include "srv0srv.h"
+#ifndef UNIV_HOTBACKUP
+# include "os0thread.h"
+# include "srv0srv.h"
#include <stdlib.h>
-/* This struct is placed first in every allocated memory block */
+/** This struct is placed first in every allocated memory block */
typedef struct ut_mem_block_struct ut_mem_block_t;
-/* The total amount of memory currently allocated from the operating
+/** The total amount of memory currently allocated from the operating
system with os_mem_alloc_large() or malloc(). Does not count malloc()
if srv_use_sys_malloc is set. Protected by ut_list_mutex. */
UNIV_INTERN ulint ut_total_allocated_memory = 0;
-/* Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
+/** Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
UNIV_INTERN os_fast_mutex_t ut_list_mutex;
+/** Dynamically allocated memory block */
struct ut_mem_block_struct{
UT_LIST_NODE_T(ut_mem_block_t) mem_block_list;
- /* mem block list node */
- ulint size; /* size of allocated memory */
- ulint magic_n;
+ /*!< mem block list node */
+ ulint size; /*!< size of allocated memory */
+ ulint magic_n;/*!< magic number (UT_MEM_MAGIC_N) */
};
+/** The value of ut_mem_block_struct::magic_n. Used in detecting
+memory corruption. */
#define UT_MEM_MAGIC_N 1601650166
-/* List of all memory blocks allocated from the operating system
+/** List of all memory blocks allocated from the operating system
with malloc. Protected by ut_list_mutex. */
static UT_LIST_BASE_NODE_T(ut_mem_block_t) ut_mem_block_list;
+/** Flag: has ut_mem_block_list been initialized? */
static ibool ut_mem_block_list_inited = FALSE;
+/** A dummy pointer for generating a null pointer exception in
+ut_malloc_low() */
static ulint* ut_mem_null_ptr = NULL;
-/**************************************************************************
+/**********************************************************************//**
Initializes the mem block list at database startup. */
UNIV_INTERN
void
@@ -74,22 +81,24 @@ ut_mem_init(void)
UT_LIST_INIT(ut_mem_block_list);
ut_mem_block_list_inited = TRUE;
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
-defined and set_to_zero is TRUE. */
+defined and set_to_zero is TRUE.
+@return own: allocated memory */
UNIV_INTERN
void*
ut_malloc_low(
/*==========*/
- /* out, own: allocated memory */
- ulint n, /* in: number of bytes to allocate */
- ibool set_to_zero, /* in: TRUE if allocated memory should be
+ ulint n, /*!< in: number of bytes to allocate */
+ ibool set_to_zero, /*!< in: TRUE if allocated memory should be
set to zero if UNIV_SET_MEM_TO_ZERO is
defined */
- ibool assert_on_error)/* in: if TRUE, we crash mysqld if the
+ ibool assert_on_error)/*!< in: if TRUE, we crash mysqld if the
memory cannot be allocated */
{
+#ifndef UNIV_HOTBACKUP
ulint retry_count;
void* ret;
@@ -208,31 +217,47 @@ retry:
os_fast_mutex_unlock(&ut_list_mutex);
return((void*)((byte*)ret + sizeof(ut_mem_block_t)));
+#else /* !UNIV_HOTBACKUP */
+ void* ret = malloc(n);
+ ut_a(ret || !assert_on_error);
+
+# ifdef UNIV_SET_MEM_TO_ZERO
+ if (set_to_zero) {
+ memset(ret, '\0', n);
+ }
+# endif
+ return(ret);
+#endif /* !UNIV_HOTBACKUP */
}
-/**************************************************************************
+/**********************************************************************//**
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
-defined. */
+defined.
+@return own: allocated memory */
UNIV_INTERN
void*
ut_malloc(
/*======*/
- /* out, own: allocated memory */
- ulint n) /* in: number of bytes to allocate */
+ ulint n) /*!< in: number of bytes to allocate */
{
+#ifndef UNIV_HOTBACKUP
return(ut_malloc_low(n, TRUE, TRUE));
+#else /* !UNIV_HOTBACKUP */
+ return(malloc(n));
+#endif /* !UNIV_HOTBACKUP */
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs
out. It cannot be used if we want to return an error message. Prints to
-stderr a message if fails. */
+stderr a message if fails.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
ut_test_malloc(
/*===========*/
- /* out: TRUE if succeeded */
- ulint n) /* in: try to allocate this many bytes */
+ ulint n) /*!< in: try to allocate this many bytes */
{
void* ret;
@@ -262,15 +287,17 @@ ut_test_malloc(
return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Frees a memory block allocated with ut_malloc. */
UNIV_INTERN
void
ut_free(
/*====*/
- void* ptr) /* in, own: memory block */
+ void* ptr) /*!< in, own: memory block */
{
+#ifndef UNIV_HOTBACKUP
ut_mem_block_t* block;
if (UNIV_LIKELY(srv_use_sys_malloc)) {
@@ -291,9 +318,13 @@ ut_free(
free(block);
os_fast_mutex_unlock(&ut_list_mutex);
+#else /* !UNIV_HOTBACKUP */
+ free(ptr);
+#endif /* !UNIV_HOTBACKUP */
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not
use this function because the allocation functions in mem0mem.h are the
recommended ones in InnoDB.
@@ -302,7 +333,7 @@ man realloc in Linux, 2004:
realloc() changes the size of the memory block pointed to
by ptr to size bytes. The contents will be unchanged to
- the minimum of the old and new sizes; newly allocated mem­
+ the minimum of the old and new sizes; newly allocated mem-
ory will be uninitialized. If ptr is NULL, the call is
equivalent to malloc(size); if size is equal to zero, the
call is equivalent to free(ptr). Unless ptr is NULL, it
@@ -316,14 +347,14 @@ RETURN VALUE
size was equal to 0, either NULL or a pointer suitable to
be passed to free() is returned. If realloc() fails the
original block is left untouched - it is not freed or
- moved. */
+ moved.
+@return own: pointer to new mem block or NULL */
UNIV_INTERN
void*
ut_realloc(
/*=======*/
- /* out, own: pointer to new mem block or NULL */
- void* ptr, /* in: pointer to old block or NULL */
- ulint size) /* in: desired size */
+ void* ptr, /*!< in: pointer to old block or NULL */
+ ulint size) /*!< in: desired size */
{
ut_mem_block_t* block;
ulint old_size;
@@ -372,7 +403,7 @@ ut_realloc(
return(new_ptr);
}
-/**************************************************************************
+/**********************************************************************//**
Frees in shutdown all allocated memory not freed yet. */
UNIV_INTERN
void
@@ -402,20 +433,23 @@ ut_free_all_mem(void)
" total allocated memory is %lu\n",
(ulong) ut_total_allocated_memory);
}
+
+ ut_mem_block_list_inited = FALSE;
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Copies up to size - 1 characters from the NUL-terminated string src to
dst, NUL-terminating the result. Returns strlen(src), so truncation
-occurred if the return value >= size. */
+occurred if the return value >= size.
+@return strlen(src) */
UNIV_INTERN
ulint
ut_strlcpy(
/*=======*/
- /* out: strlen(src) */
- char* dst, /* in: destination buffer */
- const char* src, /* in: source buffer */
- ulint size) /* in: size of destination buffer */
+ char* dst, /*!< in: destination buffer */
+ const char* src, /*!< in: source buffer */
+ ulint size) /*!< in: size of destination buffer */
{
ulint src_size = strlen(src);
@@ -429,17 +463,17 @@ ut_strlcpy(
return(src_size);
}
-/**************************************************************************
+/**********************************************************************//**
Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
-(size - 1) bytes of src, not the first. */
+(size - 1) bytes of src, not the first.
+@return strlen(src) */
UNIV_INTERN
ulint
ut_strlcpy_rev(
/*===========*/
- /* out: strlen(src) */
- char* dst, /* in: destination buffer */
- const char* src, /* in: source buffer */
- ulint size) /* in: size of destination buffer */
+ char* dst, /*!< in: destination buffer */
+ const char* src, /*!< in: source buffer */
+ ulint size) /*!< in: size of destination buffer */
{
ulint src_size = strlen(src);
@@ -452,18 +486,18 @@ ut_strlcpy_rev(
return(src_size);
}
-/**************************************************************************
+/**********************************************************************//**
Make a quoted copy of a NUL-terminated string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
-See also ut_strlenq() and ut_memcpyq(). */
+See also ut_strlenq() and ut_memcpyq().
+@return pointer to end of dest */
UNIV_INTERN
char*
ut_strcpyq(
/*=======*/
- /* out: pointer to end of dest */
- char* dest, /* in: output buffer */
- char q, /* in: the quote character */
- const char* src) /* in: null-terminated string */
+ char* dest, /*!< in: output buffer */
+ char q, /*!< in: the quote character */
+ const char* src) /*!< in: null-terminated string */
{
while (*src) {
if ((*dest++ = *src++) == q) {
@@ -474,19 +508,19 @@ ut_strcpyq(
return(dest);
}
-/**************************************************************************
+/**********************************************************************//**
Make a quoted copy of a fixed-length string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
-See also ut_strlenq() and ut_strcpyq(). */
+See also ut_strlenq() and ut_strcpyq().
+@return pointer to end of dest */
UNIV_INTERN
char*
ut_memcpyq(
/*=======*/
- /* out: pointer to end of dest */
- char* dest, /* in: output buffer */
- char q, /* in: the quote character */
- const char* src, /* in: string to be quoted */
- ulint len) /* in: length of src */
+ char* dest, /*!< in: output buffer */
+ char q, /*!< in: the quote character */
+ const char* src, /*!< in: string to be quoted */
+ ulint len) /*!< in: length of src */
{
const char* srcend = src + len;
@@ -499,16 +533,17 @@ ut_memcpyq(
return(dest);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Return the number of times s2 occurs in s1. Overlapping instances of s2
-are only counted once. */
+are only counted once.
+@return the number of times s2 occurs in s1 */
UNIV_INTERN
ulint
ut_strcount(
/*========*/
- /* out: the number of times s2 occurs in s1 */
- const char* s1, /* in: string to search in */
- const char* s2) /* in: string to search for */
+ const char* s1, /*!< in: string to search in */
+ const char* s2) /*!< in: string to search for */
{
ulint count = 0;
ulint len = strlen(s2);
@@ -533,18 +568,17 @@ ut_strcount(
return(count);
}
-/**************************************************************************
+/**********************************************************************//**
Replace every occurrence of s1 in str with s2. Overlapping instances of s1
-are only replaced once. */
+are only replaced once.
+@return own: modified string, must be freed with mem_free() */
UNIV_INTERN
char*
ut_strreplace(
/*==========*/
- /* out, own: modified string, must be
- freed with mem_free() */
- const char* str, /* in: string to operate on */
- const char* s1, /* in: string to replace */
- const char* s2) /* in: string to replace s1 with */
+ const char* str, /*!< in: string to operate on */
+ const char* s1, /*!< in: string to replace */
+ const char* s2) /*!< in: string to replace s1 with */
{
char* new_str;
char* ptr;
@@ -671,3 +705,4 @@ test_ut_str_sql_format()
}
#endif /* UNIV_COMPILE_TEST_FUNCS */
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/ut/ut0rnd.c b/storage/xtradb/ut/ut0rnd.c
index f5d6cb08b0f..cefd0990ecc 100644
--- a/storage/xtradb/ut/ut0rnd.c
+++ b/storage/xtradb/ut/ut0rnd.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*******************************************************************
+/***************************************************************//**
+@file ut/ut0rnd.c
Random numbers and hashing
Created 5/11/1994 Heikki Tuuri
@@ -28,23 +29,25 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0rnd.ic"
#endif
-/* These random numbers are used in ut_find_prime */
+/** These random numbers are used in ut_find_prime */
+/*@{*/
#define UT_RANDOM_1 1.0412321
#define UT_RANDOM_2 1.1131347
#define UT_RANDOM_3 1.0132677
+/*@}*/
-
+/** Seed value of ut_rnd_gen_ulint(). */
UNIV_INTERN 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. */
+The prime is chosen so that it is not near any power of 2.
+@return prime */
UNIV_INTERN
ulint
ut_find_prime(
/*==========*/
- /* out: prime */
- ulint n) /* in: positive number > 100 */
+ ulint n) /*!< in: positive number > 100 */
{
ulint pow2;
ulint i;
diff --git a/storage/xtradb/ut/ut0ut.c b/storage/xtradb/ut/ut0ut.c
index d94e0771a54..498873e290a 100644
--- a/storage/xtradb/ut/ut0ut.c
+++ b/storage/xtradb/ut/ut0ut.c
@@ -1,6 +1,13 @@
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Sun Microsystems, Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -16,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*******************************************************************
+/***************************************************************//**
+@file ut/ut0ut.c
Various utilities for Innobase.
Created 5/11/1994 Heikki Tuuri
@@ -32,31 +40,32 @@ Created 5/11/1994 Heikki Tuuri
#include <string.h>
#include <ctype.h>
-#include "trx0trx.h"
-#include "ha_prototypes.h"
#ifndef UNIV_HOTBACKUP
+# include "trx0trx.h"
+# include "ha_prototypes.h"
# include "mysql_com.h" /* NAME_LEN */
#endif /* UNIV_HOTBACKUP */
+/** A constant to prevent the compiler from optimizing ut_delay() away. */
UNIV_INTERN ibool ut_always_false = FALSE;
#ifdef __WIN__
-/*********************************************************************
+/*****************************************************************//**
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
epoch starts from 1970/1/1. For selection of constant see:
http://support.microsoft.com/kb/167296/ */
#define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
-/*********************************************************************
-This is the Windows version of gettimeofday(2).*/
+/*****************************************************************//**
+This is the Windows version of gettimeofday(2).
+@return 0 if all OK else -1 */
static
int
ut_gettimeofday(
/*============*/
- /* out: 0 if all OK else -1 */
- struct timeval* tv, /* out: Values are relative to Unix epoch */
- void* tz) /* in: not used */
+ struct timeval* tv, /*!< out: Values are relative to Unix epoch */
+ void* tz) /*!< in: not used */
{
FILETIME ft;
ib_int64_t tm;
@@ -86,19 +95,21 @@ ut_gettimeofday(
return(0);
}
#else
+/** An alias for gettimeofday(2). On Microsoft Windows, we have to
+reimplement this function. */
#define ut_gettimeofday gettimeofday
#endif
-/************************************************************
+/********************************************************//**
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
but since there seem to be compiler bugs in both gcc and Visual C++,
-we do this by a special conversion. */
+we do this by a special conversion.
+@return a >> 32 */
UNIV_INTERN
ulint
ut_get_high32(
/*==========*/
- /* out: a >> 32 */
- ulint a) /* in: ulint */
+ ulint a) /*!< in: ulint */
{
ib_int64_t i;
@@ -109,9 +120,10 @@ ut_get_high32(
return((ulint)i);
}
-/**************************************************************
+/**********************************************************//**
Returns system time. We do not specify the format of the time returned:
-the only way to manipulate it is to use the function ut_difftime. */
+the only way to manipulate it is to use the function ut_difftime.
+@return system time */
UNIV_INTERN
ib_time_t
ut_time(void)
@@ -120,18 +132,19 @@ ut_time(void)
return(time(NULL));
}
-/**************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
value -1 is returned and the global variable errno is set to indicate the
-error. */
+error.
+@return 0 on success, -1 otherwise */
UNIV_INTERN
int
ut_usectime(
/*========*/
- /* out: 0 on success, -1 otherwise */
- ulint* sec, /* out: seconds since the Epoch */
- ulint* ms) /* out: microseconds since the Epoch+*sec */
+ ulint* sec, /*!< out: seconds since the Epoch */
+ ulint* ms) /*!< out: microseconds since the Epoch+*sec */
{
struct timeval tv;
int ret;
@@ -162,16 +175,16 @@ ut_usectime(
return(ret);
}
-/**************************************************************
+/**********************************************************//**
Returns the number of microseconds since epoch. Similar to
time(3), the return value is also stored in *tloc, provided
-that tloc is non-NULL. */
+that tloc is non-NULL.
+@return us since epoch */
UNIV_INTERN
ullint
ut_time_us(
/*=======*/
- /* out: us since epoch */
- ullint* tloc) /* out: us since epoch, if non-NULL */
+ ullint* tloc) /*!< out: us since epoch, if non-NULL */
{
struct timeval tv;
ullint us;
@@ -187,26 +200,44 @@ ut_time_us(
return(us);
}
-/**************************************************************
-Returns the difference of two times in seconds. */
+/**********************************************************//**
+Returns the number of milliseconds since some epoch. The
+value may wrap around. It should only be used for heuristic
+purposes.
+@return ms since epoch */
+UNIV_INTERN
+ulint
+ut_time_ms(void)
+/*============*/
+{
+ struct timeval tv;
+
+ ut_gettimeofday(&tv, NULL);
+
+ return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
+}
+#endif /* !UNIV_HOTBACKUP */
+
+/**********************************************************//**
+Returns the difference of two times in seconds.
+@return time2 - time1 expressed in seconds */
UNIV_INTERN
double
ut_difftime(
/*========*/
- /* out: time2 - time1 expressed in seconds */
- ib_time_t time2, /* in: time */
- ib_time_t time1) /* in: time */
+ ib_time_t time2, /*!< in: time */
+ ib_time_t time1) /*!< in: time */
{
return(difftime(time2, time1));
}
-/**************************************************************
+/**********************************************************//**
Prints a timestamp to a file. */
UNIV_INTERN
void
ut_print_timestamp(
/*===============*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
@@ -243,13 +274,13 @@ ut_print_timestamp(
#endif
}
-/**************************************************************
+/**********************************************************//**
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
UNIV_INTERN
void
ut_sprintf_timestamp(
/*=================*/
- char* buf) /* in: buffer where to sprintf */
+ char* buf) /*!< in: buffer where to sprintf */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
@@ -287,14 +318,14 @@ ut_sprintf_timestamp(
}
#ifdef UNIV_HOTBACKUP
-/**************************************************************
+/**********************************************************//**
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
replaced by '_'. */
UNIV_INTERN
void
ut_sprintf_timestamp_without_extra_chars(
/*=====================================*/
- char* buf) /* in: buffer where to sprintf */
+ char* buf) /*!< in: buffer where to sprintf */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
@@ -331,15 +362,15 @@ ut_sprintf_timestamp_without_extra_chars(
#endif
}
-/**************************************************************
+/**********************************************************//**
Returns current year, month, day. */
UNIV_INTERN
void
ut_get_year_month_day(
/*==================*/
- ulint* year, /* out: current year */
- ulint* month, /* out: month */
- ulint* day) /* out: day */
+ ulint* year, /*!< out: current year */
+ ulint* month, /*!< out: month */
+ ulint* day) /*!< out: day */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
@@ -369,28 +400,24 @@ ut_get_year_month_day(
}
#endif /* UNIV_HOTBACKUP */
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Runs an idle loop on CPU. The argument gives the desired delay
-in microseconds on 100 MHz Pentium + Visual C++. */
-extern ulint srv_spins_microsec;
-
+in microseconds on 100 MHz Pentium + Visual C++.
+@return dummy value */
UNIV_INTERN
ulint
ut_delay(
/*=====*/
- /* out: dummy value */
- ulint delay) /* in: delay in microseconds on 100 MHz Pentium */
+ ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
{
ulint i, j;
j = 0;
- for (i = 0; i < delay * srv_spins_microsec; i++) {
-#if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__)
- /* it is equal to the instruction 'pause' */
- __asm__ __volatile__ ("rep; nop");
-#endif
+ for (i = 0; i < delay * 50; i++) {
j += i;
+ UT_RELAX_CPU();
}
if (ut_always_false) {
@@ -399,16 +426,17 @@ ut_delay(
return(j);
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Prints the contents of a memory buffer in hex and ascii. */
UNIV_INTERN
void
ut_print_buf(
/*=========*/
- FILE* file, /* in: file where to print */
- const void* buf, /* in: memory buffer */
- ulint len) /* in: length of the buffer */
+ FILE* file, /*!< in: file where to print */
+ const void* buf, /*!< in: memory buffer */
+ ulint len) /*!< in: length of the buffer */
{
const byte* data;
ulint i;
@@ -433,14 +461,14 @@ ut_print_buf(
putc(';', file);
}
-/*****************************************************************
-Calculates fast the number rounded up to the nearest power of 2. */
+/*************************************************************//**
+Calculates fast the number rounded up to the nearest power of 2.
+@return first power of 2 which is >= n */
UNIV_INTERN
ulint
ut_2_power_up(
/*==========*/
- /* out: first power of 2 which is >= n */
- ulint n) /* in: number != 0 */
+ ulint n) /*!< in: number != 0 */
{
ulint res;
@@ -455,14 +483,14 @@ ut_2_power_up(
return(res);
}
-/**************************************************************************
+/**********************************************************************//**
Outputs a NUL-terminated file name, quoted with apostrophes. */
UNIV_INTERN
void
ut_print_filename(
/*==============*/
- FILE* f, /* in: output stream */
- const char* name) /* in: name to print */
+ FILE* f, /*!< in: output stream */
+ const char* name) /*!< in: name to print */
{
putc('\'', f);
for (;;) {
@@ -480,8 +508,8 @@ ut_print_filename(
done:
putc('\'', f);
}
-
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
@@ -490,16 +518,16 @@ UNIV_INTERN
void
ut_print_name(
/*==========*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ibool table_id,/* in: TRUE=print a table name,
+ FILE* f, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ ibool table_id,/*!< in: TRUE=print a table name,
FALSE=print other identifier */
- const char* name) /* in: name to print */
+ const char* name) /*!< in: name to print */
{
ut_print_namel(f, trx, table_id, name, strlen(name));
}
-/**************************************************************************
+/**********************************************************************//**
Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
@@ -508,16 +536,13 @@ UNIV_INTERN
void
ut_print_namel(
/*===========*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction (NULL=no quotes) */
- ibool table_id,/* in: TRUE=print a table name,
+ FILE* f, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction (NULL=no quotes) */
+ ibool table_id,/*!< in: TRUE=print a table name,
FALSE=print other identifier */
- const char* name, /* in: name to print */
- ulint namelen)/* in: length of name */
+ const char* name, /*!< in: name to print */
+ ulint namelen)/*!< in: length of name */
{
-#ifdef UNIV_HOTBACKUP
- fwrite(name, 1, namelen, f);
-#else
/* 2 * NAME_LEN for database and table name,
and some slack for the #mysql50# prefix and quotes */
char buf[3 * NAME_LEN];
@@ -529,17 +554,16 @@ ut_print_namel(
table_id);
fwrite(buf, 1, bufend - buf, f);
-#endif
}
-/**************************************************************************
+/**********************************************************************//**
Catenate files. */
UNIV_INTERN
void
ut_copy_file(
/*=========*/
- FILE* dest, /* in: output file */
- FILE* src) /* in: input file to be appended to output */
+ FILE* dest, /*!< in: output file */
+ FILE* src) /*!< in: input file to be appended to output */
{
long len = ftell(src);
char buf[4096];
@@ -557,22 +581,23 @@ ut_copy_file(
}
} while (len > 0);
}
-
-/**************************************************************************
-snprintf(). */
+#endif /* !UNIV_HOTBACKUP */
#ifdef __WIN__
-#include <stdarg.h>
+# include <stdarg.h>
+/**********************************************************************//**
+A substitute for snprintf(3), formatted output conversion into
+a limited buffer.
+@return number of characters that would have been printed if the size
+were unlimited, not including the terminating '\0'. */
+UNIV_INTERN
int
ut_snprintf(
- /* out: number of characters that would
- have been printed if the size were
- unlimited, not including the terminating
- '\0'. */
- char* str, /* out: string */
- size_t size, /* in: str size */
- const char* fmt, /* in: format */
- ...) /* in: format values */
+/*========*/
+ char* str, /*!< out: string */
+ size_t size, /*!< in: str size */
+ const char* fmt, /*!< in: format */
+ ...) /*!< in: format values */
{
int res;
va_list ap1;
diff --git a/storage/xtradb/ut/ut0vec.c b/storage/xtradb/ut/ut0vec.c
index 69b7bec701a..45f2bc9771f 100644
--- a/storage/xtradb/ut/ut0vec.c
+++ b/storage/xtradb/ut/ut0vec.c
@@ -16,21 +16,28 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*******************************************************************//**
+@file ut/ut0vec.c
+A vector of pointers to data items
+
+Created 4/6/2006 Osku Salerma
+************************************************************************/
+
#include "ut0vec.h"
#ifdef UNIV_NONINL
#include "ut0vec.ic"
#endif
#include <string.h>
-/********************************************************************
-Create a new vector with the given initial size. */
+/****************************************************************//**
+Create a new vector with the given initial size.
+@return vector */
UNIV_INTERN
ib_vector_t*
ib_vector_create(
/*=============*/
- /* out: vector */
- mem_heap_t* heap, /* in: heap */
- ulint size) /* in: initial size */
+ mem_heap_t* heap, /*!< in: heap */
+ ulint size) /*!< in: initial size */
{
ib_vector_t* vec;
@@ -46,14 +53,14 @@ ib_vector_create(
return(vec);
}
-/********************************************************************
+/****************************************************************//**
Push a new element to the vector, increasing its size if necessary. */
UNIV_INTERN
void
ib_vector_push(
/*===========*/
- ib_vector_t* vec, /* in: vector */
- void* elem) /* in: data element */
+ ib_vector_t* vec, /*!< in: vector */
+ void* elem) /*!< in: data element */
{
if (vec->used >= vec->total) {
void** new_data;
diff --git a/storage/xtradb/ut/ut0wqueue.c b/storage/xtradb/ut/ut0wqueue.c
index a5c14ac8130..5220d1e17f4 100644
--- a/storage/xtradb/ut/ut0wqueue.c
+++ b/storage/xtradb/ut/ut0wqueue.c
@@ -18,13 +18,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "ut0wqueue.h"
-/********************************************************************
-Create a new work queue. */
+/*******************************************************************//**
+@file ut/ut0wqueue.c
+A work queue
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
+/****************************************************************//**
+Create a new work queue.
+@return work queue */
UNIV_INTERN
ib_wqueue_t*
ib_wqueue_create(void)
/*===================*/
- /* out: work queue */
{
ib_wqueue_t* wq = mem_alloc(sizeof(ib_wqueue_t));
@@ -36,13 +43,13 @@ ib_wqueue_create(void)
return(wq);
}
-/********************************************************************
+/****************************************************************//**
Free a work queue. */
UNIV_INTERN
void
ib_wqueue_free(
/*===========*/
- ib_wqueue_t* wq) /* in: work queue */
+ ib_wqueue_t* wq) /*!< in: work queue */
{
ut_a(!ib_list_get_first(wq->items));
@@ -53,15 +60,15 @@ ib_wqueue_free(
mem_free(wq);
}
-/********************************************************************
+/****************************************************************//**
Add a work item to the queue. */
UNIV_INTERN
void
ib_wqueue_add(
/*==========*/
- ib_wqueue_t* wq, /* in: work queue */
- void* item, /* in: work item */
- mem_heap_t* heap) /* in: memory heap to use for allocating the
+ ib_wqueue_t* wq, /*!< in: work queue */
+ void* item, /*!< in: work item */
+ mem_heap_t* heap) /*!< in: memory heap to use for allocating the
list node */
{
mutex_enter(&wq->mutex);
@@ -72,13 +79,14 @@ ib_wqueue_add(
mutex_exit(&wq->mutex);
}
-/********************************************************************
-Wait for a work item to appear in the queue. */
+/****************************************************************//**
+Wait for a work item to appear in the queue.
+@return work item */
UNIV_INTERN
void*
ib_wqueue_wait(
- /* out: work item */
- ib_wqueue_t* wq) /* in: work queue */
+/*===========*/
+ ib_wqueue_t* wq) /*!< in: work queue */
{
ib_list_node_t* node;
diff --git a/storage/xtradb/win-plugin/README b/storage/xtradb/win-plugin/README
deleted file mode 100644
index 9182f2c555c..00000000000
--- a/storage/xtradb/win-plugin/README
+++ /dev/null
@@ -1,25 +0,0 @@
-This directory contains patches that need to be applied to the MySQL
-source tree in order to build the dynamic plugin on Windows --
-HA_INNODB.DLL. Please note the followings when adding the patches:
-
-* The patch must be applied from the mysql top-level source directory.
- patch -p0 < win-plugin.diff
-* The patch filenames end in ".diff".
-* All patches here are expected to apply cleanly to the latest MySQL 5.1
- tree when storage/innobase is replaced with this InnoDB branch.
-
-When applying the patch, the following files will be modified:
-
- * CMakeLists.txt
- * sql/CMakeLists.txt
- * win/configure.js
- * win/build-vs71.bat
- * win/build-vs8.bat
- * win/build-vs8_x64.bat
-
-Also, two new files will be added:
-
- * sql/mysqld.def
- * sql/mysqld_x64.def
-
-You can get "patch" utility for Windows from http://unxutils.sourceforge.net/
diff --git a/storage/xtradb/win-plugin/win-plugin.diff b/storage/xtradb/win-plugin/win-plugin.diff
deleted file mode 100644
index 46d2e5b2d2d..00000000000
--- a/storage/xtradb/win-plugin/win-plugin.diff
+++ /dev/null
@@ -1,297 +0,0 @@
-diff -Nur CMakeLists.txt.orig CMakeLists.txt
---- CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
-+++ CMakeLists.txt 2008-09-26 17:32:51 -05:00
-@@ -244,9 +244,9 @@
- IF(WITH_FEDERATED_STORAGE_ENGINE)
- ADD_SUBDIRECTORY(storage/federated)
- ENDIF(WITH_FEDERATED_STORAGE_ENGINE)
--IF(WITH_INNOBASE_STORAGE_ENGINE)
-+IF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
- ADD_SUBDIRECTORY(storage/innobase)
--ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
-+ENDIF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
- ADD_SUBDIRECTORY(sql)
- ADD_SUBDIRECTORY(server-tools/instance-manager)
- ADD_SUBDIRECTORY(libmysql)
-
-diff -Nur sql/CMakeLists.txt.orig sql/CMakeLists.txt
---- sql/CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
-+++ sql/CMakeLists.txt 2008-09-24 03:58:19 -05:00
-@@ -100,6 +100,15 @@
- LINK_FLAGS "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
- ENDIF(cmake_version EQUAL 20406)
-
-+# Checks for 64-bit version
-+IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+SET_TARGET_PROPERTIES(mysqld PROPERTIES
-+ LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld_x64.def\"")
-+ELSE(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+SET_TARGET_PROPERTIES(mysqld PROPERTIES
-+ LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld.def\"")
-+ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+
- IF(EMBED_MANIFESTS)
- MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
- ENDIF(EMBED_MANIFESTS)
-
-diff -Nur sql/mysqld.def.orig sql/mysqld.def
---- sql/mysqld.def.orig 1969-12-31 18:00:00 -06:00
-+++ sql/mysqld.def 2008-10-31 02:20:32 -05:00
-@@ -0,0 +1,98 @@
-+EXPORTS
-+ ?use_hidden_primary_key@handler@@UAEXXZ
-+ ?get_dynamic_partition_info@handler@@UAEXPAUPARTITION_INFO@@I@Z
-+ ?read_first_row@handler@@UAEHPAEI@Z
-+ ?read_range_next@handler@@UAEHXZ
-+ ?read_range_first@handler@@UAEHPBUst_key_range@@0_N1@Z
-+ ?read_multi_range_first@handler@@UAEHPAPAUst_key_multi_range@@PAU2@I_NPAUst_handler_buffer@@@Z
-+ ?read_multi_range_next@handler@@UAEHPAPAUst_key_multi_range@@@Z
-+ ?index_read_idx_map@handler@@UAEHPAEIPBEKW4ha_rkey_function@@@Z
-+ ?print_error@handler@@UAEXHH@Z
-+ ?clone@handler@@UAEPAV1@PAUst_mem_root@@@Z
-+ ?get_auto_increment@handler@@UAEX_K00PA_K1@Z
-+ ?index_next_same@handler@@UAEHPAEPBEI@Z
-+ ?get_error_message@handler@@UAE_NHPAVString@@@Z
-+ ?ha_thd@handler@@IBEPAVTHD@@XZ
-+ ?update_auto_increment@handler@@QAEHXZ
-+ ?ha_statistic_increment@handler@@IBEXPQsystem_status_var@@K@Z
-+ ?trans_register_ha@@YAXPAVTHD@@_NPAUhandlerton@@@Z
-+ ?cmp@Field_blob@@QAEHPBEI0I@Z
-+ ?set_time@Field_timestamp@@QAEXXZ
-+ ?sql_print_error@@YAXPBDZZ
-+ ?sql_print_warning@@YAXPBDZZ
-+ ?check_global_access@@YA_NPAVTHD@@K@Z
-+ ?schema_table_store_record@@YA_NPAVTHD@@PAUst_table@@@Z
-+ ?get_quote_char_for_identifier@@YAHPAVTHD@@PBDI@Z
-+ ?copy@String@@QAE_NXZ
-+ ?copy@String@@QAE_NABV1@@Z
-+ ?copy@String@@QAE_NPBDIPAUcharset_info_st@@@Z
-+ ?copy_and_convert@@YAIPADIPAUcharset_info_st@@PBDI1PAI@Z
-+ ?filename_to_tablename@@YAIPBDPADI@Z
-+ ?strconvert@@YAIPAUcharset_info_st@@PBD0PADIPAI@Z
-+ ?calculate_key_len@@YAIPAUst_table@@IPBEK@Z
-+ ?sql_alloc@@YAPAXI@Z
-+ ?localtime_to_TIME@@YAXPAUst_mysql_time@@PAUtm@@@Z
-+ ?push_warning@@YAPAVMYSQL_ERROR@@PAVTHD@@W4enum_warning_level@1@IPBD@Z
-+ ?push_warning_printf@@YAXPAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPBDZZ
-+ ?drop_table@handler@@EAEXPBD@Z
-+ ?column_bitmaps_signal@handler@@UAEXXZ
-+ ?delete_table@handler@@MAEHPBD@Z
-+ ?rename_table@handler@@MAEHPBD0@Z
-+ ?key_map_empty@@3V?$Bitmap@$0EA@@@B
-+ ?THR_THD@@3PAVTHD@@A
-+ ?end_of_list@@3Ulist_node@@A
-+ ?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
-+ mysql_query_cache_invalidate4
-+ thd_query
-+ thd_sql_command
-+ thd_get_thread_id
-+ thd_get_xid
-+ thd_slave_thread
-+ thd_non_transactional_update
-+ thd_mark_transaction_to_rollback
-+ thd_security_context
-+ thd_charset
-+ thd_test_options
-+ thd_ha_data
-+ thd_killed
-+ thd_tx_isolation
-+ thd_tablespace_op
-+ thd_sql_command
-+ thd_memdup
-+ thd_make_lex_string
-+ thd_in_lock_tables
-+ thd_binlog_format
-+ _my_hash_init
-+ my_hash_free
-+ my_tmpdir
-+ check_if_legal_filename
-+ my_filename
-+ my_sync_dir_by_file
-+ alloc_root
-+ thr_lock_data_init
-+ thr_lock_init
-+ thr_lock_delete
-+ my_multi_malloc
-+ get_charset
-+ unpack_filename
-+ my_hash_insert
-+ my_hash_search
-+ my_hash_delete
-+ mysql_bin_log_file_pos
-+ mysql_bin_log_file_name
-+ mysqld_embedded
-+ my_thread_name
-+ my_malloc
-+ my_no_flags_free
-+ _sanity
-+ _mymalloc
-+ _myfree
-+ _my_strdup
-+ _my_thread_var
-+ my_error
-+ pthread_cond_init
-+ pthread_cond_signal
-+ pthread_cond_wait
-+ pthread_cond_destroy
-+ localtime_r
-+ my_strdup
-
-diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def
---- sql/mysqld_x64.def.orig 1969-12-31 18:00:00 -06:00
-+++ sql/mysqld_x64.def 2008-10-31 02:22:04 -05:00
-@@ -0,0 +1,98 @@
-+EXPORTS
-+ ?use_hidden_primary_key@handler@@UEAAXXZ
-+ ?get_dynamic_partition_info@handler@@UEAAXPEAUPARTITION_INFO@@I@Z
-+ ?read_first_row@handler@@UEAAHPEAEI@Z
-+ ?read_range_next@handler@@UEAAHXZ
-+ ?read_range_first@handler@@UEAAHPEBUst_key_range@@0_N1@Z
-+ ?read_multi_range_first@handler@@UEAAHPEAPEAUst_key_multi_range@@PEAU2@I_NPEAUst_handler_buffer@@@Z
-+ ?read_multi_range_next@handler@@UEAAHPEAPEAUst_key_multi_range@@@Z
-+ ?index_read_idx_map@handler@@UEAAHPEAEIPEBEKW4ha_rkey_function@@@Z
-+ ?print_error@handler@@UEAAXHH@Z
-+ ?clone@handler@@UEAAPEAV1@PEAUst_mem_root@@@Z
-+ ?get_auto_increment@handler@@UEAAX_K00PEA_K1@Z
-+ ?index_next_same@handler@@UEAAHPEAEPEBEI@Z
-+ ?get_error_message@handler@@UEAA_NHPEAVString@@@Z
-+ ?ha_thd@handler@@IEBAPEAVTHD@@XZ
-+ ?update_auto_increment@handler@@QEAAHXZ
-+ ?ha_statistic_increment@handler@@IEBAXPEQsystem_status_var@@K@Z
-+ ?trans_register_ha@@YAXPEAVTHD@@_NPEAUhandlerton@@@Z
-+ ?cmp@Field_blob@@QEAAHPEBEI0I@Z
-+ ?set_time@Field_timestamp@@QEAAXXZ
-+ ?sql_print_error@@YAXPEBDZZ
-+ ?sql_print_warning@@YAXPEBDZZ
-+ ?check_global_access@@YA_NPEAVTHD@@K@Z
-+ ?schema_table_store_record@@YA_NPEAVTHD@@PEAUst_table@@@Z
-+ ?get_quote_char_for_identifier@@YAHPEAVTHD@@PEBDI@Z
-+ ?copy@String@@QEAA_NXZ
-+ ?copy@String@@QEAA_NAEBV1@@Z
-+ ?copy@String@@QEAA_NPEBDIPEAUcharset_info_st@@@Z
-+ ?copy_and_convert@@YAIPEADIPEAUcharset_info_st@@PEBDI1PEAI@Z
-+ ?filename_to_tablename@@YAIPEBDPEADI@Z
-+ ?strconvert@@YAIPEAUcharset_info_st@@PEBD0PEADIPEAI@Z
-+ ?calculate_key_len@@YAIPEAUst_table@@IPEBEK@Z
-+ ?sql_alloc@@YAPEAX_K@Z
-+ ?localtime_to_TIME@@YAXPEAUst_mysql_time@@PEAUtm@@@Z
-+ ?push_warning@@YAPEAVMYSQL_ERROR@@PEAVTHD@@W4enum_warning_level@1@IPEBD@Z
-+ ?push_warning_printf@@YAXPEAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPEBDZZ
-+ ?drop_table@handler@@EEAAXPEBD@Z
-+ ?column_bitmaps_signal@handler@@UEAAXXZ
-+ ?delete_table@handler@@MEAAHPEBD@Z
-+ ?rename_table@handler@@MEAAHPEBD0@Z
-+ ?key_map_empty@@3V?$Bitmap@$0EA@@@B
-+ ?THR_THD@@3PEAVTHD@@EA
-+ ?end_of_list@@3Ulist_node@@A
-+ ?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
-+ mysql_query_cache_invalidate4
-+ thd_query
-+ thd_sql_command
-+ thd_get_thread_id
-+ thd_get_xid
-+ thd_slave_thread
-+ thd_non_transactional_update
-+ thd_mark_transaction_to_rollback
-+ thd_security_context
-+ thd_charset
-+ thd_test_options
-+ thd_ha_data
-+ thd_killed
-+ thd_tx_isolation
-+ thd_tablespace_op
-+ thd_sql_command
-+ thd_memdup
-+ thd_make_lex_string
-+ thd_in_lock_tables
-+ thd_binlog_format
-+ _my_hash_init
-+ my_hash_free
-+ my_tmpdir
-+ check_if_legal_filename
-+ my_filename
-+ my_sync_dir_by_file
-+ alloc_root
-+ thr_lock_data_init
-+ thr_lock_init
-+ thr_lock_delete
-+ my_multi_malloc
-+ get_charset
-+ unpack_filename
-+ my_hash_insert
-+ my_hash_search
-+ my_hash_delete
-+ mysql_bin_log_file_pos
-+ mysql_bin_log_file_name
-+ mysqld_embedded
-+ my_thread_name
-+ my_malloc
-+ my_no_flags_free
-+ _sanity
-+ _mymalloc
-+ _myfree
-+ _my_strdup
-+ _my_thread_var
-+ my_error
-+ pthread_cond_init
-+ pthread_cond_signal
-+ pthread_cond_wait
-+ pthread_cond_destroy
-+ localtime_r
-+ my_strdup
-
-diff -Nur win/configure.js.orig win/configure.js
---- win/configure.js.orig 2008-09-26 21:18:37 -05:00
-+++ win/configure.js 2008-10-01 11:21:27 -05:00
-@@ -49,6 +49,7 @@
- case "CYBOZU":
- case "EMBED_MANIFESTS":
- case "WITH_EMBEDDED_SERVER":
-+ case "INNODB_DYNAMIC_PLUGIN":
- configfile.WriteLine("SET (" + args.Item(i) + " TRUE)");
- break;
- case "MYSQL_SERVER_SUFFIX":
-
-diff -Nur win/build-vs71.bat.orig win/build-vs71.bat
---- win/build-vs71.bat.orig 2008-08-20 10:21:59 -05:00
-+++ win/build-vs71.bat 2008-10-27 10:52:38 -05:00
-@@ -15,8 +15,10 @@
- REM along with this program; if not, write to the Free Software
- REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
-+
- if exist cmakecache.txt del cmakecache.txt
- copy win\vs71cache.txt cmakecache.txt
--cmake -G "Visual Studio 7 .NET 2003"
-+cmake -G "Visual Studio 7 .NET 2003" -DCMAKE_BUILD_TYPE=%1
- copy cmakecache.txt win\vs71cache.txt
-
-diff -Nur win/build-vs8.bat.orig win/build-vs8.bat
---- win/build-vs8.bat.orig 2008-08-20 10:21:59 -05:00
-+++ win/build-vs8.bat 2008-10-27 10:52:31 -05:00
-@@ -15,7 +15,9 @@
- REM along with this program; if not, write to the Free Software
- REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
-+
- if exist cmakecache.txt del cmakecache.txt
- copy win\vs8cache.txt cmakecache.txt
--cmake -G "Visual Studio 8 2005"
-+cmake -G "Visual Studio 8 2005" -DCMAKE_BUILD_TYPE=%1
- copy cmakecache.txt win\vs8cache.txt
-diff -Nur win/build-vs8_x64.bat.orig win/build-vs8_x64.bat
---- win/build-vs8_x64.bat.orig 2008-08-20 10:21:59 -05:00
-+++ win/build-vs8_x64.bat 2008-10-27 10:53:11 -05:00
-@@ -15,7 +15,9 @@
- REM along with this program; if not, write to the Free Software
- REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
-+
- if exist cmakecache.txt del cmakecache.txt
- copy win\vs8cache.txt cmakecache.txt
--cmake -G "Visual Studio 8 2005 Win64"
-+cmake -G "Visual Studio 8 2005 Win64" -DCMAKE_BUILD_TYPE=%1
- copy cmakecache.txt win\vs8cache.txt