mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
38ca9be4de
There is a race condition in InnoDB startup. A number of fil_crypt_thread are created by fil_crypt_threads_init(). These threads may call btr_scrub_complete_space() before btr_scrub_init() was called. Those too early calls would be accessing an uninitialized scrub_stat_mutex. innobase_start_or_create_for_mysql(): Invoke btr_scrub_init() before fil_crypt_threads_init(). fil_crypt_complete_rotate_space(): Only invoke btr_scrub_complete_space() if scrubbing is enabled. There is no need to update the statistics if it is not enabled.
163 lines
4.6 KiB
C
163 lines
4.6 KiB
C
// Copyright 2014 Google
|
|
|
|
#ifndef btr0scrub_h
|
|
#define btr0scrub_h
|
|
|
|
#include "univ.i"
|
|
|
|
#include "dict0dict.h"
|
|
#include "data0data.h"
|
|
#include "page0cur.h"
|
|
#include "mtr0mtr.h"
|
|
#include "btr0types.h"
|
|
|
|
/**
|
|
* enum describing page allocation status
|
|
*/
|
|
enum btr_scrub_page_allocation_status_t {
|
|
BTR_SCRUB_PAGE_FREE,
|
|
BTR_SCRUB_PAGE_ALLOCATED,
|
|
BTR_SCRUB_PAGE_ALLOCATION_UNKNOWN
|
|
};
|
|
|
|
/**
|
|
* constants returned by btr_page_needs_scrubbing & btr_scrub_recheck_page
|
|
*/
|
|
#define BTR_SCRUB_PAGE 1 /* page should be scrubbed */
|
|
#define BTR_SCRUB_SKIP_PAGE 2 /* no scrub & no action */
|
|
#define BTR_SCRUB_SKIP_PAGE_AND_CLOSE_TABLE 3 /* no scrub & close table */
|
|
#define BTR_SCRUB_SKIP_PAGE_AND_COMPLETE_SPACE 4 /* no scrub & complete space */
|
|
#define BTR_SCRUB_TURNED_OFF 5 /* we detected that scrubbing
|
|
was disabled by global
|
|
variable */
|
|
|
|
/**************************************************************//**
|
|
struct for keeping scrub statistics. */
|
|
struct btr_scrub_stat_t {
|
|
/* page reorganizations */
|
|
ulint page_reorganizations;
|
|
/* page splits */
|
|
ulint page_splits;
|
|
/* scrub failures */
|
|
ulint page_split_failures_underflow;
|
|
ulint page_split_failures_out_of_filespace;
|
|
ulint page_split_failures_missing_index;
|
|
ulint page_split_failures_unknown;
|
|
};
|
|
|
|
/**************************************************************//**
|
|
struct for thread local scrub state. */
|
|
struct btr_scrub_t {
|
|
|
|
/* current space */
|
|
ulint space;
|
|
|
|
/* is scrubbing enabled for this space */
|
|
bool scrubbing;
|
|
|
|
/* is current space compressed */
|
|
bool compressed;
|
|
|
|
dict_table_t* current_table;
|
|
dict_index_t* current_index;
|
|
/* savepoint for X_LATCH of block */
|
|
ulint savepoint;
|
|
|
|
/* statistic counters */
|
|
btr_scrub_stat_t scrub_stat;
|
|
};
|
|
|
|
/*********************************************************************
|
|
Init scrub global variables */
|
|
UNIV_INTERN
|
|
void
|
|
btr_scrub_init();
|
|
|
|
/*********************************************************************
|
|
Cleanup scrub globals */
|
|
UNIV_INTERN
|
|
void
|
|
btr_scrub_cleanup();
|
|
|
|
/***********************************************************************
|
|
Return crypt statistics */
|
|
UNIV_INTERN
|
|
void
|
|
btr_scrub_total_stat(
|
|
/*==================*/
|
|
btr_scrub_stat_t *stat); /*!< out: stats to update */
|
|
|
|
/**************************************************************//**
|
|
Check if a page needs scrubbing
|
|
* @return BTR_SCRUB_PAGE if page should be scrubbed
|
|
* else btr_scrub_skip_page should be called
|
|
* with this return value (and without any latches held)
|
|
*/
|
|
UNIV_INTERN
|
|
int
|
|
btr_page_needs_scrubbing(
|
|
/*=====================*/
|
|
btr_scrub_t* scrub_data, /*!< in: scrub data */
|
|
buf_block_t* block, /*!< in: block to check, latched */
|
|
btr_scrub_page_allocation_status_t allocated); /*!< in: is block
|
|
allocated, free or
|
|
unknown */
|
|
|
|
/****************************************************************
|
|
Recheck if a page needs scrubbing, and if it does load appropriate
|
|
table and index
|
|
* @return BTR_SCRUB_PAGE if page should be scrubbed
|
|
* else btr_scrub_skip_page should be called
|
|
* with this return value (and without any latches held)
|
|
*/
|
|
UNIV_INTERN
|
|
int
|
|
btr_scrub_recheck_page(
|
|
/*====================*/
|
|
btr_scrub_t* scrub_data, /*!< inut: scrub data */
|
|
buf_block_t* block, /*!< in: block */
|
|
btr_scrub_page_allocation_status_t allocated, /*!< in: is block
|
|
allocated or free */
|
|
mtr_t* mtr); /*!< in: mtr */
|
|
|
|
/****************************************************************
|
|
Perform actual scrubbing of page */
|
|
UNIV_INTERN
|
|
int
|
|
btr_scrub_page(
|
|
/*============*/
|
|
btr_scrub_t* scrub_data, /*!< in/out: scrub data */
|
|
buf_block_t* block, /*!< in: block */
|
|
btr_scrub_page_allocation_status_t allocated, /*!< in: is block
|
|
allocated or free */
|
|
mtr_t* mtr); /*!< in: mtr */
|
|
|
|
/****************************************************************
|
|
Perform cleanup needed for a page not needing scrubbing */
|
|
UNIV_INTERN
|
|
void
|
|
btr_scrub_skip_page(
|
|
/*============*/
|
|
btr_scrub_t* scrub_data, /*!< in/out: scrub data */
|
|
int needs_scrubbing); /*!< in: return value from
|
|
btr_page_needs_scrubbing or
|
|
btr_scrub_recheck_page which encodes what kind
|
|
of cleanup is needed */
|
|
|
|
/****************************************************************
|
|
Start iterating a space
|
|
* @return true if scrubbing is turned on */
|
|
UNIV_INTERN
|
|
bool
|
|
btr_scrub_start_space(
|
|
/*===================*/
|
|
ulint space, /*!< in: space */
|
|
btr_scrub_t* scrub_data); /*!< in/out: scrub data */
|
|
|
|
/** Complete iterating a space.
|
|
@param[in,out] scrub_data scrub data */
|
|
UNIV_INTERN
|
|
void
|
|
btr_scrub_complete_space(btr_scrub_t* scrub_data);
|
|
|
|
#endif
|