$ wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-boost-8.0.28.tar.gz
$ tar xzvf mysql-boost-8.0.28.tar.gz
$ cd mysql-boost-8.0.28
$ mkdir build && cd $_
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug -DWITH_BOOST=../boost
問題の躓きポイント
するとこれである
Cannot find appropriate system libraries for WITH_SSL=system.
Make sure you have specified a supported SSL version.
Valid options are :
system (use the OS openssl library),
yes (synonym for system),
</path/to/custom/openssl/installation>
CMake Error at cmake/ssl.cmake:61 (MESSAGE):
Please install the appropriate openssl developer package.
Application-Time Periods Table は 10.4.3 からサポートされている機能で、Time Periods と呼ばれる2つの temporal column によって範囲が決定される。
このテーブルにおいて Time Periods に相当するカラムは Date and Time Data Types*1 にあるデータ型のうち TIME と YEAR を除いたものであり、データ型が同じでないといけない。
ここまでざっと書いたが、何らかの時間的な範囲を何かするテーブルということしかわからないので実例について。まずは公式ドキュメントにあるやつをそのまま見ていく。
Application Time Periods は次の様に宣言することができる。*2
CREATETABLE t1(
name VARCHAR(50),
date_1 DATE,
date_2 DATE,
PERIOD FOR date_period(date_1, date_2));
name カラムは特に今関係無い。重要なのは PERIOD FOR *(date_1, date_2) の部分。これがまさに前述の Time Periods というやつ。
余談だが date_period(date_1, date_2) という風に Time Periods を宣言した場合、それぞれのカラムに入る値は date_1 < date_2 となる必要がある。
MariaDB [test]> insert into t1(name, date_1, date_2) values ('e', '2022-01-01', '2021-01-01');
ERROR 4025 (23000): CONSTRAINT `date_period` failed for `test`.`t1`
MariaDB [test]> insert into t1(name, date_1, date_2) values ('e', '2022-01-01', '2022-01-01');
ERROR 4025 (23000): CONSTRAINT `date_period` failed for `test`.`t1`
DELETE
次に Time Periods に基づいて DELETE を飛ばしてみる。
MariaDB [test]> DELETE FROM t1
-> FOR PORTION OF date_period
-> FROM '2001-01-01' TO '2018-01-01';
Query OK, 3 rows affected (0.008 sec)
MariaDB [test]> SELECT * FROM t1 ORDER BY name;
+------+------------+------------+
| name | date_1 | date_2 |
+------+------------+------------+
| a | 1999-01-01 | 2000-01-01 |
| b | 1999-01-01 | 2001-01-01 |
| b | 2018-01-01 | 2018-12-12 |
| c | 1999-01-01 | 2001-01-01 |
| d | 2018-01-01 | 2019-01-01 |
+------+------------+------------+
5 rows in set (0.001 sec)
すると name = b の行が何故か2つになり、date_1, date_2 の値も変わっている。 name = c, name = d の列は増えてはないが date_1, date_2 の値が変わっている。
大体予想はつくが何が起こったかを図にするとこうなる。
DELETE FOR PORTION OF
DELETE FOR PORTION OF は指定された Time Periods に基づいてその範囲を含むレコードの Time Periods を縮小・分割する。公式ドキュメントの例にはなかったが、DELETE で指定された Time Periods に収まりきる Time Periods を持つレコードは削除される。
MariaDB [test]> INSERT INTO t1(name, date_1, date_2) values('e', '2002-01-01', '2007-01-01');
Query OK, 1 row affected (0.007 sec)
MariaDB [test]> DELETE FROM t1 FOR PORTION OF date_period FROM '2001-01-01' TO '2018-01-01';
Query OK, 1 row affected (0.007 sec)
MariaDB [test]> SELECT * FROM t1 ORDER BY name;
+------+------------+------------+
| name | date_1 | date_2 |
+------+------------+------------+
| a | 1999-01-01 | 2000-01-01 |
| b | 1999-01-01 | 2001-01-01 |
| b | 2018-01-01 | 2018-12-12 |
| c | 1999-01-01 | 2001-01-01 |
| d | 2018-01-01 | 2019-01-01 |
+------+------------+------------+
5 rows in set (0.001 sec)
MariaDB [test]> UPDATE t1 FOR PORTION OF date_period
-> FROM '2000-01-01' TO '2018-01-01'
-> SET name = CONCAT(name,'_original');
Query OK, 3 rows affected (0.009 sec)
Rows matched: 3 Changed: 3 Inserted: 4 Warnings: 0
MariaDB [test]> SELECT * FROM t1 ORDER BY name;
+------------+------------+------------+
| name | date_1 | date_2 |
+------------+------------+------------+
| a | 1999-01-01 | 2000-01-01 |
| b | 1999-01-01 | 2000-01-01 |
| b | 2018-01-01 | 2018-12-12 |
| b_original | 2000-01-01 | 2018-01-01 |
| c | 1999-01-01 | 2000-01-01 |
| c_original | 2000-01-01 | 2017-01-01 |
| d | 2018-01-01 | 2019-01-01 |
| d_original | 2017-01-01 | 2018-01-01 |
+------------+------------+------------+
8 rows in set (0.001 sec)
これもまた図にするとこうなる。
UPDATE FOR PORTION OF
name = a は例によって範囲外なので影響を受けない。name = b, name = c, name = d は範囲内が更新され範囲外の Time Periods は分割・縮小される。
ここで気になるのが、やはり範囲内に収まりきる Time Periods の挙動について。UPDATE により前述の *_original も影響を受け、とても見づらいが範囲内に収まる Time Periods については DELETE 時と同様に UPDATE の影響を受け、Time Periods が分割・縮小されない。
MariaDB [test]> INSERT INTO t1(name, date_1, date_2) values('e', '2002-01-01', '2007-01-01');
Query OK, 1 row affected (0.007 sec)
MariaDB [test]> UPDATE t1 FOR PORTION OF date_period FROM '2000-01-01' TO '2018-01-01' SET name = CONCAT(name,'_original');
Query OK, 4 rows affected (0.009 sec)
Rows matched: 4 Changed: 4 Inserted: 0 Warnings: 0
MariaDB [test]> SELECT * FROM t1 ORDER BY name;
+---------------------+------------+------------+
| name | date_1 | date_2 |
+---------------------+------------+------------+
| a | 1999-01-01 | 2000-01-01 |
| b | 1999-01-01 | 2000-01-01 |
| b | 2018-01-01 | 2018-12-12 |
| b_original_original | 2000-01-01 | 2018-01-01 |
| c | 1999-01-01 | 2000-01-01 |
| c_original_original | 2000-01-01 | 2017-01-01 |
| d | 2018-01-01 | 2019-01-01 |
| d_original_original | 2017-01-01 | 2018-01-01 |
| e_original | 2002-01-01 | 2007-01-01 |
+---------------------+------------+------------+
9 rows in set (0.001 sec)
WITHOUT OVERLAPS
ここまで書いた上で WITHOUT OVERLAPS なんて名前のものが出てきたら察しがつくが MariaDB 10.5.3 から重複不可にも利用できる。
In file included from server/sql/structs.h:26,
from server/sql/handler.h:34,
from server/storage/innobase/include/trx0xa.h:27,
from server/storage/innobase/include/trx0trx.h:34,
from server/storage/innobase/btr/btr0pcur.cc:30:
server/include/my_time.h: In function 'void my_timeval_trunc(timeval*, uint)':
server/include/my_time.h:249:65: error: conversion from 'long int' to '__darwin_suseconds_t' {aka 'int'} may change value [-Werror=conversion]
249 | tv->tv_usec-= my_time_fraction_remainder(tv->tv_usec, decimals);
/* * Copyright (c) 2003-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */#ifndef _STRUCT_TIMEVAL#define _STRUCT_TIMEVAL struct timeval#include <machine/types.h>/* __darwin_time_t */#include <sys/_types.h>/* __darwin_suseconds_t */
_STRUCT_TIMEVAL
{
__darwin_time_t tv_sec; /* seconds */
__darwin_suseconds_t tv_usec; /* and microseconds */
};
#endif/* _STRUCT_TIMEVAL */
この辺を雑に書くと、オブジェクトが生成された場合はまず Eden 領域に配置されて、そこから Minor GC によって Survivor 領域に移されたり、Survivor 領域が足りなくなったら Tenured 領域に配置され、そこでも領域が足りなくなると Major GC で解放される。
もう少し細かく書くと、Eden 領域に配置されたオブジェクトは Minor GC が走った時に利用されていないオブジェクトを破棄して、利用されているオブジェクトを Survivor 領域に移動させる。Survivor 領域にも移動させられない場合 or 一定回数 Minor GC を生き残ったオブジェクトは Tenured 領域に移動させる。
Tenured 領域にオブジェクトを移動させることができない場合は Major GC が走って不要なオブジェクトを解放する。一般的にはこの時どちらの GC でも停止時間が発生する。特に Full GC の方が時間がかかりがち。
G1GC も世代別 GC となっているがヒープをリージョンという単位で分割し、管理している。その上でそれぞれのリージョンは Young 領域または Old 領域に属することとなる。この時、それぞれの領域に属するリージョンは必ずしも連続するとは限らない。また Tenured 領域に対する処理はバックグラウンドスレッドが行うため大抵の場合、アプリケーションスレッドは停止しない。その代わり複雑な処理を内部で行っているため CPU 使用率が高くなりやすい。
仕組み
G1GC は特に Old 領域に対する GC が他の GCアルゴリズムと異なる。Old 領域に対する GC では対象リージョン内にどれだけ不要となったオブジェクトが存在するかを基準にして領域を確保する。つまり不要オブジェクトが多いリージョンの操作に注力する。そのため短時間で GC を実行することが可能となる。この仕組みは Young 領域には適用されない。
初期マーク付けでマークされた Survivor 領域を走査して、 Old 領域のオブジェクトに対する参照をマークする。次の停止を伴う Young 領域に対する GC が実行される前に完了している必要がある。このフェーズはアプリケーションスレッドと並列実行されるため停止を伴わない。ただし G1GC が利用するスレッドに対する CPU リソースが十分でない時は停止時間が増大する可能性がある。またこのフェーズは中断できないことに注意が必要。
マーク付けフェーズを開始し、完了するまでに Old 領域がいっぱいになった場合。この時該当するフェーズを中断して Major GC が走る。
promotion failure
混合 GC が開始されたが、Old 領域に移動させる必要のあるものが解放されるものより多く、かつ Old 領域がいっぱいになってしまった場合。
evacuation failure
Minor GC 時に Survivor 空間に十分な空きがなく対象となる全てオブジェクトを Old 領域に移動させる必要のある場合。リージョンが確保されているが、各リージョンでデータが断片化してしまった場合に起きやすい。必ず Major GC を伴うわけではないが、Major GC が走る可能性がある。またログ上では Minor GC として記録されているらしい。