1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-5834: Merge Kakao Defragmentation implementation to MariaDB 10.1

Merge https://github.com/kakao/mariadb-10.0 that contains Facebook's
    implementation for defragmentation

    facebook/mysql-5.6@a2d3a74
    facebook/mysql-5.6@def96c8
    facebook/mysql-5.6@9c67c5d
    facebook/mysql-5.6@921a81b
    facebook/mysql-5.6@aa519bd
    facebook/mysql-5.6@fea7d13
    facebook/mysql-5.6@09b29d3
    facebook/mysql-5.6@9284abb
    facebook/mysql-5.6@dbd623d
    facebook/mysql-5.6@aed55dc
    facebook/mysql-5.6@aad5c82

    This version does not add new SQL-syntax and new handler API function.
    Instead optimize table is mapped to defragment table if
    innodb_defragment=ON, by default the feature is off.

    Contains changes authored by Sunguck Lee (Kakao).
This commit is contained in:
Jan Lindström
2014-08-06 15:28:58 +03:00
parent e974b56438
commit 6dad23f04a
91 changed files with 5772 additions and 168 deletions

View File

@ -0,0 +1,180 @@
--source include/have_innodb.inc
--disable_warnings
DROP TABLE if exists t1;
--enable_warnings
--disable_query_log
let $innodb_defragment_n_pages_orig=`select @@innodb_defragment_n_pages`;
let $innodb_defragment_stats_accuracy_orig=`select @@innodb_defragment_stats_accuracy`;
--enable_query_log
select @@global.innodb_stats_persistent;
set global innodb_defragment_stats_accuracy = 80;
# Create table.
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), c INT, KEY second(a, b),KEY third(c)) ENGINE=INNODB;
connect (con1,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connect (con2,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connect (con3,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connect (con4,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connection default;
SET @@global.innodb_defragment_n_pages = 20;
let $data_size = 20000;
let $delete_size = 2000;
# Populate table.
let $i = $data_size;
--disable_query_log
while ($i)
{
eval
INSERT INTO t1 VALUES ($data_size + 1 - $i, REPEAT('A', 256), $i);
dec $i;
}
--enable_query_log
--echo after populate PRIMARY
select count(*) from t1;
if (`select count(*) < 30 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'PRIMARY' order by page_number;`)
{
aelect count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'PRIMARY' order by page_number;
}
--echo after populate second
select count(*) from t1 force index (second);
if (`select count(*) < 320 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'second' order by page_number;`)
{
select count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'second' order by page_number;
}
--ECHO after populate third
select count(*) from t1 force index (third);
if (`select count(*) < 20 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'third' order by page_number;`)
{
select count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'third' order by page_number;
}
# Delete some data
--disable_query_log
let $size = $delete_size;
while ($size)
{
let $j = 100 * $size;
eval delete from t1 where a between $j - 20 and $j;
dec $size;
}
--enable_query_log
select count(*) from t1;
--echo after delete PRIMAY
if (`select count(*) < 30 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'PRIMARY' order by page_number;`)
{
select count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'PRIMARY' order by page_number;
}
select count(*) from t1 force index (second);
--echo after delete second
if (`select count(*) < 300 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'second' order by page_number;`)
{
select count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'second' order by page_number;
}
select count(*) from t1 force index (third);
--echo after delete third
if (`select count(*) > 20 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'third' order by page_number;`)
{
select count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'third' order by page_number;
}
# Above delete will free some pages and insert causes page split and these could cause defrag
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
connection con1;
--send optimize table t1;
connection default;
--send INSERT INTO t1 VALUES (400000, REPEAT('A', 256),300000);
connection con2;
--send INSERT INTO t1 VALUES (500000, REPEAT('A', 256),400000);
connection con3;
--send DELETE FROM t1 where a between 1 and 100;
connection con4;
--send UPDATE t1 SET c = c + 1 where c between 2000 and 8000;
connection con1;
--disable_result_log
--reap
--enable_result_log
connection con2;
--reap
connection con3;
--reap
connection con4;
--reap
connection default;
--reap
disconnect con1;
disconnect con2;
disconnect con3;
disconnect con4;
optimize table t1;
select sleep(5);
select count(*) from t1;
--echo after optimize PRIMARY
if (`select count(*) > 62 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'PRIMARY' order by page_number;`)
{
select count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'PRIMARY' order by page_number;
}
select count(*) from t1 force index (second);
--echo after optimize second
if (`select count(*) > 340 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'second' order by page_number;`)
{
select count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'second' order by page_number;
}
select count(*) from t1 force index (third);
--echo after optimize third
if (`select count(*) > 25 from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'third' order by page_number;`)
{
select count(*) from information_schema.innodb_buffer_page where table_name like '%t1%' and index_name = 'third' order by page_number;
}
# Now pages are freed
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
drop table t1;
# reset system
--disable_query_log
EVAL SET GLOBAL innodb_defragment_n_pages = $innodb_defragment_n_pages_orig;
EVAL SET GLOBAL innodb_defragment_stats_accuracy = $innodb_defragment_stats_accuracy_orig;
--enable_query_log