mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
5ad477f6cb
Abort mysqld if Maria engine didn't start and we are using Maria for temporary tables Fixed bug that caused update of big blobs to crash Use pagecache_page_no_t as type for pages (to get rid of compiler warnings) Added cast to get rid of compiler warning Fixed wrong types of variables and arguments that caused lost information Fixed wrong DBUG_ASSERT() that caused REDO of big blobs to fail Removed some historical ifdefs that caused problem with windows compilations BUILD/SETUP.sh: Added --with-maria-tmp-tables include/maria.h: Use pagecache_page_no_t as type for pages Use my_bool as parameter for 'rep_quick' option include/my_base.h: Added comment mysql-test/r/maria-big.result: Added test that uses big blobs mysql-test/t/maria-big.test: Added test that uses big blobs sql/mysqld.cc: Abort mysqld if Maria engine didn't start and we are using Maria for temporary tables sql/sql_class.h: Don't use Maria for temporary tables if --with-maria-tmp-tables is not defined sql/sql_select.cc: Don't use Maria for temporary tables if --with-maria-tmp-tables is not defined storage/maria/ha_maria.cc: Fixed compiler warnings reported by MCC - Fixed usage of wrong types that caused data loss - Changed parameter for rep_quick to my_bool - Added safe casts Fixed indentation storage/maria/ma_bitmap.c: Use pagecache_page_no_t as type for pages Fixed compiler warnings Fixed bug that caused update of big blobs to crash storage/maria/ma_blockrec.c: Use pagecache_page_no_t as type for pages Use my_bool as parameter for 'rep_quick' option Fixed compiler warnings Fixed wrong DBUG_ASSERT() storage/maria/ma_blockrec.h: Use pagecache_page_no_t as type for pages storage/maria/ma_check.c: Fixed some wrong parameters where we didn't get all bits for test_flag Changed rep_quick to be of type my_bool Use pagecache_page_no_t as type for pages Added cast's to get rid of compiler warnings Changed type of record_pos to get rid of compiler warning storage/maria/ma_create.c: Added safe cast's to get rid of compiler warnings storage/maria/ma_dynrec.c: Fixed usage of wrong type storage/maria/ma_key.c: Fixed compiler warning storage/maria/ma_key_recover.c: Use pagecache_page_no_t as type for pages storage/maria/ma_loghandler_lsn.h: Added cast's to get rid of compiler warnings storage/maria/ma_page.c: Changed variable name from 'page' to 'pos' as it was an offset and not a page address Moved page_size inside block to get rid of compiler warning storage/maria/ma_pagecache.c: Fixed compiler warnings Replaced compile time assert with TODO storage/maria/ma_pagecache.h: Use pagecache_page_no_t as type for pages storage/maria/ma_pagecrc.c: Allow bitmap pages that is all zero storage/maria/ma_preload.c: Added cast to get rid of compiler warning storage/maria/ma_recovery.c: Changed types to get rid of compiler warnings Use bool for quick_repair to get rid of compiler warning Fixed some variables that was wrongly declared (not enough precission) Added cast to get rid of compiler warning storage/maria/ma_test2.c: Remove historical undefs storage/maria/maria_chk.c: Changed rep_quick to bool Fixed wrong parameter to maria_chk_data_link() storage/maria/maria_def.h: Use pagecache_page_no_t as type for pages storage/maria/maria_pack.c: Renamed isam -> maria storage/maria/plug.in: Added option --with-maria-tmp-tables storage/maria/trnman.c: Added cast to get rid of compiler warning storage/myisam/mi_test2.c: Remove historical undefs
359 lines
11 KiB
C
359 lines
11 KiB
C
/* TODO: copyright & Co */
|
|
|
|
#include "maria_def.h"
|
|
|
|
|
|
/**
|
|
@brief calculate crc of the page avoiding special values
|
|
|
|
@param start The value to start CRC (we use page number here)
|
|
@param data data pointer
|
|
@param length length of the data
|
|
|
|
@return crc of the page without special values
|
|
*/
|
|
|
|
static uint32 maria_page_crc(uint32 start, uchar *data, uint length)
|
|
{
|
|
uint32 crc= crc32(start, data, length);
|
|
|
|
/* we need this assert to get following comparison working */
|
|
compile_time_assert(MARIA_NO_CRC_BITMAP_PAGE ==
|
|
MARIA_NO_CRC_NORMAL_PAGE - 1 &&
|
|
MARIA_NO_CRC_NORMAL_PAGE == 0xffffffff);
|
|
if (crc >= MARIA_NO_CRC_BITMAP_PAGE)
|
|
crc= MARIA_NO_CRC_BITMAP_PAGE - 1;
|
|
|
|
return(crc);
|
|
}
|
|
|
|
/**
|
|
@brief Maria pages read callback (checks the page CRC)
|
|
|
|
@param page The page data to check
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr pointer to MARIA_SHARE
|
|
@param no_crc_val Value which means CRC absence
|
|
(MARIA_NO_CRC_NORMAL_PAGE or MARIA_NO_CRC_BITMAP_PAGE)
|
|
@param data_length length of data to calculate CRC
|
|
|
|
@retval 0 OK
|
|
@retval 1 Error
|
|
*/
|
|
|
|
static my_bool maria_page_crc_check(uchar *page,
|
|
pgcache_page_no_t page_no,
|
|
MARIA_SHARE *share,
|
|
uint32 no_crc_val,
|
|
int data_length)
|
|
{
|
|
uint32 crc= uint4korr(page + share->block_size - CRC_SIZE), new_crc;
|
|
my_bool res;
|
|
DBUG_ENTER("maria_page_crc_check");
|
|
|
|
DBUG_ASSERT((uint)data_length <= share->block_size - CRC_SIZE);
|
|
|
|
/* we need this assert to get following comparison working */
|
|
compile_time_assert(MARIA_NO_CRC_BITMAP_PAGE ==
|
|
MARIA_NO_CRC_NORMAL_PAGE - 1 &&
|
|
MARIA_NO_CRC_NORMAL_PAGE == 0xffffffff);
|
|
/*
|
|
If crc is no_crc_val then
|
|
the page has no crc, so there is nothing to check.
|
|
*/
|
|
if (crc >= MARIA_NO_CRC_BITMAP_PAGE)
|
|
{
|
|
DBUG_PRINT("info", ("No crc: %lu crc: %lu page: %lu ",
|
|
(ulong) no_crc_val, (ulong) crc, (ulong) page_no));
|
|
if (crc != no_crc_val)
|
|
{
|
|
my_errno= HA_ERR_WRONG_CRC;
|
|
DBUG_PRINT("error", ("Wrong no CRC value"));
|
|
DBUG_RETURN(1);
|
|
}
|
|
DBUG_RETURN(0);
|
|
}
|
|
new_crc= maria_page_crc(page_no & UINT_MAX32, page, data_length);
|
|
DBUG_ASSERT(new_crc != no_crc_val);
|
|
res= test(new_crc != crc);
|
|
if (res)
|
|
{
|
|
/*
|
|
Bitmap pages may be totally zero filled in some cases.
|
|
This happens when we get a crash after the pagecache has written
|
|
out a page that is on a newly created bitmap page and we get
|
|
a crash before the bitmap page is written out.
|
|
|
|
We handle this case with the following logic:
|
|
When reading, approve of bitmap pages where all bytes are zero
|
|
(This is after all a bitmap pages where no data is reserved and
|
|
the CRC will be corrected at next write)
|
|
*/
|
|
if (no_crc_val == MARIA_NO_CRC_BITMAP_PAGE &&
|
|
crc == 0 && _ma_check_if_zero(page, data_length))
|
|
{
|
|
DBUG_PRINT("warning", ("Found bitmap page that was not initialized"));
|
|
DBUG_RETURN(0);
|
|
}
|
|
|
|
DBUG_PRINT("error", ("Page: %lu crc: %lu calculated crc: %lu",
|
|
(ulong) page_no, (ulong) crc, (ulong) new_crc));
|
|
my_errno= HA_ERR_WRONG_CRC;
|
|
}
|
|
DBUG_RETURN(res);
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria pages write callback (sets the page CRC for data and index
|
|
files)
|
|
|
|
@param page The page data to set
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr Write callback data pointer (pointer to MARIA_SHARE)
|
|
|
|
@retval 0 OK
|
|
*/
|
|
|
|
my_bool maria_page_crc_set_normal(uchar *page,
|
|
pgcache_page_no_t page_no,
|
|
uchar *data_ptr)
|
|
{
|
|
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
|
|
int data_length= share->block_size - CRC_SIZE;
|
|
uint32 crc= maria_page_crc(page_no & UINT_MAX32, page, data_length);
|
|
DBUG_ENTER("maria_page_crc_set_normal");
|
|
DBUG_PRINT("info", ("Page %lu crc: %lu", (ulong) page_no, (ulong)crc));
|
|
|
|
/* crc is on the stack so it is aligned, pagecache buffer is aligned, too */
|
|
int4store_aligned(page + data_length, crc);
|
|
DBUG_RETURN(0);
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria pages write callback (sets the page CRC for keys)
|
|
|
|
@param page The page data to set
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr Write callback data pointer (pointer to MARIA_SHARE)
|
|
|
|
@retval 0 OK
|
|
*/
|
|
|
|
my_bool maria_page_crc_set_index(uchar *page,
|
|
pgcache_page_no_t page_no,
|
|
uchar *data_ptr)
|
|
{
|
|
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
|
|
int data_length= _ma_get_page_used(share, page);
|
|
uint32 crc= maria_page_crc(page_no & UINT_MAX32, page, data_length);
|
|
DBUG_ENTER("maria_page_crc_set");
|
|
DBUG_PRINT("info", ("Page %lu crc: %lu",
|
|
(ulong) page_no, (ulong) crc));
|
|
DBUG_ASSERT((uint)data_length <= share->block_size - CRC_SIZE);
|
|
/* crc is on the stack so it is aligned, pagecache buffer is aligned, too */
|
|
int4store_aligned(page + share->block_size - CRC_SIZE, crc);
|
|
DBUG_RETURN(0);
|
|
}
|
|
|
|
|
|
/* interface functions */
|
|
|
|
|
|
/**
|
|
@brief Maria pages read callback (checks the page CRC) for index/data pages
|
|
|
|
@param page The page data to check
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr Read callback data pointer (pointer to MARIA_SHARE)
|
|
|
|
@retval 0 OK
|
|
@retval 1 Error
|
|
*/
|
|
|
|
my_bool maria_page_crc_check_data(uchar *page,
|
|
pgcache_page_no_t page_no,
|
|
uchar *data_ptr)
|
|
{
|
|
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
|
|
return (maria_page_crc_check(page, page_no & UINT_MAX32, share,
|
|
MARIA_NO_CRC_NORMAL_PAGE,
|
|
share->block_size - CRC_SIZE));
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria pages read callback (checks the page CRC) for bitmap pages
|
|
|
|
@param page The page data to check
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr Read callback data pointer (pointer to MARIA_SHARE)
|
|
|
|
@retval 0 OK
|
|
@retval 1 Error
|
|
*/
|
|
|
|
my_bool maria_page_crc_check_bitmap(uchar *page,
|
|
pgcache_page_no_t page_no,
|
|
uchar *data_ptr)
|
|
{
|
|
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
|
|
return (maria_page_crc_check(page, page_no & UINT_MAX32, share,
|
|
MARIA_NO_CRC_BITMAP_PAGE,
|
|
share->block_size - CRC_SIZE));
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria pages read callback (checks the page CRC) for index pages
|
|
|
|
@param page The page data to check
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr Read callback data pointer (pointer to MARIA_SHARE)
|
|
|
|
@retval 0 OK
|
|
@retval 1 Error
|
|
*/
|
|
|
|
my_bool maria_page_crc_check_index(uchar *page,
|
|
pgcache_page_no_t page_no,
|
|
uchar *data_ptr)
|
|
{
|
|
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
|
|
uint length= _ma_get_page_used(share, page);
|
|
if (length > share->block_size - CRC_SIZE)
|
|
{
|
|
DBUG_PRINT("error", ("Wrong page length: %u", length));
|
|
return (my_errno= HA_ERR_WRONG_CRC);
|
|
}
|
|
return maria_page_crc_check(page, page_no & UINT_MAX32, share,
|
|
MARIA_NO_CRC_NORMAL_PAGE,
|
|
length);
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria pages dumme read callback for temporary tables
|
|
|
|
@retval 0 OK
|
|
@retval 1 Error
|
|
*/
|
|
|
|
my_bool maria_page_crc_check_none(uchar *page __attribute__((unused)),
|
|
pgcache_page_no_t page_no
|
|
__attribute__((unused)),
|
|
uchar *data_ptr __attribute__((unused)))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria pages write callback (sets the page filler for index/data)
|
|
|
|
@param page The page data to set
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr Write callback data pointer (pointer to MARIA_SHARE)
|
|
|
|
@retval 0 OK
|
|
*/
|
|
|
|
my_bool maria_page_filler_set_normal(uchar *page,
|
|
pgcache_page_no_t page_no
|
|
__attribute__((unused)),
|
|
uchar *data_ptr)
|
|
{
|
|
DBUG_ENTER("maria_page_filler_set_normal");
|
|
DBUG_ASSERT(page_no != 0); /* Catches some simple bugs */
|
|
int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
|
|
MARIA_NO_CRC_NORMAL_PAGE);
|
|
DBUG_RETURN(0);
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria pages write callback (sets the page filler for bitmap)
|
|
|
|
@param page The page data to set
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr Write callback data pointer (pointer to MARIA_SHARE)
|
|
|
|
@retval 0 OK
|
|
*/
|
|
|
|
my_bool maria_page_filler_set_bitmap(uchar *page,
|
|
pgcache_page_no_t page_no
|
|
__attribute__((unused)),
|
|
uchar *data_ptr)
|
|
{
|
|
DBUG_ENTER("maria_page_filler_set_bitmap");
|
|
int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
|
|
MARIA_NO_CRC_BITMAP_PAGE);
|
|
DBUG_RETURN(0);
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria pages dummy write callback for temporary tables
|
|
|
|
@retval 0 OK
|
|
*/
|
|
|
|
my_bool maria_page_filler_set_none(uchar *page __attribute__((unused)),
|
|
pgcache_page_no_t page_no
|
|
__attribute__((unused)),
|
|
uchar *data_ptr __attribute__((unused)))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Write failure callback (mark table as corrupted)
|
|
|
|
@param data_ptr Write callback data pointer (pointer to MARIA_SHARE)
|
|
*/
|
|
|
|
void maria_page_write_failure(uchar* data_ptr)
|
|
{
|
|
maria_mark_crashed_share((MARIA_SHARE *)data_ptr);
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Maria flush log log if needed
|
|
|
|
@param page The page data to set
|
|
@param page_no The page number (<offset>/<page length>)
|
|
@param data_ptr Write callback data pointer (pointer to MARIA_SHARE)
|
|
|
|
@retval 0 OK
|
|
@retval 1 error
|
|
*/
|
|
|
|
my_bool maria_flush_log_for_page(uchar *page,
|
|
pgcache_page_no_t page_no
|
|
__attribute__((unused)),
|
|
uchar *data_ptr)
|
|
{
|
|
LSN lsn;
|
|
const MARIA_SHARE *share= (MARIA_SHARE*) data_ptr;
|
|
DBUG_ENTER("maria_flush_log_for_page");
|
|
/* share is 0 here only in unittest */
|
|
DBUG_ASSERT(!share || (share->page_type == PAGECACHE_LSN_PAGE &&
|
|
share->now_transactional));
|
|
lsn= lsn_korr(page);
|
|
if (translog_flush(lsn))
|
|
DBUG_RETURN(1);
|
|
DBUG_RETURN(0);
|
|
}
|
|
|
|
|
|
my_bool maria_flush_log_for_page_none(uchar *page __attribute__((unused)),
|
|
pgcache_page_no_t page_no
|
|
__attribute__((unused)),
|
|
uchar *data_ptr __attribute__((unused)))
|
|
{
|
|
return 0;
|
|
}
|