mirror of
https://github.com/MariaDB/server.git
synced 2025-12-06 05:42:06 +03:00
merged
trnman_get_state/trnman_set_state renamed to trnman_get/set_flags TRN::state - to TRN::flags accordingly
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
set global max_allowed_packet=400000000;
|
||||||
set storage_engine=maria;
|
set storage_engine=maria;
|
||||||
affected rows: 0
|
affected rows: 0
|
||||||
set global maria_log_file_size=4294967295;
|
set global maria_log_file_size=4294967295;
|
||||||
@@ -61,8 +62,6 @@ count(*)
|
|||||||
affected rows: 1
|
affected rows: 1
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
affected rows: 0
|
affected rows: 0
|
||||||
set @@max_allowed_packet=400000000;
|
|
||||||
affected rows: 0
|
|
||||||
create table t1 (a int, b longtext);
|
create table t1 (a int, b longtext);
|
||||||
affected rows: 0
|
affected rows: 0
|
||||||
insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321");
|
insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321");
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ create database mysqltest;
|
|||||||
use mysqltest;
|
use mysqltest;
|
||||||
* TEST of recovery with blobs
|
* TEST of recovery with blobs
|
||||||
* shut down mysqld, removed logs, restarted it
|
* shut down mysqld, removed logs, restarted it
|
||||||
set @@max_allowed_packet=32000000;
|
|
||||||
create table t1 (a int, b longtext) engine=maria table_checksum=1;
|
create table t1 (a int, b longtext) engine=maria table_checksum=1;
|
||||||
* copied t1 for feeding_recovery
|
* copied t1 for feeding_recovery
|
||||||
insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321");
|
insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321");
|
||||||
|
|||||||
@@ -25,5 +25,43 @@ Checksum-check
|
|||||||
ok
|
ok
|
||||||
use mysqltest;
|
use mysqltest;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
* TEST of logging of BLOBs
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`blob` blob,
|
||||||
|
`blob_key` blob
|
||||||
|
) ENGINE=maria ROW_FORMAT=page
|
||||||
|
;
|
||||||
|
* copied t1 for feeding_recovery
|
||||||
|
* compared t1 to old version
|
||||||
|
set global maria_checkpoint_interval=0;
|
||||||
|
INSERT INTO `t1` VALUES (NULL,repeat('A',5198));
|
||||||
|
INSERT INTO `t1` VALUES (NULL,repeat('B',65535));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('K',5198),repeat('L',2325));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('C',65535),NULL);
|
||||||
|
INSERT INTO `t1` VALUES (NULL,repeat('D',65535));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('E',65535),repeat('F',16111));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('G',65535),repeat('H',65535));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('I',5198),repeat('J',65535));
|
||||||
|
check table t1 extended;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
mysqltest.t1 check status OK
|
||||||
|
flush table t1;
|
||||||
|
* copied t1 for comparison
|
||||||
|
* compared t1 to old version
|
||||||
|
SET SESSION debug="+d,maria_flush_whole_log,maria_crash";
|
||||||
|
* crashing mysqld intentionally
|
||||||
|
set global maria_checkpoint_interval=1;
|
||||||
|
ERROR HY000: Lost connection to MySQL server during query
|
||||||
|
* copied t1 back for feeding_recovery
|
||||||
|
* recovery happens
|
||||||
|
check table t1 extended;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
mysqltest.t1 check status OK
|
||||||
|
* testing that checksum after recovery is as expected
|
||||||
|
Checksum-check
|
||||||
|
ok
|
||||||
|
* compared t1 to old version
|
||||||
|
use mysqltest;
|
||||||
|
drop table t1;
|
||||||
drop database mysqltest_for_comparison;
|
drop database mysqltest_for_comparison;
|
||||||
drop database mysqltest;
|
drop database mysqltest;
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
--source include/have_maria.inc
|
--source include/have_maria.inc
|
||||||
--source include/big_test.inc
|
--source include/big_test.inc
|
||||||
|
|
||||||
|
set global max_allowed_packet=400000000;
|
||||||
|
# need new session to use setting above
|
||||||
|
connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
|
||||||
|
connection root;
|
||||||
|
|
||||||
enable_info;
|
enable_info;
|
||||||
set storage_engine=maria;
|
set storage_engine=maria;
|
||||||
set global maria_log_file_size=4294967295;
|
set global maria_log_file_size=4294967295;
|
||||||
@@ -38,7 +43,6 @@ drop table t1, t2;
|
|||||||
# Test creating a really big blob (up to 16M)
|
# Test creating a really big blob (up to 16M)
|
||||||
#
|
#
|
||||||
|
|
||||||
set @@max_allowed_packet=400000000;
|
|
||||||
create table t1 (a int, b longtext);
|
create table t1 (a int, b longtext);
|
||||||
insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321");
|
insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321");
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
--skip-stack-trace --skip-core-file
|
--skip-stack-trace --skip-core-file --max_allowed_packet=32000000
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ use mysqltest;
|
|||||||
|
|
||||||
--echo * TEST of recovery with blobs
|
--echo * TEST of recovery with blobs
|
||||||
-- source include/maria_empty_logs.inc
|
-- source include/maria_empty_logs.inc
|
||||||
set @@max_allowed_packet=32000000;
|
|
||||||
create table t1 (a int, b longtext) engine=maria table_checksum=1;
|
create table t1 (a int, b longtext) engine=maria table_checksum=1;
|
||||||
let $mms_tables=1;
|
let $mms_tables=1;
|
||||||
-- source include/maria_make_snapshot_for_feeding_recovery.inc
|
-- source include/maria_make_snapshot_for_feeding_recovery.inc
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
--skip-stack-trace --skip-core-file --maria-log-dir-path=../tmp
|
--skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ let $mvr_restore_old_snapshot=0;
|
|||||||
# UNDO phase prevents physical comparison, normally,
|
# UNDO phase prevents physical comparison, normally,
|
||||||
# so we'll only use checksums to compare.
|
# so we'll only use checksums to compare.
|
||||||
let $mms_compare_physically=0;
|
let $mms_compare_physically=0;
|
||||||
let $mvr_crash_statement= set global maria_checkpoint_interval=1;
|
|
||||||
create table t1(a int primary key) engine=maria;
|
create table t1(a int primary key) engine=maria;
|
||||||
insert into t1 values(1);
|
insert into t1 values(1);
|
||||||
-- source include/maria_make_snapshot_for_comparison.inc
|
-- source include/maria_make_snapshot_for_comparison.inc
|
||||||
@@ -65,6 +64,30 @@ drop table t1;
|
|||||||
# before checkpoint happens, test should still pass (though it won't
|
# before checkpoint happens, test should still pass (though it won't
|
||||||
# reproduce the conditions of the bug).
|
# reproduce the conditions of the bug).
|
||||||
|
|
||||||
|
# Test for BUG#41493 Maria: two recovery failures (wrong logging of BLOB pages)
|
||||||
|
--echo * TEST of logging of BLOBs
|
||||||
|
let $mvr_restore_old_snapshot=1;
|
||||||
|
let $mms_compare_physically=1;
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`blob` blob,
|
||||||
|
`blob_key` blob
|
||||||
|
) ENGINE=maria ROW_FORMAT=page
|
||||||
|
;
|
||||||
|
-- source include/maria_make_snapshot_for_feeding_recovery.inc
|
||||||
|
set global maria_checkpoint_interval=0; # no checkpoints
|
||||||
|
INSERT INTO `t1` VALUES (NULL,repeat('A',5198));
|
||||||
|
INSERT INTO `t1` VALUES (NULL,repeat('B',65535));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('K',5198),repeat('L',2325));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('C',65535),NULL);
|
||||||
|
INSERT INTO `t1` VALUES (NULL,repeat('D',65535));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('E',65535),repeat('F',16111));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('G',65535),repeat('H',65535));
|
||||||
|
INSERT INTO `t1` VALUES (repeat('I',5198),repeat('J',65535));
|
||||||
|
check table t1 extended;
|
||||||
|
-- source include/maria_make_snapshot_for_comparison.inc
|
||||||
|
-- source include/maria_verify_recovery.inc
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# clean up everything
|
# clean up everything
|
||||||
let $mms_purpose=comparison;
|
let $mms_purpose=comparison;
|
||||||
eval drop database mysqltest_for_$mms_purpose;
|
eval drop database mysqltest_for_$mms_purpose;
|
||||||
|
|||||||
@@ -3493,6 +3493,12 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
MYSQL_LOCK_IGNORE_FLUSH, ¬_used)) ||
|
MYSQL_LOCK_IGNORE_FLUSH, ¬_used)) ||
|
||||||
hooks->postlock(&table, 1))
|
hooks->postlock(&table, 1))
|
||||||
{
|
{
|
||||||
|
/* purecov: begin tested */
|
||||||
|
/*
|
||||||
|
This can happen in innodb when you get a deadlock when using same table
|
||||||
|
in insert and select
|
||||||
|
*/
|
||||||
|
my_error(ER_CANT_LOCK, MYF(0), my_errno);
|
||||||
if (*lock)
|
if (*lock)
|
||||||
{
|
{
|
||||||
mysql_unlock_tables(thd, *lock);
|
mysql_unlock_tables(thd, *lock);
|
||||||
@@ -3502,6 +3508,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
if (!create_info->table_existed)
|
if (!create_info->table_existed)
|
||||||
drop_open_table(thd, table, create_table->db, create_table->table_name);
|
drop_open_table(thd, table, create_table->db, create_table->table_name);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
/* purecov: end */
|
||||||
}
|
}
|
||||||
DBUG_RETURN(table);
|
DBUG_RETURN(table);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2264,6 +2264,9 @@ int ha_maria::extra_opt(enum ha_extra_function operation, ulong cache_size)
|
|||||||
|
|
||||||
int ha_maria::delete_all_rows()
|
int ha_maria::delete_all_rows()
|
||||||
{
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
(void) translog_log_debug_info(file->trn, LOGREC_DEBUG_INFO_QUERY,
|
||||||
|
(uchar*) thd->query, thd->query_length);
|
||||||
if (file->s->now_transactional &&
|
if (file->s->now_transactional &&
|
||||||
((table->in_use->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
|
((table->in_use->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
|
||||||
table->in_use->locked_tables))
|
table->in_use->locked_tables))
|
||||||
@@ -2280,6 +2283,9 @@ int ha_maria::delete_all_rows()
|
|||||||
|
|
||||||
int ha_maria::delete_table(const char *name)
|
int ha_maria::delete_table(const char *name)
|
||||||
{
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
(void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
|
||||||
|
(uchar*) thd->query, thd->query_length);
|
||||||
return maria_delete_table(name);
|
return maria_delete_table(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2353,6 +2359,16 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
|||||||
DBUG_PRINT("info", ("Disabling logging for table"));
|
DBUG_PRINT("info", ("Disabling logging for table"));
|
||||||
_ma_tmp_disable_logging_for_table(file, TRUE);
|
_ma_tmp_disable_logging_for_table(file, TRUE);
|
||||||
}
|
}
|
||||||
|
#ifdef EXTRA_DEBUG
|
||||||
|
if (lock_type == F_WRLCK &&
|
||||||
|
! (trnman_get_flags(trn) & TRN_STATE_INFO_LOGGED))
|
||||||
|
{
|
||||||
|
trnman_set_flags(trn, trnman_get_flags(trn) | TRN_STATE_INFO_LOGGED |
|
||||||
|
TRN_STATE_TABLES_CAN_CHANGE);
|
||||||
|
(void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
|
||||||
|
(uchar*) thd->query, thd->query_length);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2377,9 +2393,10 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
|||||||
external lock of the table
|
external lock of the table
|
||||||
*/
|
*/
|
||||||
file->state= &file->s->state.state;
|
file->state= &file->s->state.state;
|
||||||
if (trn && trnman_has_locked_tables(trn))
|
if (trn)
|
||||||
{
|
{
|
||||||
if (!trnman_decrement_locked_tables(trn))
|
if (trnman_has_locked_tables(trn) &&
|
||||||
|
!trnman_decrement_locked_tables(trn))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
OK should not have been sent to client yet (ACID).
|
OK should not have been sent to client yet (ACID).
|
||||||
@@ -2402,6 +2419,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
trnman_set_flags(trn, trnman_get_flags(trn) & ~ TRN_STATE_INFO_LOGGED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* if transactional table */
|
} /* if transactional table */
|
||||||
@@ -2436,6 +2454,16 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
|
|||||||
call to start_stmt().
|
call to start_stmt().
|
||||||
*/
|
*/
|
||||||
trnman_new_statement(trn);
|
trnman_new_statement(trn);
|
||||||
|
|
||||||
|
#ifdef EXTRA_DEBUG
|
||||||
|
if (!(trnman_get_flags(trn) & TRN_STATE_INFO_LOGGED) &&
|
||||||
|
trnman_get_flags(trn) & TRN_STATE_TABLES_CAN_CHANGE)
|
||||||
|
{
|
||||||
|
trnman_set_flags(trn, trnman_get_flags(trn) | TRN_STATE_INFO_LOGGED);
|
||||||
|
(void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
|
||||||
|
(uchar*) thd->query, thd->query_length);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2648,6 +2676,7 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||||||
TABLE_SHARE *share= table_arg->s;
|
TABLE_SHARE *share= table_arg->s;
|
||||||
uint options= share->db_options_in_use;
|
uint options= share->db_options_in_use;
|
||||||
enum data_file_type row_type;
|
enum data_file_type row_type;
|
||||||
|
THD *thd= current_thd;
|
||||||
DBUG_ENTER("ha_maria::create");
|
DBUG_ENTER("ha_maria::create");
|
||||||
|
|
||||||
for (i= 0; i < share->keys; i++)
|
for (i= 0; i < share->keys; i++)
|
||||||
@@ -2712,6 +2741,9 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||||||
ha_create_info->page_checksum == HA_CHOICE_YES)
|
ha_create_info->page_checksum == HA_CHOICE_YES)
|
||||||
create_flags|= HA_CREATE_PAGE_CHECKSUM;
|
create_flags|= HA_CREATE_PAGE_CHECKSUM;
|
||||||
|
|
||||||
|
(void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
|
||||||
|
(uchar*) thd->query, thd->query_length);
|
||||||
|
|
||||||
/* TODO: Check that the following fn_format is really needed */
|
/* TODO: Check that the following fn_format is really needed */
|
||||||
error=
|
error=
|
||||||
maria_create(fn_format(buff, name, "", "",
|
maria_create(fn_format(buff, name, "", "",
|
||||||
@@ -2728,6 +2760,9 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||||||
|
|
||||||
int ha_maria::rename_table(const char *from, const char *to)
|
int ha_maria::rename_table(const char *from, const char *to)
|
||||||
{
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
(void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
|
||||||
|
(uchar*) thd->query, thd->query_length);
|
||||||
return maria_rename(from, to);
|
return maria_rename(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2872,6 +2907,8 @@ static int maria_commit(handlerton *hton __attribute__ ((unused)),
|
|||||||
TRN *trn= THD_TRN;
|
TRN *trn= THD_TRN;
|
||||||
DBUG_ENTER("maria_commit");
|
DBUG_ENTER("maria_commit");
|
||||||
trnman_reset_locked_tables(trn, 0);
|
trnman_reset_locked_tables(trn, 0);
|
||||||
|
trnman_set_flags(trn, trnman_get_flags(trn) & ~TRN_STATE_INFO_LOGGED);
|
||||||
|
|
||||||
/* statement or transaction ? */
|
/* statement or transaction ? */
|
||||||
if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && !all)
|
if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && !all)
|
||||||
DBUG_RETURN(0); // end of statement
|
DBUG_RETURN(0); // end of statement
|
||||||
|
|||||||
@@ -3146,8 +3146,8 @@ static my_bool write_block_record(MARIA_HA *info,
|
|||||||
|
|
||||||
log_pos= store_page_range(log_pos, tmp_block, block_size,
|
log_pos= store_page_range(log_pos, tmp_block, block_size,
|
||||||
blob_length, &extents);
|
blob_length, &extents);
|
||||||
tmp_block+= tmp_block->sub_blocks;
|
|
||||||
}
|
}
|
||||||
|
tmp_block+= tmp_block->sub_blocks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6182,6 +6182,7 @@ err:
|
|||||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||||
LSN_IMPOSSIBLE, 0, FALSE);
|
LSN_IMPOSSIBLE, 0, FALSE);
|
||||||
_ma_mark_file_crashed(share);
|
_ma_mark_file_crashed(share);
|
||||||
|
DBUG_ASSERT(0); /* catch recovery errors early */
|
||||||
DBUG_RETURN((my_errno= error));
|
DBUG_RETURN((my_errno= error));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6280,6 +6281,7 @@ err:
|
|||||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||||
LSN_IMPOSSIBLE, 0, FALSE);
|
LSN_IMPOSSIBLE, 0, FALSE);
|
||||||
_ma_mark_file_crashed(share);
|
_ma_mark_file_crashed(share);
|
||||||
|
DBUG_ASSERT(0);
|
||||||
DBUG_RETURN((my_errno= error));
|
DBUG_RETURN((my_errno= error));
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6337,6 +6339,7 @@ uint _ma_apply_redo_free_blocks(MARIA_HA *info,
|
|||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
_ma_mark_file_crashed(share);
|
_ma_mark_file_crashed(share);
|
||||||
|
DBUG_ASSERT(0);
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6420,6 +6423,7 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
_ma_mark_file_crashed(share);
|
_ma_mark_file_crashed(share);
|
||||||
|
DBUG_ASSERT(0);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6431,6 +6435,10 @@ err:
|
|||||||
@parma lsn LSN to put on pages
|
@parma lsn LSN to put on pages
|
||||||
@param header Header (with FILEID)
|
@param header Header (with FILEID)
|
||||||
@param redo_lsn REDO record's LSN
|
@param redo_lsn REDO record's LSN
|
||||||
|
@param[out] number_of_blobs Number of blobs found in log record
|
||||||
|
@param[out] number_of_ranges Number of ranges found
|
||||||
|
@param[out] first_page First page touched
|
||||||
|
@param[out] last_page Last page touched
|
||||||
|
|
||||||
@note Write full pages (full head & blob pages)
|
@note Write full pages (full head & blob pages)
|
||||||
|
|
||||||
@@ -6441,13 +6449,18 @@ err:
|
|||||||
|
|
||||||
uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
|
uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
|
||||||
LSN lsn, const uchar *header,
|
LSN lsn, const uchar *header,
|
||||||
LSN redo_lsn)
|
LSN redo_lsn,
|
||||||
|
uint * const number_of_blobs,
|
||||||
|
uint * const number_of_ranges,
|
||||||
|
pgcache_page_no_t * const first_page,
|
||||||
|
pgcache_page_no_t * const last_page)
|
||||||
{
|
{
|
||||||
MARIA_SHARE *share= info->s;
|
MARIA_SHARE *share= info->s;
|
||||||
const uchar *data;
|
const uchar *data;
|
||||||
uint data_size= FULL_PAGE_SIZE(share->block_size);
|
uint data_size= FULL_PAGE_SIZE(share->block_size);
|
||||||
uint blob_count, ranges;
|
uint blob_count, ranges;
|
||||||
uint16 sid;
|
uint16 sid;
|
||||||
|
pgcache_page_no_t first_page2= ULONGLONG_MAX, last_page2= 0;
|
||||||
DBUG_ENTER("_ma_apply_redo_insert_row_blobs");
|
DBUG_ENTER("_ma_apply_redo_insert_row_blobs");
|
||||||
|
|
||||||
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
|
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
|
||||||
@@ -6455,9 +6468,9 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
|
|||||||
|
|
||||||
sid= fileid_korr(header);
|
sid= fileid_korr(header);
|
||||||
header+= FILEID_STORE_SIZE;
|
header+= FILEID_STORE_SIZE;
|
||||||
ranges= pagerange_korr(header);
|
*number_of_ranges= ranges= pagerange_korr(header);
|
||||||
header+= PAGERANGE_STORE_SIZE;
|
header+= PAGERANGE_STORE_SIZE;
|
||||||
blob_count= pagerange_korr(header);
|
*number_of_blobs= blob_count= pagerange_korr(header);
|
||||||
header+= PAGERANGE_STORE_SIZE;
|
header+= PAGERANGE_STORE_SIZE;
|
||||||
DBUG_ASSERT(ranges >= blob_count);
|
DBUG_ASSERT(ranges >= blob_count);
|
||||||
|
|
||||||
@@ -6495,6 +6508,8 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
|
|||||||
enum pagecache_page_pin unpin_method;
|
enum pagecache_page_pin unpin_method;
|
||||||
uint length;
|
uint length;
|
||||||
|
|
||||||
|
set_if_smaller(first_page2, page);
|
||||||
|
set_if_bigger(last_page2, page);
|
||||||
if (_ma_redo_not_needed_for_page(sid, redo_lsn, page, FALSE))
|
if (_ma_redo_not_needed_for_page(sid, redo_lsn, page, FALSE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -6545,15 +6560,22 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
uchar found_page_type= (buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK);
|
||||||
|
#endif
|
||||||
if (lsn_korr(buff) >= lsn)
|
if (lsn_korr(buff) >= lsn)
|
||||||
{
|
{
|
||||||
/* Already applied */
|
/* Already applied */
|
||||||
|
DBUG_PRINT("info", ("already applied %llu >= %llu",
|
||||||
|
lsn_korr(buff), lsn));
|
||||||
pagecache_unlock_by_link(share->pagecache, page_link.link,
|
pagecache_unlock_by_link(share->pagecache, page_link.link,
|
||||||
PAGECACHE_LOCK_WRITE_UNLOCK,
|
PAGECACHE_LOCK_WRITE_UNLOCK,
|
||||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||||
LSN_IMPOSSIBLE, 0, FALSE);
|
LSN_IMPOSSIBLE, 0, FALSE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
DBUG_ASSERT((found_page_type == (uchar) BLOB_PAGE) ||
|
||||||
|
(found_page_type == (uchar) UNALLOCATED_PAGE));
|
||||||
}
|
}
|
||||||
unlock_method= PAGECACHE_LOCK_WRITE_UNLOCK;
|
unlock_method= PAGECACHE_LOCK_WRITE_UNLOCK;
|
||||||
unpin_method= PAGECACHE_UNPIN;
|
unpin_method= PAGECACHE_UNPIN;
|
||||||
@@ -6595,10 +6617,13 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*first_page= first_page2;
|
||||||
|
*last_page= last_page2;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
_ma_mark_file_crashed(share);
|
_ma_mark_file_crashed(share);
|
||||||
|
DBUG_ASSERT(0);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -236,7 +236,11 @@ uint _ma_apply_redo_free_blocks(MARIA_HA *info, LSN lsn,
|
|||||||
uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
|
uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||||
const uchar *header);
|
const uchar *header);
|
||||||
uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, LSN lsn,
|
uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, LSN lsn,
|
||||||
const uchar *header, LSN redo_lsn);
|
const uchar *header, LSN redo_lsn,
|
||||||
|
uint * const number_of_blobs,
|
||||||
|
uint * const number_of_ranges,
|
||||||
|
pgcache_page_no_t * const first_page,
|
||||||
|
pgcache_page_no_t * const last_page);
|
||||||
my_bool _ma_apply_redo_bitmap_new_page(MARIA_HA *info, LSN lsn,
|
my_bool _ma_apply_redo_bitmap_new_page(MARIA_HA *info, LSN lsn,
|
||||||
const uchar *header);
|
const uchar *header);
|
||||||
my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
|
my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
|
||||||
|
|||||||
@@ -652,7 +652,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
/* There are only 16 bits for the total header length. */
|
/* There are only 16 bits for the total header length. */
|
||||||
if (info_length > 65535)
|
if (info_length > 65535)
|
||||||
{
|
{
|
||||||
my_printf_error(0, "Maria table '%s' has too many columns and/or "
|
my_printf_error(HA_WRONG_CREATE_OPTION,
|
||||||
|
"Maria table '%s' has too many columns and/or "
|
||||||
"indexes and/or unique constraints.",
|
"indexes and/or unique constraints.",
|
||||||
MYF(0), name + dirname_length(name));
|
MYF(0), name + dirname_length(name));
|
||||||
my_errno= HA_WRONG_CREATE_OPTION;
|
my_errno= HA_WRONG_CREATE_OPTION;
|
||||||
|
|||||||
@@ -685,6 +685,10 @@ static LOG_DESC INIT_LOGREC_IMPORTED_TABLE=
|
|||||||
{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0,
|
{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0,
|
||||||
"imported_table", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
|
"imported_table", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
|
||||||
|
|
||||||
|
static LOG_DESC INIT_LOGREC_DEBUG_INFO=
|
||||||
|
{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0,
|
||||||
|
"info", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
|
||||||
|
|
||||||
const myf log_write_flags= MY_WME | MY_NABP | MY_WAIT_IF_FULL;
|
const myf log_write_flags= MY_WME | MY_NABP | MY_WAIT_IF_FULL;
|
||||||
|
|
||||||
void translog_table_init()
|
void translog_table_init()
|
||||||
@@ -774,6 +778,9 @@ void translog_table_init()
|
|||||||
INIT_LOGREC_REDO_BITMAP_NEW_PAGE;
|
INIT_LOGREC_REDO_BITMAP_NEW_PAGE;
|
||||||
log_record_type_descriptor[LOGREC_IMPORTED_TABLE]=
|
log_record_type_descriptor[LOGREC_IMPORTED_TABLE]=
|
||||||
INIT_LOGREC_IMPORTED_TABLE;
|
INIT_LOGREC_IMPORTED_TABLE;
|
||||||
|
log_record_type_descriptor[LOGREC_DEBUG_INFO]=
|
||||||
|
INIT_LOGREC_DEBUG_INFO;
|
||||||
|
|
||||||
for (i= LOGREC_FIRST_FREE; i < LOGREC_NUMBER_OF_TYPES; i++)
|
for (i= LOGREC_FIRST_FREE; i < LOGREC_NUMBER_OF_TYPES; i++)
|
||||||
log_record_type_descriptor[i].rclass= LOGRECTYPE_NOT_ALLOWED;
|
log_record_type_descriptor[i].rclass= LOGRECTYPE_NOT_ALLOWED;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
@@ -8299,6 +8306,46 @@ void translog_set_file_size(uint32 size)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write debug information to log if we EXTRA_DEBUG is enabled
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool translog_log_debug_info(TRN *trn __attribute__((unused)),
|
||||||
|
enum translog_debug_info_type type
|
||||||
|
__attribute__((unused)),
|
||||||
|
uchar *info __attribute__((unused)),
|
||||||
|
size_t length __attribute__((unused)))
|
||||||
|
{
|
||||||
|
#ifdef EXTRA_DEBUG
|
||||||
|
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
|
||||||
|
uchar debug_type;
|
||||||
|
LSN lsn;
|
||||||
|
|
||||||
|
if (!trn)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We can't log the current transaction because we don't have
|
||||||
|
an active transaction. Use a temporary transaction object instead
|
||||||
|
*/
|
||||||
|
trn= &dummy_transaction_object;
|
||||||
|
}
|
||||||
|
debug_type= (uchar) type;
|
||||||
|
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= &debug_type;
|
||||||
|
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= 1;
|
||||||
|
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= info;
|
||||||
|
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length;
|
||||||
|
return translog_write_record(&lsn, LOGREC_DEBUG_INFO,
|
||||||
|
trn, NULL,
|
||||||
|
(translog_size_t) (1+ length),
|
||||||
|
sizeof(log_array)/sizeof(log_array[0]),
|
||||||
|
log_array, NULL, NULL);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MARIA_DUMP_LOG
|
#ifdef MARIA_DUMP_LOG
|
||||||
#include <my_getopt.h>
|
#include <my_getopt.h>
|
||||||
extern void translog_example_table_init();
|
extern void translog_example_table_init();
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ enum translog_record_type
|
|||||||
LOGREC_UNDO_BULK_INSERT,
|
LOGREC_UNDO_BULK_INSERT,
|
||||||
LOGREC_REDO_BITMAP_NEW_PAGE,
|
LOGREC_REDO_BITMAP_NEW_PAGE,
|
||||||
LOGREC_IMPORTED_TABLE,
|
LOGREC_IMPORTED_TABLE,
|
||||||
|
LOGREC_DEBUG_INFO,
|
||||||
LOGREC_FIRST_FREE,
|
LOGREC_FIRST_FREE,
|
||||||
LOGREC_RESERVED_FUTURE_EXTENSION= 63
|
LOGREC_RESERVED_FUTURE_EXTENSION= 63
|
||||||
};
|
};
|
||||||
@@ -167,6 +168,12 @@ enum en_key_op
|
|||||||
KEY_OP_COMPACT_PAGE /* Compact key page */
|
KEY_OP_COMPACT_PAGE /* Compact key page */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum translog_debug_info_type
|
||||||
|
{
|
||||||
|
LOGREC_DEBUG_INFO_QUERY
|
||||||
|
};
|
||||||
|
|
||||||
/* Size of log file; One log file is restricted to 4G */
|
/* Size of log file; One log file is restricted to 4G */
|
||||||
typedef uint32 translog_size_t;
|
typedef uint32 translog_size_t;
|
||||||
|
|
||||||
@@ -323,6 +330,9 @@ translog_assign_id_to_share_from_recovery(struct st_maria_share *share,
|
|||||||
extern my_bool translog_walk_filenames(const char *directory,
|
extern my_bool translog_walk_filenames(const char *directory,
|
||||||
my_bool (*callback)(const char *,
|
my_bool (*callback)(const char *,
|
||||||
const char *));
|
const char *));
|
||||||
|
extern my_bool translog_log_debug_info(TRN *trn,
|
||||||
|
enum translog_debug_info_type type,
|
||||||
|
uchar *info, size_t length);
|
||||||
|
|
||||||
enum enum_translog_status
|
enum enum_translog_status
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ prototype_redo_exec_hook(UNDO_KEY_DELETE);
|
|||||||
prototype_redo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT);
|
prototype_redo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT);
|
||||||
prototype_redo_exec_hook(COMMIT);
|
prototype_redo_exec_hook(COMMIT);
|
||||||
prototype_redo_exec_hook(CLR_END);
|
prototype_redo_exec_hook(CLR_END);
|
||||||
|
prototype_redo_exec_hook(DEBUG_INFO);
|
||||||
prototype_undo_exec_hook(UNDO_ROW_INSERT);
|
prototype_undo_exec_hook(UNDO_ROW_INSERT);
|
||||||
prototype_undo_exec_hook(UNDO_ROW_DELETE);
|
prototype_undo_exec_hook(UNDO_ROW_DELETE);
|
||||||
prototype_undo_exec_hook(UNDO_ROW_UPDATE);
|
prototype_undo_exec_hook(UNDO_ROW_UPDATE);
|
||||||
@@ -488,6 +489,11 @@ static void display_record_position(const LOG_DESC *log_desc,
|
|||||||
number ? "" : " ", number, LSN_IN_PARTS(rec->lsn),
|
number ? "" : " ", number, LSN_IN_PARTS(rec->lsn),
|
||||||
rec->short_trid, log_desc->name, rec->type,
|
rec->short_trid, log_desc->name, rec->type,
|
||||||
(ulong)rec->record_length);
|
(ulong)rec->record_length);
|
||||||
|
if (rec->type == LOGREC_DEBUG_INFO)
|
||||||
|
{
|
||||||
|
/* Print some extra information */
|
||||||
|
(*log_desc->record_execute_in_redo_phase)(rec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1412,6 +1418,9 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_BLOBS)
|
|||||||
{
|
{
|
||||||
int error= 1;
|
int error= 1;
|
||||||
uchar *buff;
|
uchar *buff;
|
||||||
|
uint number_of_blobs, number_of_ranges;
|
||||||
|
pgcache_page_no_t first_page, last_page;
|
||||||
|
char llbuf1[22], llbuf2[22];
|
||||||
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
|
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
|
||||||
if (info == NULL)
|
if (info == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1426,11 +1435,19 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_BLOBS)
|
|||||||
}
|
}
|
||||||
buff= log_record_buffer.str;
|
buff= log_record_buffer.str;
|
||||||
if (_ma_apply_redo_insert_row_blobs(info, current_group_end_lsn,
|
if (_ma_apply_redo_insert_row_blobs(info, current_group_end_lsn,
|
||||||
buff, rec->lsn))
|
buff, rec->lsn, &number_of_blobs,
|
||||||
|
&number_of_ranges,
|
||||||
|
&first_page, &last_page))
|
||||||
goto end;
|
goto end;
|
||||||
|
llstr(first_page, llbuf1);
|
||||||
|
llstr(last_page, llbuf2);
|
||||||
|
tprint(tracef, " %u blobs %u ranges, first page %s last %s",
|
||||||
|
number_of_blobs, number_of_ranges, llbuf1, llbuf2);
|
||||||
|
|
||||||
error= 0;
|
error= 0;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
tprint(tracef, " \n");
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1992,6 +2009,37 @@ prototype_redo_exec_hook(CLR_END)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Hock to print debug information (like MySQL query)
|
||||||
|
*/
|
||||||
|
|
||||||
|
prototype_redo_exec_hook(DEBUG_INFO)
|
||||||
|
{
|
||||||
|
uchar *data;
|
||||||
|
enum translog_debug_info_type debug_info;
|
||||||
|
|
||||||
|
enlarge_buffer(rec);
|
||||||
|
if (log_record_buffer.str == NULL ||
|
||||||
|
translog_read_record(rec->lsn, 0, rec->record_length,
|
||||||
|
log_record_buffer.str, NULL) !=
|
||||||
|
rec->record_length)
|
||||||
|
{
|
||||||
|
eprint(tracef, "Failed to read record debug record");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
debug_info= (enum translog_debug_info_type) log_record_buffer.str[0];
|
||||||
|
data= log_record_buffer.str + 1;
|
||||||
|
switch (debug_info) {
|
||||||
|
case LOGREC_DEBUG_INFO_QUERY:
|
||||||
|
tprint(tracef, "Query: %s\n", (char*) data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
In some cases we have to skip execution of an UNDO record during the UNDO
|
In some cases we have to skip execution of an UNDO record during the UNDO
|
||||||
phase.
|
phase.
|
||||||
@@ -2350,6 +2398,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply)
|
|||||||
install_redo_exec_hook(UNDO_BULK_INSERT);
|
install_redo_exec_hook(UNDO_BULK_INSERT);
|
||||||
install_undo_exec_hook(UNDO_BULK_INSERT);
|
install_undo_exec_hook(UNDO_BULK_INSERT);
|
||||||
install_redo_exec_hook(IMPORTED_TABLE);
|
install_redo_exec_hook(IMPORTED_TABLE);
|
||||||
|
install_redo_exec_hook(DEBUG_INFO);
|
||||||
|
|
||||||
current_group_end_lsn= LSN_IMPOSSIBLE;
|
current_group_end_lsn= LSN_IMPOSSIBLE;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
@@ -3392,6 +3441,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MARIA_EXTERNAL_LOCKING
|
#ifdef MARIA_EXTERNAL_LOCKING
|
||||||
#error Marias Checkpoint and Recovery are really not ready for it
|
#error Marias Checkpoint and Recovery are really not ready for it
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -89,6 +89,18 @@ void trnman_reset_locked_tables(TRN *trn, uint locked_tables)
|
|||||||
trn->locked_tables= locked_tables;
|
trn->locked_tables= locked_tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EXTRA_DEBUG
|
||||||
|
uint16 trnman_get_flags(TRN *trn)
|
||||||
|
{
|
||||||
|
return trn->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void trnman_set_flags(TRN *trn, uint16 flags)
|
||||||
|
{
|
||||||
|
trn->flags= flags;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Wake up threads waiting for this transaction */
|
/** Wake up threads waiting for this transaction */
|
||||||
static void wt_thd_release_self(TRN *trn)
|
static void wt_thd_release_self(TRN *trn)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ struct st_ma_transaction
|
|||||||
LSN_WITH_FLAGS first_undo_lsn;
|
LSN_WITH_FLAGS first_undo_lsn;
|
||||||
uint locked_tables;
|
uint locked_tables;
|
||||||
uint16 short_id;
|
uint16 short_id;
|
||||||
|
uint16 flags; /**< Various flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TRANSACTION_LOGGED_LONG_ID ULL(0x8000000000000000)
|
#define TRANSACTION_LOGGED_LONG_ID ULL(0x8000000000000000)
|
||||||
|
|||||||
@@ -69,5 +69,17 @@ my_bool trnman_exists_active_transactions(TrID min_id, TrID max_id,
|
|||||||
void trnman_lock();
|
void trnman_lock();
|
||||||
void trnman_unlock();
|
void trnman_unlock();
|
||||||
my_bool trman_is_inited();
|
my_bool trman_is_inited();
|
||||||
|
#ifdef EXTRA_DEBUG
|
||||||
|
uint16 trnman_get_flags(TRN *);
|
||||||
|
void trnman_set_flags(TRN *, uint16 flags);
|
||||||
|
#else
|
||||||
|
#define trnman_get_flags(A) 0
|
||||||
|
#define trnman_set_flags(A, B) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Flag bits */
|
||||||
|
#define TRN_STATE_INFO_LOGGED 1 /* Query is logged */
|
||||||
|
#define TRN_STATE_TABLES_CAN_CHANGE 2 /* Things can change during trans. */
|
||||||
|
|
||||||
C_MODE_END
|
C_MODE_END
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -496,7 +496,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
/* There are only 16 bits for the total header length. */
|
/* There are only 16 bits for the total header length. */
|
||||||
if (info_length > 65535)
|
if (info_length > 65535)
|
||||||
{
|
{
|
||||||
my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
|
my_printf_error(HA_WRONG_CREATE_OPTION,
|
||||||
|
"MyISAM table '%s' has too many columns and/or "
|
||||||
"indexes and/or unique constraints.",
|
"indexes and/or unique constraints.",
|
||||||
MYF(0), name + dirname_length(name));
|
MYF(0), name + dirname_length(name));
|
||||||
my_errno= HA_WRONG_CREATE_OPTION;
|
my_errno= HA_WRONG_CREATE_OPTION;
|
||||||
|
|||||||
Reference in New Issue
Block a user