Below is the list of changes that have just been committed into a local
6.0 repository of guilhem. When guilhem does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-11-28 22:51:34+01:00, guilhem@stripped +79 -0
WL#866 - Online backup driver for MyISAM.
When this driver (file myisam_backup_engine.cc) is to do a backup,
it starts physical logging of changes for target tables (file
mi_log.c), dirtily copies tables, then the physical log.
When this driver does a restore, it copies back tables and the log,
applies the log (file mi_examine_log.c).
The data file is always backed up; for the index file two methods are
available: either only its 64KB header is copied and then restore will
repair indexes, or the whole index file is copied.
Backup starts and runs without disturbing any running or new update
except at the very end: when creating the validity point it locks all
backed-up MyISAM tables with a read lock (so, stalls new update
statements and waits for running update statements to finish).
I recommend to readers to read in order myisam_backup_engine.cc,
mi_log.c then other files.
GUILHEM_TODO tag identifies the most urgent todo.
Fixes for misc bugs found along the way of development:
missing initialization in Bitmap<64>, issues with the dbug library.
dbug/dbug.c@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +1 -0
bugfix provided by Serg, for when doing "SET DEBUG=-d,etc"
(process hung).
include/atomic/nolock.h@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +4 -1
comment
include/keycache.h@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +11 -2
A block now has an optional post_write_arg. A key cache has a global
post_write function which is called after any block is written to its file.
The block's post_write_arg is set through key_cache_write(). The
key cache's post_write is set when opening MyISAM tables.
This is used by MyISAM's physical logging: when a key page
is flushed to the file, the write is also recorded in the physical log,
thanks to such callback.
include/my_atomic.h@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +6 -1
work around gcc bug
include/my_global.h@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +5 -3
When testing a C++ file against "gcc -Wold-style-cast", these casts
surfaced. STATIC_CAST means "a static cast which works in
C and in C++, without -Wold-style-cast warnings".
include/my_sys.h@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +27 -11
New members of IO_CACHE:
* post_write (called by my_b_flush_io_cache()),
* hard_write_error_in_the_past: like the existing 'error' except that
once set it is not reset until cache is reinitialized; 'error' is
reset at next _my_b_write() call for example. Is useful when we want
to lazily (once in a while) monitor if an IO_CACHE got a write error
(and so, file is not usable) instead of monitoring each IO_CACHE write.
These are used by MyISAM's online backup (myisam_backup_engine.cc)
to test if the physical log got a write error.
include/myisam.h@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +18 -3
declarations' update.
mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test@stripped, 2007-11-28
22:51:28+01:00, guilhem@stripped +1 -1
don't pollute rest of the calling test by keeping a lock.
mysql-test/mysql-test-run.pl@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped
+21 -0
ability to call myisamlog from tests (for new test t/myisamlog.test)
mysql-test/r/backup.result@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +157
-45
result update.
Note, for the first test, the increase in backup size which is due to:
- more tables to back up
- the MyISAM native driver copies the index file which is always at
least 1 KB, while the generic locking driver (which was used for MyISAM
so far) copies only rows, so can give a smaller backup.
Note how the checksums after restore are equal to those at the _end_ of
the backup. CHECKSUM is used instead of SELECT.
For the second test, MyISAM table has no index, and MYD is more
compact that row format used by the default backup driver, so size
decreases.
mysql-test/r/backup_commit_blocker.result@stripped, 2007-11-28 22:51:28+01:00,
guilhem@stripped +2 -1
result update
mysql-test/r/backup_ddl_blocker.result@stripped, 2007-11-28 22:51:28+01:00,
guilhem@stripped +62 -61
"header" increased because it contains name of driver, "MyISAM"
is 6 bytes, "default" used 0 bytes; 1 byte for name's length, =7.
mysql-test/r/backup_fkey.result@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped
+9 -9
"header" increased because it contains name of driver, "MyISAM"
is 6 bytes, "default" used 0 bytes; 1 byte for name's length, =7.
mysql-test/r/backup_myisam1.result@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +7 -0
result
mysql-test/r/backup_myisam1.result@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +0 -0
mysql-test/r/backup_myisam2.result@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +61 -0
result is ok: checksums match.
mysql-test/r/backup_myisam2.result@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +0 -0
mysql-test/r/backup_no_engine.result@stripped, 2007-11-28 22:51:28+01:00,
guilhem@stripped +6 -6
MyISAM driver gives larger backup than default driver because it
backs up the index (which is 1KB in this case).
"header" increased because it contains name of driver, "MyISAM"
is 6 bytes, "default" used 0 bytes; 1 byte for name's length, =7.
mysql-test/r/backup_security.result@stripped, 2007-11-28 22:51:28+01:00,
guilhem@stripped +12 -12
"header" increased because it contains name of driver, "MyISAM"
is 6 bytes, "default" used 0 bytes; 1 byte for name's length, =7.
mysql-test/r/myisamlog.result@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped +48
-0
result
mysql-test/r/myisamlog.result@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped +0
-0
mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result@stripped, 2007-11-28
22:51:28+01:00, guilhem@stripped +1 -0
result update
mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result@stripped, 2007-11-28
22:51:28+01:00, guilhem@stripped +1 -0
result update
mysql-test/t/backup.test@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +142 -22
testing of online backup for MyISAM:
- table 'staff' is augmented (index, more records)
- a second MyISAM table is added, 'tasking2' with indices and
delay_key_write.
- a third MyISAM table is added, 'staff2' to test index rebuilds
done by bulk insert when the table is empty.
A backup is launched but blocked before it creates the validity
point; then we modify MyISAM tables. After restore, we verify
that restored tables are as they originally were at end of backup,
i.e. they contain the modifications.
Too long lines are wrapped.
mysql-test/t/backup_commit_blocker.test@stripped, 2007-11-28 22:51:28+01:00,
guilhem@stripped +6 -6
patch provided by Chuck: don't go through BACKUP_BREAKPOINT()
when holding a user-level lock.
Use +- so that it does not cancel all of --debug
(+ adds to the existing debug variable, which is possibly set
by --debug). Do SET GLOBAL before creating connections
(SET GLOBAL is supposed to influence only future connections,
though DEBUG might be an exception).
mysql-test/t/backup_ddl_blocker.test@stripped, 2007-11-28 22:51:28+01:00,
guilhem@stripped +4 -8
Use +- so that it does not cancel all of --debug
(+ adds to the existing debug variable, which is possibly set
by --debug). Do SET GLOBAL before creating connections
(SET GLOBAL is supposed to influence only future connections,
though DEBUG might be an exception).
mysql-test/t/backup_myisam1-master.opt@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +1 -0
test with external locking
mysql-test/t/backup_myisam1-master.opt@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +0 -0
mysql-test/t/backup_myisam1.test@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped
+14 -0
test that backup fails with external locking
mysql-test/t/backup_myisam1.test@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped
+0 -0
mysql-test/t/backup_myisam2.test@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped
+66 -0
test of records >64k (see MI_LOG_BIG_NUMBERS in mi_log.c)
mysql-test/t/backup_myisam2.test@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped
+0 -0
mysql-test/t/key_cache.test@stripped, 2007-11-28 22:51:28+01:00, guilhem@stripped +3
-3
As the size of the BLOCK_LINK structure has grown (to accomodate
the new post_write_arg member), the number
of available blocks for a fixed key cache size has decreased
(a similar fix will be needed for 64-bit systems too)
mysql-test/t/myisamlog-master.opt@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped
+1 -0
To test the MyISAM logical log, which cannot be enabled on the fly.
mysql-test/t/myisamlog-master.opt@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped
+0 -0
mysql-test/t/myisamlog.test@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped +37
-0
Test of MyISAM logical logging and the myisamlog utility:
see if they can repopulate a table.
mysql-test/t/myisamlog.test@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped +0 -0
mysys/mf_iocache.c@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +53 -19
Calling the new post_write hook. Note that it does not work with
SEQ_READ_APPEND IO_CACHEs (we don't need a post_write for them now).
Setting IO_CACHE::hard_write_error_in_the_past at the same time we
set IO_CACHE::error to -1 in functions which do writes.
IO_CACHE::hard_write_error_in_the_past is however not reset for
each write, that's its difference from IO_CACHE::error.
mysys/mf_keycache.c@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +60 -17
A block now has an optional post_write_arg which is used by
keycache->post_write after flushing the block.
We make sure that all pwrite() call keycache->post_write, by replacing
them by a new key_cache_pwrite().
This is used by MyISAM's physical logging.
mysys/my_thr_init.c@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +16 -4
A dedicated mutex for the MyISAM log (better not use THR_LOCK_myisam
which is already used at every mi_open()/mi_close(), and also it made
coding easier, see comments in _myisam_log_command()).
In my_thread_end(), do a DBUG_POP() so that if the thread has used
SET DEBUG=, the memory allocated by that SET is freed.
sql/backup/archive.h@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +6 -0
bugfix (for memory leak) provided by Rafal
sql/backup/backup_aux.h@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +1 -1
unneeded initialization
sql/backup/be_thread.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +1 -5
no need to "delete" if thd is NULL. C++ cast.
sql/backup/data_backup.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +7 -7
Bugfix: pump was registered in list before its begin(); if begin()
failed it was deleted but left in list, crash.
sql/backup/stream.h@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +10 -2
temporary bugfix. Too long comment lines, but the whole
block will go away soon.
sql/item_func.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +22 -7
debug_sync_point() implicitely releases any user-level lock held
by the current thread (like GET_LOCK()) ones; this is incorrect for
testing: assert that it does not hold a lock, and a comment to suggest
proper usage.
sql/mysqld.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +7 -7
emphasizing that the MyISAM log set from the command line is the
logical one.
sql/sql_bitmap.h@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +2 -2
Fix for valgrind error (unrelated to MyISAM online backup driver):
Bitmap<64> needs to initialize in its constructor, like the any-other-size
Bitmap does. Bug specific of 6.0.
sql/sql_cache.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +3 -2
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
sql/sql_class.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +3 -2
For the "locking threads" created by some online backup drivers
(MyISAM one and default lock-based one), THD::awake() must abort locks.
That if() dates from a time where the only possible system threads
were the delayed insert system thread and the slave threads.
sql/sql_load.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +1 -2
cast not needed
sql/sql_repl.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +4 -1
new prototype
sql/sql_repl.h@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +1 -1
new prototype
sql/sql_table.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +3 -0
As start_bulk_insert() has been called, end_bulk_insert() must be
called (bug found thanks to new assertion in mi_locking.c)
storage/myisam/CMakeLists.txt@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +1
-1
include new files in build
storage/myisam/Makefile.am@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +1 -1
include new files in build
storage/myisam/ha_myisam.cc@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +12
-7
MyISAM now has an online backup driver, see myisam_backup_engine.cc.
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name.
Unset STATE_BAD_OPEN_COUNT after a successful check or repair.
Fix for doxygen.err warnings.
storage/myisam/ha_myisam.h@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +4 -0
MyISAM now has an online backup driver
storage/myisam/mi_check.c@stripped, 2007-11-28 22:51:29+01:00, guilhem@stripped +83
-11
mi_state_info_write() needs the MYISAM_SHARE now, as it is used by
physical logging.
Note: REPAIR/OPTIMIZE TABLE are not handled by
physical logging; they should be blocked by the MySQL online backup
kernel: when they delete/create/rename files, they are as much
a problem as ALTER TABLE. So we assert for these cases.
At end of INSERT SELECT, if the table was originally empty,
an index rebuild is done. This uses my_pwrite() and my_chsize(),
which we thus have to write to the physical log.
storage/myisam/mi_close.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +12 -2
If we failed to flush the key cache, we need to mark the table as
corrupted (fix for an unlikely bug).
mi_state_info_write() needs the MYISAM_SHARE now, as it is used by
physical logging.
If the table has logged a MI_LOG_OPEN to the physical log (because it
has logged some writes there), it needs to log a MI_LOG_CLOSE too.
Regarding the added assertion, see revision comment in mi_locking.c.
storage/myisam/mi_create.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +9 -1
Ensure that no table is truncated if it is doing physical
logging. We *could* support TRUNCATE during an online backup of
MyISAM (switch off HTON_CAN_RECREATE during backup) but:
- it would require some synchro (no backup can start while recreate-based
truncate is running, etc)
- consistent-snapshot driver can't bear TRUNCATE anyway.
Another possibility is also to always switch off HTON_CAN_RECREATE.
storage/myisam/mi_delete.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +7 -4
update to new prototype.
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
storage/myisam/mi_delete_all.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped
+4 -1
Log to the physical log the MI_DELETE_ALL operation
storage/myisam/mi_dynrec.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +23
-13
Log to the physical log the operation of writing bytes to the data file.
Always log _after_ the write (see comment at start of
mi_log_start_physical()).
storage/myisam/mi_examine_log.c@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped
+871 -0
This is the examine_log() function taken out of myisamlog.c, as we
now need it in the server too, to restore from an online backup.
It is renamed to mi_examine_log().
examine_log() used global variables of myisamlog.c, that is not possible
now so mi_examine_log() takes in parameter a new structure
MI_EXAMINE_LOG_PARAM whose content corresponds to the old global
variables.
The function is extended to understand new log commands found in
physical logs: MI_LOG_WRITE_BYTES_MYI, MI_LOG_WRITE_BYTES_MYD,
MI_LOG_CHSIZE_MYI, as well as MI_LOG_DELETE_ALL which wasn't replayed
properly (a bug).
Other bugfix: NO_FILEPOS was too small for 64-bit machines.
Other bugfix: MI_LOG_LOCK applying could not work because it didn't
remove the 'flag' added at the end of mi_lock_database().
To see the real code changes I made (because, most of lines are just
moved from myisamlog.c), you should diff mi_examine_log() with
examine_log() from the old myisamlog.c (I recommend it).
storage/myisam/mi_examine_log.c@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped
+0 -0
storage/myisam/mi_extra.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +59 -3
When we set up a write cache (HA_EXTRA_WRITE_CACHE) we give the cache
a post_write call, which will make sure that writes to the data file
will go to the physical log if needed.
It is more efficient that logging all my_b_write()s as it generates
less log records, and anyway we needed the post_write callback for
when logging is enabled while the table is in already the middle of
using a write cache, when non-logged my_b_write()s have passed already.
mi_state_info_write() needs the MYISAM_SHARE now, as it is used by
physical logging
storage/myisam/mi_locking.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +89
-46
Comments explaining why certain writes to the index file needn't go into
the physical log.
New function mi_remap_file_and_write_state_for_unlock(), used when
unlocking a table and in mi_backup_stop_logging_for_tables().
If logical log, we now always log MI_LOG_LOCK. Indeed, without it,
the MI_LOG_EXTRA failed to apply when command was HA_EXTRA_CACHE (see
the EACCES error in mi_extra():
missing MI_LOG_LOCK => info->lock_type==F_UNLCK => applying of
MI_LOG_EXTRA failed (so myisamlog.test got such warnings in
mysqltest.log: "Warning: error 13, expected 0 on command extra at 211").
We also make the storage of lock_type portable (independent of
endianess).
storage/myisam/mi_log.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +779 -80
mi_log() can now open a logical (==debug)or physical (==backup) log:
it thus receives new parameters (list of tables...); it can
close logs too. Opening and closing a physical log is more work
than a logical one, so additional functions are called.
Logging functions now use IO_CACHE instead of my_write(), to be
faster.
_myisam_log() merged into _myisam_log_command() (they were very
similar).
If _myisam_log_command() uses small numbers (file descriptor,
file offset buffer length) it stores them in few bytes; if they are big
it stores them in more bytes; how many bytes are used is denoted
by the highest bit of the 'command' (MI_LOG_BIG_NUMBERS).
That and the merge of _myisam_log() and _myisam_log_command()
imply that old myisamlog won't read new logical log, but it's ok: the
MyISAM log was so far only for debugging, advertised as such,
apparently used only by MySQL devs, and had a bug (MI_LOG_DELETE_ALL
was not replayed by myisamlog) which nobody reported.
_myisam_log_record() renamed to _myisam_log_record_logical()
(used only by logical logging).
Logging functions now need to check if the log is opened _inside the
log's mutex_, because the physical log can close at any time (while
the old logical log, was either open or closed for the
lifetime of the MySQL server process).
_myisam_log_command() may log MI_LOG_OPEN on top of its command
(needed for physical logging), if this is a physical log and
the first time this table's share writes to it.
_myisam_log_record() is used only by logical logging, renamed it.
storage/myisam/mi_open.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +114
-25
When opening a table, detect if it must do physical logging;
and remember with STATE_BAD_OPEN_COUNT if open_count>0 at first
open (this way, online backup can know if the open_count>0 which it
sees is a real problem or not); set key cache's post_write.
mi_state_info_write() needs the MYISAM_SHARE now, as it needs to
record the my_pwrite() done to the index file, into the physical log.
Note, for now all calls to mi_state_info_write() have the state
equal to the share's state but future projects may not have that,
that's why the two arguments stay.
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name,
indeed physical logging needs this unresolved name, and
sometimes cannot have MI_INFO available, but always has MYISAM_SHARE
(see log_key_cache_flush_physical()). It is also more
efficient (why duplicate the same string in all MI_INFOs for a same
table?).
storage/myisam/mi_page.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +17 -15
passing "share" as post_write_arg to key_cache_write()
storage/myisam/mi_panic.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +11 -7
update for new prototype.
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
storage/myisam/mi_rrnd.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +1 -3
cosmetic change
storage/myisam/mi_static.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +36
-5
New physical log in MyISAM. MyISAM-specific error messages.
storage/myisam/mi_test2.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +3 -3
update for new prototype. Complement to the fix of BUG#30094
(this complement has been approved by Serg and pushed in another
tree months ago); the bug caused random assertion failures.
storage/myisam/mi_test3.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +2 -2
update for new prototype
storage/myisam/mi_test_all.sh@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +2
-0
We need to remove logs from previous "mi_test_all" runs, or a bug
in writing myisam.log would continue to make the test fail even
though bug is fixed (mi_test2 would just append to the bad log).
storage/myisam/mi_update.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +6 -4
update to new prototype.
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
storage/myisam/mi_write.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +5 -4
update to new prototype.
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
storage/myisam/myisam_backup_engine.cc@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +1918 -0
MyISAM online backup engine. See this file's first lines (namespace
myisam_backup) for a description of how it works.
This is the file which really drives the backup/restore inside MyISAM
(see it as the master which calls functions from other files to
perform some subtasks).
Note that Chuck has taken some code from this file and it is now
duplicated into sql/backup/ files, I should merge the two
to avoid duplication, when Chuck's work is pushed
storage/myisam/myisam_backup_engine.cc@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +0 -0
storage/myisam/myisam_ftdump.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped
+2 -1
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
storage/myisam/myisamchk.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +4
-2
STATE_BAD_OPEN_COUNT reset on repair
storage/myisam/myisamdef.h@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +131
-19
Adding member "physical_logging" to MYISAM_SHARE, tells if the table
is currently doing physical logging or not.
It is read and set with atomic operations: this provides the needed
synchronization between the table-writer thread (if the table is being
written now) (which is the reader of "physical_logging") and the thread
turning physical logging on or off (which is the writer of
"physical_logging").
Adding member "MI_LOG_OPEN_stored_in_physical_log" to MYISAM_SHARE, to
remember if we already stored MI_LOG_OPEN in this physical log for this
table.
A new mutex THR_LOCK_myisam_log to protect MyISAM logs (instead of
THR_LOCK_myisam, for concurrency and coding reasons (explained
in _myisam_log_command()).
New commands which can be stored only in the physical log:
MI_LOG_WRITE_BYTES_MYD, MI_LOG_WRITE_BYTES_MYI, MI_LOG_CHSIZE_MYI.
Updates to myisam_log_* macros to adapt to the fact that logs are now
an IO_CACHE and not a plain OS file.
As most of the logic of myisamlog moved out of myisamlog.c into
mi_examine_log.c, mi_examine_log() cannot use globals of myisamlog.c
anymore; a new structure MI_EXAMINE_LOG_PARAM is introduced instead
(like MI_CHECK). mi_state_info_write() needs the MYISAM_SHARE now, as
it is used by physical logging.
Flag STATE_BAD_OPEN_COUNT.
Note: all extern vars touched in this file have their documentation
in the file where they are defined.
storage/myisam/myisamlog.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +74
-624
The main function of this file, examine_log(), is now needed in
the server to be able to do a restore from an online backup,
so moves to mi_examine_log.c.
I changed a meaningless min() to max().
New log commands (MI_LOG_etc) have long names so I widened the
space for displaying their name to 20 characters.
Due to backward-incompatibilities (see mi_log.c) we bump version
number to 2.0.
storage/myisam/myisampack.c@stripped, 2007-11-28 22:51:30+01:00, guilhem@stripped +10
-5
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name.
mi_state_info_write() needs MYISAM_SHARE as physical logging does.
storage/myisammrg/ha_myisammrg.cc@stripped, 2007-11-28 22:51:31+01:00,
guilhem@stripped +4 -4
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
storage/myisammrg/myrg_info.c@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped +2
-1
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
storage/myisammrg/myrg_rrnd.c@stripped, 2007-11-28 22:51:31+01:00, guilhem@stripped +1
-1
MI_INFO::filename is now MYISAM_SHARE::unresolv_file_name
diff -Nrup a/dbug/dbug.c b/dbug/dbug.c
--- a/dbug/dbug.c 2007-10-15 18:56:22 +02:00
+++ b/dbug/dbug.c 2007-11-28 22:51:28 +01:00
@@ -1296,6 +1296,7 @@ static struct link *ListDel(struct link
free((void*) delme);
}
} while (*cur && *(cur=&((*cur)->next_link)));
+ ctlp++;
}
return head;
}
diff -Nrup a/include/atomic/nolock.h b/include/atomic/nolock.h
--- a/include/atomic/nolock.h 2007-10-09 19:55:11 +02:00
+++ b/include/atomic/nolock.h 2007-11-28 22:51:28 +01:00
@@ -29,7 +29,10 @@
#endif
#ifdef make_atomic_cas_body
-
+/*
+ Type not used so minimal size (emptry struct has different size between C
+ and C++, zero-length array is gcc-specific).
+*/
typedef char my_atomic_rwlock_t __attribute__ ((unused));
#define my_atomic_rwlock_destroy(name)
#define my_atomic_rwlock_init(name)
diff -Nrup a/include/keycache.h b/include/keycache.h
--- a/include/keycache.h 2007-10-02 09:32:29 +02:00
+++ b/include/keycache.h 2007-11-28 22:51:28 +01:00
@@ -13,7 +13,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Key cache variable structures */
+/**
+ @file
+ Key cache API
+*/
#ifndef _keycache_h
#define _keycache_h
@@ -34,6 +37,10 @@ typedef struct st_keycache_wqueue
struct st_my_thread_var *last_thread; /* circular list of waiting threads */
} KEYCACHE_WQUEUE;
+/** Callback called when any block is flushed */
+typedef int (*KEYCACHE_POST_WRITE_CALLBACK)(void *arg, const uchar *buffert,
+ uint length, my_off_t filepos);
+
#define CHANGED_BLOCKS_HASH 128 /* must be power of 2 */
/*
@@ -81,6 +88,7 @@ typedef struct st_key_cache
KEYCACHE_WQUEUE waiting_for_block; /* requests waiting for a free block */
BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/
BLOCK_LINK *file_blocks[CHANGED_BLOCKS_HASH]; /* hash for other file bl.*/
+ KEYCACHE_POST_WRITE_CALLBACK post_write;/**< Called when flushing any block*/
/*
The following variables are and variables used to hold parameters for
@@ -124,7 +132,8 @@ extern int key_cache_insert(KEY_CACHE *k
extern int key_cache_write(KEY_CACHE *keycache,
File file, my_off_t filepos, int level,
uchar *buff, uint length,
- uint block_length,int force_write);
+ uint block_length, int force_write,
+ void *post_write_arg);
extern int flush_key_blocks(KEY_CACHE *keycache,
int file, enum flush_type type);
extern void end_key_cache(KEY_CACHE *keycache, my_bool cleanup);
diff -Nrup a/include/my_atomic.h b/include/my_atomic.h
--- a/include/my_atomic.h 2007-10-09 19:55:10 +02:00
+++ b/include/my_atomic.h 2007-11-28 22:51:28 +01:00
@@ -83,7 +83,12 @@
#endif
#endif
-#ifdef __GNUC__
+/*
+ Some gcc versions (gcc (GCC) 4.1.2 20061115 (prerelease) (SUSE Linux))
+ unfortunately fail when the transparent unions below are included in C++
+ files.
+*/
+#if defined(__GNUC__) && !defined(__cplusplus)
/*
we want to be able to use my_atomic_xxx functions with
both signed and unsigned integers. But gcc will issue a warning
diff -Nrup a/include/my_global.h b/include/my_global.h
--- a/include/my_global.h 2007-11-14 11:54:37 +01:00
+++ b/include/my_global.h 2007-11-28 22:51:28 +01:00
@@ -68,9 +68,11 @@
#ifdef __cplusplus
#define C_MODE_START extern "C" {
#define C_MODE_END }
+#define STATIC_CAST(TYPE) static_cast<TYPE>
#else
#define C_MODE_START
#define C_MODE_END
+#define STATIC_CAST(TYPE) (TYPE)
#endif
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
@@ -936,7 +938,7 @@ typedef long long my_ptrdiff_t;
#define my_offsetof(TYPE, MEMBER) \
((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
-#define NullS (char *) 0
+#define NullS STATIC_CAST(char *)(0)
/* Nowdays we do not support MessyDos */
#ifndef NEAR
#define NEAR /* Who needs segments ? */
@@ -1052,7 +1054,7 @@ typedef ulonglong my_off_t;
#else
typedef unsigned long my_off_t;
#endif
-#define MY_FILEPOS_ERROR (~(my_off_t) 0)
+#define MY_FILEPOS_ERROR (~STATIC_CAST(my_off_t)(0))
#if !defined(__WIN__)
typedef off_t os_off_t;
#endif
@@ -1089,7 +1091,7 @@ typedef char bool; /* Ordinary boolean
#define INT8(v) (int8) (v)
#define INT16(v) (int16) (v)
#define INT32(v) (int32) (v)
-#define MYF(v) (myf) (v)
+#define MYF(v) STATIC_CAST(myf)(v)
#ifndef LL
#ifdef HAVE_LONG_LONG
diff -Nrup a/include/my_sys.h b/include/my_sys.h
--- a/include/my_sys.h 2007-11-14 17:29:46 +01:00
+++ b/include/my_sys.h 2007-11-28 22:51:28 +01:00
@@ -13,6 +13,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/**
+ @file
+ mysys library API
+*/
+
#ifndef _my_sys_h
#define _my_sys_h
C_MODE_START
@@ -335,7 +340,10 @@ typedef struct st_dynamic_string
} DYNAMIC_STRING;
struct st_io_cache;
-typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
+/** Function called when certain events happen to an IO_CACHE */
+typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache *cache,
+ const uchar *buffert, uint length,
+ my_off_t filepos);
#ifdef THREAD
typedef struct st_io_cache_share
@@ -434,21 +442,24 @@ typedef struct st_io_cache /* Used when
*/
enum cache_type type;
/*
- Callbacks when the actual read I/O happens. These were added and
- are currently used for binary logging of LOAD DATA INFILE - when a
- block is read from the file, we create a block create/append event, and
- when IO_CACHE is closed, we create an end event. These functions could,
- of course be used for other things
- */
- IO_CACHE_CALLBACK pre_read;
- IO_CACHE_CALLBACK post_read;
- IO_CACHE_CALLBACK pre_close;
+ Callbacks were added and are currently used for binary logging of LOAD
+ DATA INFILE - when a block is read from the file, we create a block
+ create/append event, and when IO_CACHE is closed, we create an end event;
+ also used to write the MyISAM WRITE_CACHE blocks to the MyISAM physical
+ log. These functions could, of course be used for other things. Note: some
+ callbacks share the same argument ("arg").
+ */
+ IO_CACHE_CALLBACK pre_read; /**< called before reading from disk */
+ IO_CACHE_CALLBACK post_read; /**< called after reading from disk */
+ IO_CACHE_CALLBACK pre_close; /**< called before ending the cache */
+ /** Called _after_ writing to disk; not honoured by SEQ_READ_APPEND */
+ IO_CACHE_CALLBACK post_write;
/*
Counts the number of times, when we were forced to use disk. We use it to
increase the binlog_cache_disk_use status variable.
*/
ulong disk_writes;
- void* arg; /* for use by pre/post_read */
+ void *arg; /**< used by pre/post_read,post_write */
char *file_name; /* if used with 'open_cached_file' */
char *dir,*prefix;
File file; /* file descriptor */
@@ -460,6 +471,11 @@ typedef struct st_io_cache /* Used when
partial.
*/
int seek_not_done,error;
+ /**
+ Cumulative 'error' since last [re]init_io_cache(). Useful if cache's user
+ polls for errors only once in a while.
+ */
+ int hard_write_error_in_the_past;
/* buffer_length is memory size allocated for buffer or write_buffer */
size_t buffer_length;
/* read_length is the same as buffer_length except when we use async io */
diff -Nrup a/include/myisam.h b/include/myisam.h
--- a/include/myisam.h 2007-10-22 13:43:27 +02:00
+++ b/include/myisam.h 2007-11-28 22:51:28 +01:00
@@ -13,7 +13,10 @@
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 should be included when using myisam_funktions */
+/**
+ @file
+ This file should be included when using MyISAM functions.
+*/
#ifndef _myisam_h
#define _myisam_h
@@ -32,6 +35,7 @@ extern "C" {
#endif
#include "my_handler.h"
#include <mysql/plugin.h>
+#include <hash.h>
/*
There is a hard limit for the maximum number of keys as there are only
@@ -257,10 +261,13 @@ typedef struct st_columndef /* column i
#endif
} MI_COLUMNDEF;
+/** Physical logging is always compiled in. Undefine if want to benchmark */
+#define HAVE_MYISAM_PHYSICAL_LOGGING 1
+
/* invalidator function reference for Query Cache */
typedef void (* invalidator_by_filename)(const char * filename);
-extern char * myisam_log_filename; /* Name of logfile */
+extern char * myisam_logical_log_filename;
extern ulong myisam_block_size;
extern ulong myisam_concurrent_insert;
extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
@@ -305,7 +312,15 @@ extern int mi_extra(struct st_myisam_inf
extern int mi_reset(struct st_myisam_info *file);
extern ha_rows mi_records_in_range(MI_INFO *info, int inx,
key_range *min_key, key_range *max_key);
-extern int mi_log(int activate_log);
+/** Open/close actions allowed on a MyISAM log */
+enum enum_mi_log_action
+{
+ MI_LOG_ACTION_OPEN,
+ MI_LOG_ACTION_CLOSE_CONSISTENT, MI_LOG_ACTION_CLOSE_INCONSISTENT
+};
+enum enum_mi_log_type { MI_LOG_PHYSICAL, MI_LOG_LOGICAL };
+extern int mi_log(enum enum_mi_log_action action, enum enum_mi_log_type type,
+ const char *log_filename, const HASH *tables);
extern int mi_is_changed(struct st_myisam_info *info);
extern int mi_delete_all_rows(struct st_myisam_info *info);
extern ulong _mi_calc_blob_length(uint length , const uchar *pos);
diff -Nrup a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
--- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test 2007-10-13 15:11:08
+02:00
+++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test 2007-11-28 22:51:28
+01:00
@@ -315,4 +315,4 @@ disconnect con3;
connection con4;
select get_lock("a",10); # wait for rollback to finish
-
+do release_lock("a");
diff -Nrup a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
--- a/mysql-test/mysql-test-run.pl 2007-11-22 20:45:08 +01:00
+++ b/mysql-test/mysql-test-run.pl 2007-11-28 22:51:28 +01:00
@@ -139,6 +139,7 @@ our $exe_mysql;
our $exe_mysqladmin;
our $exe_mysql_upgrade;
our $exe_mysqlbinlog;
+our $exe_myisamlog;
our $exe_mysql_client_test;
our $exe_bug25714;
our $exe_mysqld;
@@ -2015,6 +2016,26 @@ sub environment_setup () {
" --debug=d:t:A,$path_vardir_trace/log/mysqlbinlog.trace";
}
$ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog;
+
+ # ----------------------------------------------------
+ # Setup env so childs can execute myisamlog
+ # ----------------------------------------------------
+
+ my $myisam_path= mtr_file_exists("$glob_basedir/storage/myisam",
+ "$glob_basedir/bin");
+
+ $exe_myisamlog=
+ mtr_exe_exists("$myisam_path/myisamlog");
+
+ my $cmdline_myisamlog=
+ mtr_native_path($exe_myisamlog);
+
+ if ( $opt_debug )
+ {
+ $cmdline_myisamlog .=
+ " -#d:t:A,$path_vardir_trace/log/myisamlog.trace";
+ }
+ $ENV{'MYISAMLOG'}= $cmdline_myisamlog;
# ----------------------------------------------------
# Setup env so childs can execute mysql
diff -Nrup a/mysql-test/r/backup.result b/mysql-test/r/backup.result
--- a/mysql-test/r/backup.result 2007-11-09 22:32:08 +01:00
+++ b/mysql-test/r/backup.result 2007-11-28 22:51:28 +01:00
@@ -14,9 +14,9 @@ CREATE TABLE `building` (
`dir_code` char(4),
`building` char(6)
) ENGINE=archive DEFAULT CHARSET=latin1;
-LOCK TABLES `building` WRITE;
-INSERT INTO `building` VALUES
('N41','1300'),('N01','1453'),('M00','1000'),('N41','1301'),('N41','1305');
-UNLOCK TABLES;
+INSERT INTO `building` VALUES
+('N41','1300'),('N01','1453'),('M00','1000'),
+('N41','1301'),('N41','1305');
DROP TABLE IF EXISTS `directorate`;
Warnings:
Note 1051 Unknown table 'directorate'
@@ -25,9 +25,8 @@ CREATE TABLE `directorate` (
`dir_name` char(30),
`dir_head_id` char(9)
) ENGINE=archive DEFAULT CHARSET=latin1;
-LOCK TABLES `directorate` WRITE;
-INSERT INTO `directorate` VALUES ('N41','Development','333445555'),('N01','Human
Resources','123654321'),('M00','Management','333444444');
-UNLOCK TABLES;
+INSERT INTO `directorate` VALUES ('N41','Development','333445555'),
+('N01','Human Resources','123654321'),('M00','Management','333444444');
USE db2;
DROP TABLE IF EXISTS `staff`;
Warnings:
@@ -39,11 +38,26 @@ CREATE TABLE `staff` (
`last_name` char(30),
`sex` char(1),
`salary` int(11),
-`mgr_id` char(9)
+`mgr_id` char(9),
+index(mid_name)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-LOCK TABLES `staff` WRITE;
-INSERT INTO `staff` VALUES
('333445555','John','Q','Smith','M',30000,'333444444'),('123763153','William','E','Walters','M',25000,'123654321'),('333444444','Alicia','F','St.Cruz','F',25000,NULL),('921312388','Goy','X','Hong','F',40000,'123654321'),('800122337','Rajesh','G','Kardakarna','M',38000,'333445555'),('820123637','Monty','C','Smythe','M',38000,'333445555'),('830132335','Richard','E','Jones','M',38000,'333445555'),('333445665','Edward','E','Engles','M',25000,'333445555'),('123654321','Beware','D','Borg','F',55000,'333444444'),('123456789','Wilma','N','Maxima','F',43000,'333445555');
-UNLOCK TABLES;
+INSERT INTO `staff` VALUES
+('333445555','John','Q','Smith','M',30000,'333444444'),
+('123763153','William','E','Walters','M',25000,'123654321'),
+('333444444','Alicia','F','St.Cruz','F',25000,NULL),
+('921312388','Goy','X','Hong','F',40000,'123654321'),
+('800122337','Rajesh','G','Kardakarna','M',38000,'333445555'),
+('820123637','Monty','C','Smythe','M',38000,'333445555'),
+('830132335','Richard','E','Jones','M',38000,'333445555'),
+('333445665','Edward','E','Engles','M',25000,'333445555'),
+('123654321','Beware','D','Borg','F',55000,'333444444'),
+('123456789','Wilma','N','Maxima','F',43000,'333445555');
+insert into staff select * from staff;
+insert into staff select * from staff;
+insert into staff select * from staff;
+insert into staff select * from staff;
+insert into staff select * from staff;
+create table staff2 like staff;
DROP TABLE IF EXISTS `tasking`;
Warnings:
Note 1051 Unknown table 'tasking'
@@ -52,26 +66,88 @@ CREATE TABLE `tasking` (
`project_number` char(9),
`hours_worked` double(10,2)
) ENGINE=blackhole DEFAULT CHARSET=latin1;
-LOCK TABLES `tasking` WRITE;
-INSERT INTO `tasking` VALUES
('333445555','405',23),('123763153','405',33.5),('921312388','601',44),('800122337','300',13),('820123637','300',9.5),('830132335','401',8.5),('333445555','300',11),('921312388','500',13),('800122337','300',44),('820123637','401',500.5),('830132335','400',12),('333445665','600',300.25),('123654321','607',444.75),('123456789','300',1000);
-UNLOCK TABLES;
-BACKUP DATABASE db1,db2 TO 'test.ba';
+INSERT INTO `tasking` VALUES ('333445555','405',23),
+('123763153','405',33.5),('921312388','601',44),('800122337','300',13),
+('820123637','300',9.5),('830132335','401',8.5),('333445555','300',11),
+('921312388','500',13),('800122337','300',44),('820123637','401',500.5),
+('830132335','400',12),('333445665','600',300.25),('123654321','607',444.75),
+('123456789','300',1000);
+CREATE TABLE `tasking2` (
+`id` char(9),
+`project_number` char(9),
+`hours_worked` double(10,2),
+index(id), index(project_number), index(hours_worked)
+) delay_key_write=1 ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO `tasking2` VALUES
+('333445555','405',23),('123763153','405',33.5),
+('921312388','601',44),('800122337','300',13),('820123637','300',9.5),
+('830132335','401',8.5),('333445555','300',11),('921312388','500',13),
+('800122337','300',44),('820123637','401',500.5),('830132335','400',12),
+('333445665','600',300.25),('123654321','607',444.75),
+('123456789','300',1000);
+insert into tasking select * from tasking;
+insert into tasking select * from tasking;
+insert into tasking select * from tasking;
+insert into tasking select * from tasking;
+insert into tasking select * from tasking;
+SELECT get_lock("data_prepare", 100);
+get_lock("data_prepare", 100)
+1
+SET SESSION debug="+d,enter,info,query,backup_debug";
+BACKUP DATABASE db1,db2 TO 'test.bak';
+use db2;
+checksum table staff;
+Table Checksum
+db2.staff 569030976
+checksum table tasking2;
+Table Checksum
+db2.tasking2 2742373372
+checksum table staff2;
+Table Checksum
+db2.staff2 0
+insert into staff2 select * from staff;
+INSERT INTO staff SELECT * FROM staff;
+UPDATE staff SET sex='N' where sex='M';
+DELETE FROM staff WHERE first_name='Edward';
+update tasking2 set hours_worked=12 where hours_worked<11;
+checksum table staff;
+Table Checksum
+db2.staff 2375145344
+checksum table tasking2;
+Table Checksum
+db2.tasking2 778095994
+checksum table staff2;
+Table Checksum
+db2.staff2 569030976
+SELECT release_lock("data_prepare");
+release_lock("data_prepare")
+1
Backup Summary
- header = 52 bytes
- meta-data = 807 bytes
- data = 639 bytes
+ header = 80 bytes
+ meta-data = 1474 bytes
+ data = 159341 bytes
--------------
- total 1498 bytes
+ total 160895 bytes
+use db2;
+CHECK TABLE staff EXTENDED;
+Table Op Msg_type Msg_text
+db2.staff check status OK
+CHECK TABLE tasking2 EXTENDED;
+Table Op Msg_type Msg_text
+db2.tasking2 check status OK
+CHECK TABLE staff2 EXTENDED;
+Table Op Msg_type Msg_text
+db2.staff2 check status OK
DROP DATABASE db1;
DROP DATABASE db2;
USE mysql;
-RESTORE FROM 'test.ba';
+RESTORE FROM 'test.bak';
Restore Summary
- header = 52 bytes
- meta-data = 807 bytes
- data = 639 bytes
+ header = 80 bytes
+ meta-data = 1474 bytes
+ data = 159341 bytes
--------------
- total 1498 bytes
+ total 160895 bytes
USE db1;
SHOW TABLES;
Tables_in_db1
@@ -93,28 +169,64 @@ USE db2;
SHOW TABLES;
Tables_in_db2
staff
+staff2
tasking
-SELECT * FROM staff;
-id first_name mid_name last_name sex salary mgr_id
-333445555 John Q Smith M 30000 333444444
-123763153 William E Walters M 25000 123654321
-333444444 Alicia F St.Cruz F 25000 NULL
-921312388 Goy X Hong F 40000 123654321
-800122337 Rajesh G Kardakarna M 38000 333445555
-820123637 Monty C Smythe M 38000 333445555
-830132335 Richard E Jones M 38000 333445555
-333445665 Edward E Engles M 25000 333445555
-123654321 Beware D Borg F 55000 333444444
-123456789 Wilma N Maxima F 43000 333445555
-SHOW CREATE TABLE tasking;
+tasking2
+SHOW CREATE TABLE staff;
Table Create Table
-tasking CREATE TABLE `tasking` (
+staff CREATE TABLE `staff` (
+ `id` char(9) DEFAULT NULL,
+ `first_name` char(20) DEFAULT NULL,
+ `mid_name` char(20) DEFAULT NULL,
+ `last_name` char(30) DEFAULT NULL,
+ `sex` char(1) DEFAULT NULL,
+ `salary` int(11) DEFAULT NULL,
+ `mgr_id` char(9) DEFAULT NULL,
+ KEY `mid_name` (`mid_name`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+checksum table staff;
+Table Checksum
+db2.staff 2375145344
+CHECK TABLE staff EXTENDED;
+Table Op Msg_type Msg_text
+db2.staff check status OK
+SHOW CREATE TABLE tasking2;
+Table Create Table
+tasking2 CREATE TABLE `tasking2` (
`id` char(9) DEFAULT NULL,
`project_number` char(9) DEFAULT NULL,
- `hours_worked` double(10,2) DEFAULT NULL
-) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1
+ `hours_worked` double(10,2) DEFAULT NULL,
+ KEY `id` (`id`),
+ KEY `project_number` (`project_number`),
+ KEY `hours_worked` (`hours_worked`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
+checksum table tasking2;
+Table Checksum
+db2.tasking2 778095994
+CHECK TABLE tasking2 EXTENDED;
+Table Op Msg_type Msg_text
+db2.tasking2 check status OK
+SHOW CREATE TABLE staff2;
+Table Create Table
+staff2 CREATE TABLE `staff2` (
+ `id` char(9) DEFAULT NULL,
+ `first_name` char(20) DEFAULT NULL,
+ `mid_name` char(20) DEFAULT NULL,
+ `last_name` char(30) DEFAULT NULL,
+ `sex` char(1) DEFAULT NULL,
+ `salary` int(11) DEFAULT NULL,
+ `mgr_id` char(9) DEFAULT NULL,
+ KEY `mid_name` (`mid_name`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+checksum table staff2;
+Table Checksum
+db2.staff2 569030976
+CHECK TABLE staff2 EXTENDED;
+Table Op Msg_type Msg_text
+db2.staff2 check status OK
DROP DATABASE IF EXISTS db1;
DROP DATABASE IF EXISTS db2;
+SET SESSION debug="-d,enter,info,query,backup_debug";
DROP DATABASE IF EXISTS bup_default;
CREATE DATABASE bup_default;
CREATE TABLE bup_default.wide (
@@ -319,19 +431,19 @@ Chuck@linux:~> mysql -uroot -p
Enter password:
BACKUP DATABASE bup_default TO "bup_default.bak";
Backup Summary
- header = 43 bytes
+ header = 50 bytes
meta-data = 890 bytes
- data = 7368 bytes
+ data = 9698 bytes
--------------
- total 8301 bytes
+ total 10638 bytes
DROP DATABASE bup_default;
RESTORE FROM "bup_default.bak";
Restore Summary
- header = 43 bytes
+ header = 50 bytes
meta-data = 890 bytes
- data = 7368 bytes
+ data = 9698 bytes
--------------
- total 8301 bytes
+ total 10638 bytes
SELECT * FROM bup_default.t1;
a
1
diff -Nrup a/mysql-test/r/backup_commit_blocker.result
b/mysql-test/r/backup_commit_blocker.result
--- a/mysql-test/r/backup_commit_blocker.result 2007-11-27 18:23:37 +01:00
+++ b/mysql-test/r/backup_commit_blocker.result 2007-11-28 22:51:28 +01:00
@@ -1,6 +1,6 @@
DROP DATABASE IF EXISTS bup_commit_blocker;
CREATE DATABASE bup_commit_blocker;
-SET GLOBAL debug="d,backup_debug";
+SET GLOBAL debug="+d,backup_debug";
Starting Test 1
@@ -467,3 +467,4 @@ count(*)
1
con1: Cleanup
DROP DATABASE bup_commit_blocker;
+SET GLOBAL debug="-d,backup_debug";
diff -Nrup a/mysql-test/r/backup_ddl_blocker.result
b/mysql-test/r/backup_ddl_blocker.result
--- a/mysql-test/r/backup_ddl_blocker.result 2007-11-27 18:23:37 +01:00
+++ b/mysql-test/r/backup_ddl_blocker.result 2007-11-28 22:51:28 +01:00
@@ -1,4 +1,4 @@
-SET GLOBAL debug="d,backup_debug";
+SET GLOBAL debug="+d,backup_debug";
Starting Test 1 - Backup
@@ -52,11 +52,11 @@ con3: Completing DDL
con4: Completing DDL
con5: Completing DDL
Backup Summary
- header = 36 bytes
+ header = 43 bytes
meta-data = 316 bytes
- data = 162 bytes
+ data = 2326 bytes
--------------
- total 514 bytes
+ total 2685 bytes
Verifying Test 1 results for backup.
@@ -81,11 +81,11 @@ bup_ddl_blocker.t3, bup_ddl_blocker.t4;
con1: Restoring the database
RESTORE FROM "bup_ddl_blocker.bak";
Restore Summary
- header = 36 bytes
+ header = 43 bytes
meta-data = 316 bytes
- data = 162 bytes
+ data = 2326 bytes
--------------
- total 514 bytes
+ total 2685 bytes
con1: Showing columns that were backed up
con1: Table t3 should not be in restored data.
con1: Table t4 should not have new column in restored data.
@@ -127,11 +127,11 @@ INSERT INTO bup_ddl_blocker.t4 VALUES ("
DROP TABLE bup_ddl_blocker.t1, bup_ddl_blocker.t3;
BACKUP DATABASE bup_ddl_blocker to 'bup_ddl_blocker_orig.bak';
Backup Summary
- header = 29 bytes
+ header = 36 bytes
meta-data = 190 bytes
- data = 162 bytes
+ data = 2314 bytes
--------------
- total 381 bytes
+ total 2540 bytes
con6: Getting lock on DDL in progress.
SELECT get_lock("DDL_in_progress", 0);
get_lock("DDL_in_progress", 0)
@@ -161,11 +161,11 @@ con3: Completing DDL
con4: Completing DDL
con5: Completing DDL
Restore Summary
- header = 29 bytes
+ header = 36 bytes
meta-data = 190 bytes
- data = 162 bytes
+ data = 2314 bytes
--------------
- total 381 bytes
+ total 2540 bytes
Verifying Test 1 results for restore.
@@ -241,11 +241,11 @@ con5: Completing DDL
Table Op Msg_type Msg_text
bup_ddl_blocker.t4 repair status OK
Backup Summary
- header = 41 bytes
+ header = 48 bytes
meta-data = 379 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 744 bytes
+ total 2903 bytes
Verifying Test 2 results for backup.
@@ -263,11 +263,11 @@ bup_ddl_blocker.t03, bup_ddl_blocker.t4;
con1: Restoring the database
RESTORE FROM "bup_ddl_blocker.bak";
Restore Summary
- header = 41 bytes
+ header = 48 bytes
meta-data = 379 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 744 bytes
+ total 2903 bytes
con1: Showing columns that were backed up
con1: Table t01 should be in restore
con1: Table t03 should not be in restore
@@ -303,11 +303,11 @@ INSERT INTO bup_ddl_blocker.t4 VALUES ("
INSERT INTO bup_ddl_blocker.t4 VALUES ("03 Some data to test");
BACKUP DATABASE bup_ddl_blocker to 'bup_ddl_blocker_orig.bak';
Backup Summary
- header = 40 bytes
+ header = 47 bytes
meta-data = 378 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 742 bytes
+ total 2901 bytes
con6: Getting lock on DDL in progress.
SELECT get_lock("DDL_in_progress", 0);
get_lock("DDL_in_progress", 0)
@@ -341,11 +341,11 @@ con5: Completing DDL
Table Op Msg_type Msg_text
bup_ddl_blocker.t4 repair status OK
Restore Summary
- header = 40 bytes
+ header = 47 bytes
meta-data = 378 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 742 bytes
+ total 2901 bytes
Verifying Test 2 results for restore.
@@ -413,11 +413,11 @@ Table Op Msg_type Msg_text
bup_ddl_blocker.t3 optimize status OK
con5: Completing DDL
Backup Summary
- header = 36 bytes
+ header = 43 bytes
meta-data = 284 bytes
- data = 243 bytes
+ data = 1319 bytes
--------------
- total 563 bytes
+ total 1646 bytes
Verifying Test 3 results for backup.
@@ -432,11 +432,11 @@ DROP TABLE bup_ddl_blocker.t1, bup_ddl_b
con1: Restoring the database
RESTORE FROM "bup_ddl_blocker.bak";
Restore Summary
- header = 36 bytes
+ header = 43 bytes
meta-data = 284 bytes
- data = 243 bytes
+ data = 1319 bytes
--------------
- total 563 bytes
+ total 1646 bytes
con1: Showing columns that were backed up
con1: Table t2 should not be in restore
use bup_ddl_blocker;
@@ -470,11 +470,11 @@ INSERT INTO bup_ddl_blocker.t4 VALUES ("
INSERT INTO bup_ddl_blocker.t4 VALUES ("03 Some data to test");
BACKUP DATABASE bup_ddl_blocker to 'bup_ddl_blocker_orig.bak';
Backup Summary
- header = 40 bytes
+ header = 47 bytes
meta-data = 378 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 742 bytes
+ total 2901 bytes
con6: Getting lock on DDL in progress.
SELECT get_lock("DDL_in_progress", 0);
get_lock("DDL_in_progress", 0)
@@ -508,11 +508,11 @@ Table Op Msg_type Msg_text
bup_ddl_blocker.t3 optimize status OK
con5: Completing DDL
Restore Summary
- header = 40 bytes
+ header = 47 bytes
meta-data = 378 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 742 bytes
+ total 2901 bytes
Verifying Test 3 results for restore.
@@ -577,11 +577,11 @@ con3: Completing DDL
con4: Completing DDL
con5: Completing DDL
Backup Summary
- header = 81 bytes
+ header = 88 bytes
meta-data = 384 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 789 bytes
+ total 2948 bytes
Verifying Test 4 results for backup.
@@ -597,11 +597,11 @@ DROP DATABASE bup_ddl_blocker_3;
con1: Restoring the database
RESTORE FROM "bup_ddl_blocker.bak";
Restore Summary
- header = 81 bytes
+ header = 88 bytes
meta-data = 384 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 789 bytes
+ total 2948 bytes
con1: Showing databases that were backed up
con1: bup_ddl_blocker_2 and bup_ddl_blocker_3 are not present
SHOW DATABASES LIKE 'bup_ddl_blocker_%';
@@ -638,11 +638,11 @@ bup_ddl_blocker_2
bup_ddl_blocker_4
BACKUP DATABASE bup_ddl_blocker_2, bup_ddl_blocker_4 to 'bup_ddl_blocker_orig.bak';
Backup Summary
- header = 52 bytes
+ header = 59 bytes
meta-data = 192 bytes
- data = 162 bytes
+ data = 1238 bytes
--------------
- total 406 bytes
+ total 1489 bytes
con6: Getting lock on DDL in progress.
SELECT get_lock("DDL_in_progress", 0);
get_lock("DDL_in_progress", 0)
@@ -672,11 +672,11 @@ con3: Completing DDL
con4: Completing DDL
con5: Completing DDL
Restore Summary
- header = 52 bytes
+ header = 59 bytes
meta-data = 192 bytes
- data = 162 bytes
+ data = 1238 bytes
--------------
- total 406 bytes
+ total 1489 bytes
Verifying Test 4 results for restore.
@@ -740,11 +740,11 @@ con3: Completing DDL
con4: Completing DDL
con5: Completing DDL
Backup Summary
- header = 85 bytes
+ header = 92 bytes
meta-data = 478 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 887 bytes
+ total 3046 bytes
Verifying Test 5 results for backup.
@@ -773,11 +773,11 @@ DROP DATABASE bup_ddl_blocker_4;
con1: Restoring the database
RESTORE FROM "bup_ddl_blocker.bak";
Restore Summary
- header = 85 bytes
+ header = 92 bytes
meta-data = 478 bytes
- data = 324 bytes
+ data = 2476 bytes
--------------
- total 887 bytes
+ total 3046 bytes
con1: Showing databases that were backed up
con1: bup_ddl_blocker_1 has been renamed and
con1: bup_ddl_blocker_2.t1 has been truncated.
@@ -831,11 +831,11 @@ bup_ddl_blocker_4
BACKUP DATABASE bup_ddl_blocker_2, bup_ddl_blocker_4
to 'bup_ddl_blocker_orig.bak';
Backup Summary
- header = 52 bytes
+ header = 59 bytes
meta-data = 192 bytes
- data = 162 bytes
+ data = 1238 bytes
--------------
- total 406 bytes
+ total 1489 bytes
con6: Getting lock on DDL in progress.
SELECT get_lock("DDL_in_progress", 0);
get_lock("DDL_in_progress", 0)
@@ -865,11 +865,11 @@ con3: Completing DDL
con4: Completing DDL
con5: Completing DDL
Restore Summary
- header = 52 bytes
+ header = 59 bytes
meta-data = 192 bytes
- data = 162 bytes
+ data = 1238 bytes
--------------
- total 406 bytes
+ total 1489 bytes
Verifying Test 5 results for restore.
@@ -983,3 +983,4 @@ count(*)
DROP TABLE test.t2;
con1: Cleanup
DROP DATABASE bup_ddl_blocker;
+SET GLOBAL debug="-d,backup_debug";
diff -Nrup a/mysql-test/r/backup_fkey.result b/mysql-test/r/backup_fkey.result
--- a/mysql-test/r/backup_fkey.result 2007-11-21 14:44:14 +01:00
+++ b/mysql-test/r/backup_fkey.result 2007-11-28 22:51:28 +01:00
@@ -93,11 +93,11 @@ INSERT INTO backup_fkey.t1 VALUES ("07 T
Backup the data
BACKUP DATABASE backup_fkey TO 'backup_fkey.bak';
Backup Summary
- header = 21 bytes
+ header = 28 bytes
meta-data = 92 bytes
- data = 301 bytes
+ data = 1321 bytes
--------------
- total 414 bytes
+ total 1441 bytes
Turn on foreign key constraints.
SET foreign_key_checks = 1;
SHOW VARIABLES LIKE 'foreign_key_checks%';
@@ -106,11 +106,11 @@ foreign_key_checks ON
Restoring data
RESTORE FROM 'backup_fkey.bak';
Restore Summary
- header = 21 bytes
+ header = 28 bytes
meta-data = 92 bytes
- data = 301 bytes
+ data = 1321 bytes
--------------
- total 414 bytes
+ total 1441 bytes
Verify foreign_key_checks = ON
SHOW VARIABLES LIKE 'foreign_key_checks%';
Variable_name Value
@@ -123,11 +123,11 @@ foreign_key_checks OFF
Restoring data
RESTORE FROM 'backup_fkey.bak';
Restore Summary
- header = 21 bytes
+ header = 28 bytes
meta-data = 92 bytes
- data = 301 bytes
+ data = 1321 bytes
--------------
- total 414 bytes
+ total 1441 bytes
Verify foreign_key_checks = OFF
SHOW VARIABLES LIKE 'foreign_key_checks%';
Variable_name Value
diff -Nrup a/mysql-test/r/backup_myisam1.result b/mysql-test/r/backup_myisam1.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/backup_myisam1.result 2007-11-28 22:51:31 +01:00
@@ -0,0 +1,7 @@
+drop database if exists mysqltest;
+create database mysqltest;
+use mysqltest;
+CREATE TABLE t1 (a int) engine=myisam;
+BACKUP DATABASE mysqltest TO 'test.ba';
+ERROR HY000: Got error -1 'online backup impossible with --external-locking' from MyISAM
+DROP DATABASE mysqltest;
diff -Nrup a/mysql-test/r/backup_myisam2.result b/mysql-test/r/backup_myisam2.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/backup_myisam2.result 2007-11-28 22:51:31 +01:00
@@ -0,0 +1,61 @@
+drop database if exists mysqltest;
+create database mysqltest;
+use mysqltest;
+CREATE TABLE t1 (a longtext) engine=myisam;
+SELECT get_lock("data_prepare", 100);
+get_lock("data_prepare", 100)
+1
+SET SESSION debug="+d,enter,info,query,backup_debug";
+BACKUP DATABASE mysqltest TO 'test.ba';
+use mysqltest;
+insert into t1 values ("text");
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+update t1 set a=concat(a,a);
+select length(a) from t1;
+length(a)
+262144
+checksum table t1;
+Table Checksum
+mysqltest.t1 1728069308
+SELECT release_lock("data_prepare");
+release_lock("data_prepare")
+1
+Backup Summary
+ header = 26 bytes
+ meta-data = 79 bytes
+ data = 528071 bytes
+ --------------
+ total 528176 bytes
+repair table t1 quick;
+Table Op Msg_type Msg_text
+mysqltest.t1 repair status OK
+DROP DATABASE mysqltest;
+RESTORE FROM 'test.ba';
+Restore Summary
+ header = 26 bytes
+ meta-data = 79 bytes
+ data = 528071 bytes
+ --------------
+ total 528176 bytes
+select length(a) from t1;
+length(a)
+262144
+checksum table t1;
+Table Checksum
+mysqltest.t1 1728069308
+drop database mysqltest;
+SET SESSION debug="-d,enter,info,query,backup_debug";
diff -Nrup a/mysql-test/r/backup_no_engine.result b/mysql-test/r/backup_no_engine.result
--- a/mysql-test/r/backup_no_engine.result 2007-11-06 19:32:23 +01:00
+++ b/mysql-test/r/backup_no_engine.result 2007-11-28 22:51:28 +01:00
@@ -4,20 +4,20 @@ CREATE TABLE db.t1 (a int, b char(32))
ENGINE=myisam;
BACKUP DATABASE db TO "db.backup";
Backup Summary
- header = 12 bytes
+ header = 19 bytes
meta-data = 120 bytes
- data = 0 bytes
+ data = 1029 bytes
--------------
- total 132 bytes
+ total 1168 bytes
DROP DATABASE db;
CREATE DATABASE db;
RESTORE FROM "db.backup";
Restore Summary
- header = 12 bytes
+ header = 19 bytes
meta-data = 120 bytes
- data = 0 bytes
+ data = 1029 bytes
--------------
- total 132 bytes
+ total 1168 bytes
SHOW TABLES IN db;
Tables_in_db
t1
diff -Nrup a/mysql-test/r/backup_security.result b/mysql-test/r/backup_security.result
--- a/mysql-test/r/backup_security.result 2007-11-09 22:32:08 +01:00
+++ b/mysql-test/r/backup_security.result 2007-11-28 22:51:28 +01:00
@@ -19,11 +19,11 @@ GRANT SUPER ON *.* TO 'bup_with_rights'@
default: Do backup of database with default test user for later tests.
BACKUP DATABASE backup_test to 'backup_test_orig.bak';
Backup Summary
- header = 21 bytes
+ header = 28 bytes
meta-data = 92 bytes
- data = 245 bytes
+ data = 1251 bytes
--------------
- total 358 bytes
+ total 1371 bytes
default: Connect as user with no rights and attempt backup and restore.
no_rights: Attempting backup. Should fail with error 1227
BACKUP DATABASE backup_test to 'bup_no_rights.bak';
@@ -50,19 +50,19 @@ Connect as user with rights and attempt
no_rights: Attempting backup. Should succeed
BACKUP DATABASE backup_test to 'bup_with_rights.bak';
Backup Summary
- header = 21 bytes
+ header = 28 bytes
meta-data = 92 bytes
- data = 245 bytes
+ data = 1251 bytes
--------------
- total 358 bytes
+ total 1371 bytes
no_rights: Attempting restore. Should succeed
RESTORE FROM 'bup_with_rights.bak';
Restore Summary
- header = 21 bytes
+ header = 28 bytes
meta-data = 92 bytes
- data = 245 bytes
+ data = 1251 bytes
--------------
- total 358 bytes
+ total 1371 bytes
SELECT * FROM t1;
a
01 Test #1 - super privilege
@@ -75,11 +75,11 @@ a
default: Do restore to ensure it still works with default test user.
RESTORE FROM 'backup_test_orig.bak';
Restore Summary
- header = 21 bytes
+ header = 28 bytes
meta-data = 92 bytes
- data = 245 bytes
+ data = 1251 bytes
--------------
- total 358 bytes
+ total 1371 bytes
SELECT * FROM t1;
a
01 Test #1 - super privilege
diff -Nrup a/mysql-test/r/myisamlog.result b/mysql-test/r/myisamlog.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/myisamlog.result 2007-11-28 22:51:31 +01:00
@@ -0,0 +1,48 @@
+create database if not exists mysqltest;
+use mysqltest;
+drop table if exists t1;
+create table t1 (a int, b varchar(100)) engine=myisam;
+insert into t1 values(1,'life'), (2,'file');
+insert into t1 select a*5, concat("A ",b) from t1;
+update t1 set b="A knife" where a=5;
+delete from t1 where a=10;
+select * from t1;
+a b
+1 life
+2 file
+5 A knife
+truncate table t1;
+flush table t1;
+Commands Used count Errors Recover errors
+open 16 0 0
+write 4 0 0
+update 1 0 0
+delete 1 0 0
+close 8 0 0
+extra 72 0 0
+lock 48 0 0
+Total 150 0 0
+select * from t1;
+a b
+flush table t1;
+Trying to update MyISAM files according to log './var/master-data/myisam.log'
+Tables updated successfully
+
+Commands Used count Errors Recover errors
+open 17 0 0
+write 4 0 0
+update 1 0 0
+delete 1 0 0
+close 9 0 0
+extra 75 0 0
+lock 50 0 0
+Total 157 0 0
+select * from t1;
+a b
+1 life
+2 file
+5 A knife
+check table t1 extended;
+Table Op Msg_type Msg_text
+mysqltest.t1 check status OK
+drop database mysqltest;
diff -Nrup a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2007-10-13 22:12:45
+02:00
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2007-11-28 22:51:28
+01:00
@@ -400,6 +400,7 @@ insert into t2 select * from t1;
select get_lock("a",10);
get_lock("a",10)
1
+do release_lock("a");
flush logs;
select
(@a:=load_file("MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
diff -Nrup a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
--- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2007-10-13 22:12:46
+02:00
+++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2007-11-28 22:51:28
+01:00
@@ -367,6 +367,7 @@ insert into t2 select * from t1;
select get_lock("a",10);
get_lock("a",10)
1
+do release_lock("a");
flush logs;
select
(@a:=load_file("MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
diff -Nrup a/mysql-test/t/backup.test b/mysql-test/t/backup.test
--- a/mysql-test/t/backup.test 2007-11-06 19:32:25 +01:00
+++ b/mysql-test/t/backup.test 2007-11-28 22:51:28 +01:00
@@ -1,8 +1,22 @@
+# Tests is for the default, consistent snapshot and MyISAM online
+# backup drivers.
+
--source include/have_innodb.inc
+--source include/have_debug.inc
connect (backup,localhost,root,,);
connect (restore,localhost,root,,);
+# Dedicated connection for GET_LOCK(). BACKUP_BREAKPOINT, present in
+# various places like mysql_delete(), causes current lock to be
+# released, that's why GET_LOCK() and DELETE must not be made by the
+# same connection.
+connect (syncer,localhost,root,,);
+
+#
+# This test is for the default (Archive+Blackhole) and MyISAM driver.
+#
+
connection backup;
DROP DATABASE IF EXISTS db1;
@@ -27,9 +41,9 @@ CREATE TABLE `building` (
# Dumping data for table `building`
#
-LOCK TABLES `building` WRITE;
-INSERT INTO `building` VALUES
('N41','1300'),('N01','1453'),('M00','1000'),('N41','1301'),('N41','1305');
-UNLOCK TABLES;
+INSERT INTO `building` VALUES
+('N41','1300'),('N01','1453'),('M00','1000'),
+('N41','1301'),('N41','1305');
#
@@ -47,9 +61,8 @@ CREATE TABLE `directorate` (
# Dumping data for table `directorate`
#
-LOCK TABLES `directorate` WRITE;
-INSERT INTO `directorate` VALUES ('N41','Development','333445555'),('N01','Human
Resources','123654321'),('M00','Management','333444444');
-UNLOCK TABLES;
+INSERT INTO `directorate` VALUES ('N41','Development','333445555'),
+('N01','Human Resources','123654321'),('M00','Management','333444444');
USE db2;
@@ -65,16 +78,37 @@ CREATE TABLE `staff` (
`last_name` char(30),
`sex` char(1),
`salary` int(11),
- `mgr_id` char(9)
+ `mgr_id` char(9),
+ index(mid_name)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
#
# Dumping data for table `staff`
#
-LOCK TABLES `staff` WRITE;
-INSERT INTO `staff` VALUES
('333445555','John','Q','Smith','M',30000,'333444444'),('123763153','William','E','Walters','M',25000,'123654321'),('333444444','Alicia','F','St.Cruz','F',25000,NULL),('921312388','Goy','X','Hong','F',40000,'123654321'),('800122337','Rajesh','G','Kardakarna','M',38000,'333445555'),('820123637','Monty','C','Smythe','M',38000,'333445555'),('830132335','Richard','E','Jones','M',38000,'333445555'),('333445665','Edward','E','Engles','M',25000,'333445555'),('123654321','Beware','D','Borg','F',55000,'333444444'),('123456789','Wilma','N','Maxima','F',43000,'333445555');
-UNLOCK TABLES;
+INSERT INTO `staff` VALUES
+('333445555','John','Q','Smith','M',30000,'333444444'),
+('123763153','William','E','Walters','M',25000,'123654321'),
+('333444444','Alicia','F','St.Cruz','F',25000,NULL),
+('921312388','Goy','X','Hong','F',40000,'123654321'),
+('800122337','Rajesh','G','Kardakarna','M',38000,'333445555'),
+('820123637','Monty','C','Smythe','M',38000,'333445555'),
+('830132335','Richard','E','Jones','M',38000,'333445555'),
+('333445665','Edward','E','Engles','M',25000,'333445555'),
+('123654321','Beware','D','Borg','F',55000,'333444444'),
+('123456789','Wilma','N','Maxima','F',43000,'333445555');
+# grow the table a bit
+insert into staff select * from staff;
+insert into staff select * from staff;
+insert into staff select * from staff;
+insert into staff select * from staff;
+insert into staff select * from staff;
+
+# and make an empty table (INSERT SELECT works differently if the
+# destination table is empty: it disables indices (see
+# ha_myisam::start_bulk_insert()) and thus repairs them, which backup
+# has to tolerate.
+create table staff2 like staff;
#
# Table structure for table `tasking`
@@ -91,24 +125,100 @@ CREATE TABLE `tasking` (
# Dumping data for table `tasking`
#
-LOCK TABLES `tasking` WRITE;
-INSERT INTO `tasking` VALUES
('333445555','405',23),('123763153','405',33.5),('921312388','601',44),('800122337','300',13),('820123637','300',9.5),('830132335','401',8.5),('333445555','300',11),('921312388','500',13),('800122337','300',44),('820123637','401',500.5),('830132335','400',12),('333445665','600',300.25),('123654321','607',444.75),('123456789','300',1000);
-UNLOCK TABLES;
+INSERT INTO `tasking` VALUES ('333445555','405',23),
+('123763153','405',33.5),('921312388','601',44),('800122337','300',13),
+('820123637','300',9.5),('830132335','401',8.5),('333445555','300',11),
+('921312388','500',13),('800122337','300',44),('820123637','401',500.5),
+('830132335','400',12),('333445665','600',300.25),('123654321','607',444.75),
+('123456789','300',1000);
+CREATE TABLE `tasking2` (
+ `id` char(9),
+ `project_number` char(9),
+ `hours_worked` double(10,2),
+ index(id), index(project_number), index(hours_worked)
+) delay_key_write=1 ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Dumping data for table `tasking2`
+--
+
+INSERT INTO `tasking2` VALUES
+('333445555','405',23),('123763153','405',33.5),
+('921312388','601',44),('800122337','300',13),('820123637','300',9.5),
+('830132335','401',8.5),('333445555','300',11),('921312388','500',13),
+('800122337','300',44),('820123637','401',500.5),('830132335','400',12),
+('333445665','600',300.25),('123654321','607',444.75),
+('123456789','300',1000);
+insert into tasking select * from tasking;
+insert into tasking select * from tasking;
+insert into tasking select * from tasking;
+insert into tasking select * from tasking;
+insert into tasking select * from tasking;
+
+connection syncer;
+# make sure we can update MyISAM tables before the backup finishes,
+# to test backup in online conditions
+SELECT get_lock("data_prepare", 100);
+
+connection backup;
+# prepare to block:
+SET SESSION debug="+d,enter,info,query,backup_debug";
+send BACKUP DATABASE db1,db2 TO 'test.bak';
+
+connection restore;
+# Must wait to know when backup has entered lock.
+let $wait_condition = SELECT state = "debug_sync_point: data_prepare"
+ FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE info LIKE "backup database %";
+--source include/wait_condition.inc
+
+# At this point, MyISAM tables are copied, but we will do a
+# modification to them before BACKUP ends. Then we will verify that
+# the backup does contain this modification.
+
+use db2;
+
+# at start of backup, tables have:
+checksum table staff;
+checksum table tasking2;
+checksum table staff2;
+
+insert into staff2 select * from staff;
+INSERT INTO staff SELECT * FROM staff;
+UPDATE staff SET sex='N' where sex='M';
+DELETE FROM staff WHERE first_name='Edward';
+update tasking2 set hours_worked=12 where hours_worked<11;
+
+# at end of backup they have:
+checksum table staff;
+checksum table tasking2;
+checksum table staff2;
+
+# let BACKUP finish now
+connection syncer;
+SELECT release_lock("data_prepare");
+
+connection backup;
+reap;
+use db2;
+# verify that backup didn't corrupt MyISAM tables
+CHECK TABLE staff EXTENDED;
+CHECK TABLE tasking2 EXTENDED;
+CHECK TABLE staff2 EXTENDED;
-BACKUP DATABASE db1,db2 TO 'test.ba';
DROP DATABASE db1;
DROP DATABASE db2;
#Disabled until SHOW commands are implemented.
-#SHOW BACKUP 'test.ba';
+#SHOW BACKUP 'test.bak';
connection restore;
USE mysql;
-RESTORE FROM 'test.ba';
+RESTORE FROM 'test.bak';
USE db1;
SHOW TABLES;
@@ -120,17 +230,28 @@ SELECT * FROM directorate;
USE db2;
SHOW TABLES;
-SELECT * FROM staff;
-SHOW CREATE TABLE tasking;
+# verify that restored MyISAM tables are ok and correspond to the
+# validity point (end of backup)
+SHOW CREATE TABLE staff;
+checksum table staff;
+CHECK TABLE staff EXTENDED;
+SHOW CREATE TABLE tasking2;
+checksum table tasking2;
+CHECK TABLE tasking2 EXTENDED;
+SHOW CREATE TABLE staff2;
+checksum table staff2;
+CHECK TABLE staff2 EXTENDED;
DROP DATABASE IF EXISTS db1;
DROP DATABASE IF EXISTS db2;
+remove_file $MYSQLTEST_VARDIR/master-data/test.bak;
#
-# This test is for the default and snapshot online backup drivers
+# This test is for the MyISAM and snapshot online backup drivers
#
-
+
connection backup;
+SET SESSION debug="-d,enter,info,query,backup_debug";
--disable_warnings
DROP DATABASE IF EXISTS bup_default;
@@ -282,5 +403,4 @@ SELECT COUNT(*) FROM bup_default.wide;
DROP DATABASE IF EXISTS bup_default;
--enable_warnings
-#--exec rm $MYSQLTEST_VARDIR/master-data/bup_default.bak
-
+remove_file $MYSQLTEST_VARDIR/master-data/bup_default.bak;
diff -Nrup a/mysql-test/t/backup_commit_blocker.test
b/mysql-test/t/backup_commit_blocker.test
--- a/mysql-test/t/backup_commit_blocker.test 2007-11-27 18:23:37 +01:00
+++ b/mysql-test/t/backup_commit_blocker.test 2007-11-28 22:51:28 +01:00
@@ -53,6 +53,9 @@ CREATE DATABASE bup_commit_blocker;
# con7 - used for setting up non-transactions about to start
#
+# Setup the server to use the backup breakpoints
+SET GLOBAL debug="+d,backup_debug";
+
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connect (con3,localhost,root,,);
@@ -63,9 +66,6 @@ connect (con7,localhost,root,,);
connection con1;
-# Setup the server to use the backup breakpoints
-SET GLOBAL debug="d,backup_debug";
-
#
# Test 1 - transactional statements only
#
@@ -339,6 +339,8 @@ INSERT INTO bup_commit_blocker.t5 VALUES
#SELECT * FROM bup_commit_blocker.t4;
SELECT * FROM bup_commit_blocker.t5;
+connection con5;
+
# Set the breakpoint for the commit blocker.
--echo con5: Getting lock on commit blocker.
SELECT get_lock("backup_commit_blocker", 0);
@@ -752,7 +754,5 @@ SELECT count(*) FROM bup_commit_blocker.
--echo con1: Cleanup
DROP DATABASE bup_commit_blocker;
-
+SET GLOBAL debug="-d,backup_debug";
remove_file $MYSQLTEST_VARDIR/master-data/bup_commit_blocker.bak;
-
-
diff -Nrup a/mysql-test/t/backup_ddl_blocker.test b/mysql-test/t/backup_ddl_blocker.test
--- a/mysql-test/t/backup_ddl_blocker.test 2007-11-27 18:23:37 +01:00
+++ b/mysql-test/t/backup_ddl_blocker.test 2007-11-28 22:51:28 +01:00
@@ -52,6 +52,9 @@
# con6 used for setting and releasing breakpoints
#
+# Setup the server to use the backup breakpoints
+SET GLOBAL debug="+d,backup_debug";
+
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connect (con3,localhost,root,,);
@@ -61,9 +64,6 @@ connect (con6,localhost,root,,);
connection con1;
-# Setup the server to use the backup breakpoints
-SET GLOBAL debug="d,backup_debug";
-
#
# Backup test sequence diagram (not UML)
#
@@ -1730,10 +1730,6 @@ DROP TABLE test.t2;
--echo con1: Cleanup
DROP DATABASE bup_ddl_blocker;
-
+SET GLOBAL debug="-d,backup_debug";
remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker_orig.bak;
remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak;
-
-
-
-
diff -Nrup a/mysql-test/t/backup_myisam1-master.opt
b/mysql-test/t/backup_myisam1-master.opt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/backup_myisam1-master.opt 2007-11-28 22:51:31 +01:00
@@ -0,0 +1 @@
+--external-locking=1
diff -Nrup a/mysql-test/t/backup_myisam1.test b/mysql-test/t/backup_myisam1.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/backup_myisam1.test 2007-11-28 22:51:31 +01:00
@@ -0,0 +1,14 @@
+# Test specific of MyISAM's online backup:
+# see if --external-locking=1 causes backup to fail as expected
+
+--disable_warnings
+drop database if exists mysqltest;
+--enable_warnings
+create database mysqltest;
+use mysqltest;
+CREATE TABLE t1 (a int) engine=myisam;
+
+--error ER_GET_ERRMSG
+BACKUP DATABASE mysqltest TO 'test.ba';
+
+DROP DATABASE mysqltest;
diff -Nrup a/mysql-test/t/backup_myisam2.test b/mysql-test/t/backup_myisam2.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/backup_myisam2.test 2007-11-28 22:51:31 +01:00
@@ -0,0 +1,66 @@
+# Tests specific of MyISAM's online backup
+
+--source include/have_debug.inc
+
+connect (backup,localhost,root,,);
+connect (restore,localhost,root,,);
+
+# Dedicated connection for GET_LOCK(). BACKUP_BREAKPOINT, present in
+# various places like mysql_delete(), causes current lock to be
+# released, that's why GET_LOCK() and DELETE must not be made by the
+# same connection.
+connect (syncer,localhost,root,,);
+
+connection backup;
+
+--disable_warnings
+drop database if exists mysqltest;
+--enable_warnings
+create database mysqltest;
+use mysqltest;
+
+# test of long records (causing records' length to be stored in a long
+# format in the backup log)
+
+CREATE TABLE t1 (a longtext) engine=myisam;
+
+connection syncer;
+# make sure we can update MyISAM tables before the backup finishes,
+# to test backup in online conditions
+SELECT get_lock("data_prepare", 100);
+
+connection backup;
+# prepare to block:
+SET SESSION debug="+d,enter,info,query,backup_debug";
+send BACKUP DATABASE mysqltest TO 'test.ba';
+
+connection restore;
+# Must wait to know when backup has entered lock.
+let $wait_condition = SELECT state = "debug_sync_point: data_prepare"
+ FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE info LIKE "backup database %";
+--source include/wait_condition.inc
+
+use mysqltest;
+insert into t1 values ("text");
+let $1=16;
+while ($1)
+{
+ update t1 set a=concat(a,a);
+ dec $1;
+}
+select length(a) from t1;
+checksum table t1;
+
+connection syncer;
+SELECT release_lock("data_prepare");
+
+connection backup;
+reap;
+repair table t1 quick;
+DROP DATABASE mysqltest;
+RESTORE FROM 'test.ba';
+select length(a) from t1;
+checksum table t1;
+drop database mysqltest;
+SET SESSION debug="-d,enter,info,query,backup_debug";
diff -Nrup a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test
--- a/mysql-test/t/key_cache.test 2007-05-31 20:04:51 +02:00
+++ b/mysql-test/t/key_cache.test 2007-11-28 22:51:28 +01:00
@@ -71,7 +71,7 @@ show status like 'key_blocks_used';
# Following results differs on 64 and 32 bit systems because of different
# pointer sizes, which takes up different amount of space in key cache
---replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED
1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED
+--replace_result 1805 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED
1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED
show status like 'key_blocks_unused';
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
@@ -84,7 +84,7 @@ update t1 set p=2 where p=1;
update t2 set i=2 where i=1;
show status like 'key_blocks_used';
---replace_result 1808 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
1814 KEY_BLOCKS_UNUSED 1820 KEY_BLOCKS_UNUSED
+--replace_result 1801 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
1814 KEY_BLOCKS_UNUSED 1820 KEY_BLOCKS_UNUSED
show status like 'key_blocks_unused';
cache index t1 key (`primary`) in keycache1;
@@ -146,7 +146,7 @@ cache index t1,t2 in default;
drop table t1,t2,t3;
show status like 'key_blocks_used';
---replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED
1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED
+--replace_result 1805 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED
1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED
show status like 'key_blocks_unused';
diff -Nrup a/mysql-test/t/myisamlog-master.opt b/mysql-test/t/myisamlog-master.opt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/myisamlog-master.opt 2007-11-28 22:51:31 +01:00
@@ -0,0 +1 @@
+--log-isam
diff -Nrup a/mysql-test/t/myisamlog.test b/mysql-test/t/myisamlog.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/myisamlog.test 2007-11-28 22:51:31 +01:00
@@ -0,0 +1,37 @@
+# Test of MyISAM logical logging and the myisamlog utility:
+# see if they can repopulate a table.
+
+disable_warnings;
+create database if not exists mysqltest;
+use mysqltest;
+drop table if exists t1;
+enable_warnings;
+# CREATE generates no entry in the logical log
+create table t1 (a int, b varchar(100)) engine=myisam;
+
+# we put some data into the table
+insert into t1 values(1,'life'), (2,'file');
+insert into t1 select a*5, concat("A ",b) from t1;
+update t1 set b="A knife" where a=5;
+delete from t1 where a=10;
+select * from t1;
+
+# wipe it out (TRUNCATE generates no entry in the logical log)
+truncate table t1;
+# close the table (as we are going to change it out of the server process)
+flush table t1;
+
+# look at log
+exec $MYISAMLOG $MYSQLTEST_VARDIR/master-data/myisam.log ;
+# should not have changed the table
+select * from t1;
+flush table t1;
+
+# apply log to empty table
+--replace_result $MYSQL_TEST_DIR .
+exec $MYISAMLOG -F $MYSQLTEST_VARDIR/master-data -u
$MYSQLTEST_VARDIR/master-data/myisam.log ;
+
+# reopen the table and verify that content is back
+select * from t1;
+check table t1 extended;
+drop database mysqltest;
diff -Nrup a/mysys/mf_iocache.c b/mysys/mf_iocache.c
--- a/mysys/mf_iocache.c 2007-05-10 11:59:25 +02:00
+++ b/mysys/mf_iocache.c 2007-11-28 22:51:29 +01:00
@@ -129,6 +129,9 @@ init_functions(IO_CACHE* info)
}
+/* FUNCTIONS TO SET UP OR RESET A CACHE */
+
+
/*
Initialize an IO_CACHE object
@@ -166,7 +169,7 @@ int init_io_cache(IO_CACHE *info, File f
info->file= file;
info->type= TYPE_NOT_SET; /* Don't set it until mutex are created */
info->pos_in_file= seek_offset;
- info->pre_close = info->pre_read = info->post_read = 0;
+ info->pre_close= info->pre_read= info->post_read= info->post_write= NULL;
info->arg = 0;
info->alloced_buffer = 0;
info->buffer=0;
@@ -278,7 +281,7 @@ int init_io_cache(IO_CACHE *info, File f
/* End_of_file may be changed by user later */
info->end_of_file= end_of_file;
- info->error=0;
+ info->error= info->hard_write_error_in_the_past= 0;
info->type= type;
init_functions(info);
#ifdef HAVE_AIOWAIT
@@ -405,7 +408,7 @@ my_bool reinit_io_cache(IO_CACHE *info,
}
}
info->type=type;
- info->error=0;
+ info->error= info->hard_write_error_in_the_past= 0;
init_functions(info);
#ifdef HAVE_AIOWAIT
@@ -422,6 +425,8 @@ my_bool reinit_io_cache(IO_CACHE *info,
} /* reinit_io_cache */
+/* FUNCTIONS TO DO READS FROM THE CACHE */
+
/*
Read buffered.
@@ -1471,14 +1476,19 @@ int _my_b_get(IO_CACHE *info)
uchar buff;
IO_CACHE_CALLBACK pre_read,post_read;
if ((pre_read = info->pre_read))
- (*pre_read)(info);
+ (*pre_read)(info, NULL, 0, 0);
if ((*(info)->read_function)(info,&buff,1))
return my_b_EOF;
if ((post_read = info->post_read))
- (*post_read)(info);
+ (*post_read)(info, NULL, 0, 0);
return (int) (uchar) buff;
}
+/* FUNCTIONS TO DO WRITES TO THE CACHE */
+
+#define set_hard_write_error(CACHE) \
+ ((CACHE)->error= (CACHE)->hard_write_error_in_the_past= -1)
+
/*
Write a byte buffer to IO_CACHE and flush to disk
if IO_CACHE is full.
@@ -1496,7 +1506,7 @@ int _my_b_write(register IO_CACHE *info,
if (info->pos_in_file+info->buffer_length > info->end_of_file)
{
my_errno=errno=EFBIG;
- return info->error = -1;
+ return set_hard_write_error(info);
}
rest_length= (size_t) (info->write_end - info->write_pos);
@@ -1520,13 +1530,15 @@ int _my_b_write(register IO_CACHE *info,
*/
if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)))
{
- info->error= -1;
+ set_hard_write_error(info);
return (1);
}
info->seek_not_done=0;
}
if (my_write(info->file, Buffer, length, info->myflags | MY_NABP))
- return info->error= -1;
+ return set_hard_write_error(info);
+ if (info->post_write)
+ (*(info->post_write))(info, Buffer, length, info->pos_in_file);
#ifdef THREAD
/*
@@ -1571,7 +1583,7 @@ int my_b_append(register IO_CACHE *info,
*/
DBUG_ASSERT(!info->share);
#endif
-
+ DBUG_ASSERT(info->post_write == NULL); /* unsupported */
lock_append_buffer(info);
rest_length= (size_t) (info->write_end - info->write_pos);
if (Count <= rest_length)
@@ -1591,7 +1603,7 @@ int my_b_append(register IO_CACHE *info,
if (my_write(info->file,Buffer, length, info->myflags | MY_NABP))
{
unlock_append_buffer(info);
- return info->error= -1;
+ return set_hard_write_error(info);
}
Count-=length;
Buffer+=length;
@@ -1644,12 +1656,21 @@ int my_block_write(register IO_CACHE *in
{
/* Of no overlap, write everything without buffering */
if (pos + Count <= info->pos_in_file)
- return my_pwrite(info->file, Buffer, Count, pos,
- info->myflags | MY_NABP);
+ {
+ int ret= my_pwrite(info->file, Buffer, Count, pos,
+ info->myflags | MY_NABP);
+ if (unlikely(ret))
+ set_hard_write_error(info);
+ if (info->post_write)
+ (*(info->post_write))(info, Buffer, Count, pos);
+ return ret;
+ }
/* Write the part of the block that is before buffer */
length= (uint) (info->pos_in_file - pos);
if (my_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP))
- info->error= error= -1;
+ error= set_hard_write_error(info);
+ if (info->post_write)
+ (*(info->post_write))(info, Buffer, length, pos);
Buffer+=length;
pos+= length;
Count-= length;
@@ -1710,7 +1731,7 @@ int my_b_flush_io_cache(IO_CACHE *info,
if (info->file == -1)
{
if (real_open_cached_file(info))
- DBUG_RETURN((info->error= -1));
+ DBUG_RETURN(set_hard_write_error(info));
}
LOCK_APPEND_BUFFER;
@@ -1738,29 +1759,42 @@ int my_b_flush_io_cache(IO_CACHE *info,
MY_FILEPOS_ERROR)
{
UNLOCK_APPEND_BUFFER;
- DBUG_RETURN((info->error= -1));
+ DBUG_RETURN(set_hard_write_error(info));
}
if (!append_cache)
info->seek_not_done=0;
}
- if (!append_cache)
- info->pos_in_file+=length;
info->write_end= (info->write_buffer+info->buffer_length-
((pos_in_file+length) & (IO_SIZE-1)));
if (my_write(info->file,info->write_buffer,length,
info->myflags | MY_NABP))
- info->error= -1;
+ set_hard_write_error(info);
else
info->error= 0;
if (!append_cache)
{
+ /*
+ This post_write is really POST-write; callers depend on this! So
+ always call it after writing to the file, not before.
+ */
+ if (info->post_write)
+ (*(info->post_write))(info, info->write_buffer,
+ length, info->pos_in_file);
+ /*
+ The addition below will make the info->pos_in_file be the end of
+ written block; whereas the value we needed in post_write is the
+ value before the addition. That's why we called post_write before
+ this.
+ */
+ info->pos_in_file+=length;
set_if_bigger(info->end_of_file,(pos_in_file+length));
}
else
{
info->end_of_file+=(info->write_pos-info->append_read_pos);
DBUG_ASSERT(info->end_of_file == my_tell(info->file,MYF(0)));
+ DBUG_ASSERT(info->post_write == NULL); /* unsupported */
}
info->append_read_pos=info->write_pos=info->write_buffer;
@@ -1814,7 +1848,7 @@ int end_io_cache(IO_CACHE *info)
if ((pre_close=info->pre_close))
{
- (*pre_close)(info);
+ (*pre_close)(info, NULL, 0, 0);
info->pre_close= 0;
}
if (info->alloced_buffer)
diff -Nrup a/mysys/mf_keycache.c b/mysys/mf_keycache.c
--- a/mysys/mf_keycache.c 2007-10-19 12:41:16 +02:00
+++ b/mysys/mf_keycache.c 2007-11-28 22:51:29 +01:00
@@ -13,7 +13,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/*
+/**
+ @file
These functions handle keyblock cacheing for ISAM and MyISAM tables.
One cache can handle many files.
@@ -36,7 +37,9 @@
blocks_unused is the sum of never used blocks in the pool and of currently
free blocks. blocks_used is the number of blocks fetched from the pool and
as such gives the maximum number of in-use blocks at any time.
+*/
+/*
Key Cache Locking
=================
@@ -212,6 +215,7 @@ struct st_block_link
uint hits_left; /* number of hits left until promotion */
ulonglong last_hit_time; /* timestamp of the last hit */
KEYCACHE_CONDVAR *condvar; /* condition variable for 'no readers' event */
+ void *post_write_arg; /**< post_write's argument*/
};
KEY_CACHE dflt_key_cache_var;
@@ -400,6 +404,7 @@ int init_key_cache(KEY_CACHE *keycache,
keycache->in_init= 0;
pthread_mutex_init(&keycache->cache_lock, MY_MUTEX_INIT_FAST);
keycache->resize_queue.last_thread= NULL;
+ keycache->post_write= NULL;
}
keycache->key_cache_mem_size= use_mem;
@@ -762,12 +767,37 @@ void end_key_cache(KEY_CACHE *keycache,
{
pthread_mutex_destroy(&keycache->cache_lock);
keycache->key_cache_inited= keycache->can_be_used= 0;
+ keycache->post_write= NULL;
KEYCACHE_DEBUG_CLOSE;
}
DBUG_VOID_RETURN;
} /* end_key_cache */