# thread buffer がいつ解放されるか?
## thread buffer の種類
- join_buffer
- sort_buffer
- tmp_table_size
- select_into_buffer_size
ref: https://gihyo.jp/article/2022/10/mysql-rcn0183
## sort_buffer
ここで止めてみる (Filesort_info class)
- https://github.com/mysql/mysql-server/blob/mysql-cluster-8.0.32/sql/sql_sort.h#L260
### backtrace
```
(gdb) bt
#0 Filesort_info::free_sort_buffer (this=0x7fdfe5092ae0) at /mysql-8.0.32/sql/sql_sort.h:260
#1 0x000055a0caf53a17 in SortingIterator::CleanupAfterQuery (this=0x7fdfe5092ab8) at /mysql-8.0.32/sql/iterators/sorting_iterator.cc:418
#2 0x000055a0caf53954 in SortingIterator::~SortingIterator (this=0x7fdfe5092ab8, __in_chrg=<optimized out>) at /mysql-8.0.32/sql/iterators/sorting_iterator.cc:414
#3 0x000055a0ca790fb2 in destroy<RowIterator> (ptr=0x7fdfe5092ab8) at /mysql-8.0.32/include/my_alloc.h:459
#4 0x000055a0ca790ef2 in Destroy_only<RowIterator>::operator() (this=0x7fdfe5092c18, ptr=0x7fdfe5092ab8) at /mysql-8.0.32/include/my_alloc.h:481
#5 0x000055a0ca790e14 in std::unique_ptr<RowIterator, Destroy_only<RowIterator> >::~unique_ptr (this=0x7fdfe5092c18, __in_chrg=<optimized out>) at /usr/include/c++/11/bits/unique_ptr.h:361
#6 0x000055a0caf7ac92 in LimitOffsetIterator::~LimitOffsetIterator (this=0x7fdfe5092c08, __in_chrg=<optimized out>) at /mysql-8.0.32/sql/iterators/composite_iterators.h:106
#7 0x000055a0ca790fb2 in destroy<RowIterator> (ptr=0x7fdfe5092c08) at /mysql-8.0.32/include/my_alloc.h:459
#8 0x000055a0ca790ef2 in Destroy_only<RowIterator>::operator() (this=0x7fdfe507fc48, ptr=0x7fdfe5092c08) at /mysql-8.0.32/include/my_alloc.h:481
#9 0x000055a0ca8f1d86 in std::__uniq_ptr_impl<RowIterator, Destroy_only<RowIterator> >::reset (this=0x7fdfe507fc48, __p=0x0) at /usr/include/c++/11/bits/unique_ptr.h:182
#10 0x000055a0ca995cdb in std::unique_ptr<RowIterator, Destroy_only<RowIterator> >::reset (this=0x7fdfe507fc48, __p=0x0) at /usr/include/c++/11/bits/unique_ptr.h:456
#11 0x000055a0caaaad8f in Query_expression::cleanup (this=0x7fdfe507fc10, full=true) at /mysql-8.0.32/sql/sql_union.cc:1841
#12 0x000055a0ca812c25 in LEX::cleanup (this=0x7fdff01379d0, full=true) at /mysql-8.0.32/sql/sql_lex.h:4072
#13 0x000055a0ca95d750 in mysql_execute_command (thd=0x7fdff0acb960, first_level=true) at /mysql-8.0.32/sql/sql_parse.cc:4907
#14 0x000055a0ca95ecaa in dispatch_sql_command (thd=0x7fdff0acb960, parser_state=0x7fe0647f79f0) at /mysql-8.0.32/sql/sql_parse.cc:5322
#15 0x000055a0ca95433d in dispatch_command (thd=0x7fdff0acb960, com_data=0x7fe0647f8340, command=COM_QUERY) at /mysql-8.0.32/sql/sql_parse.cc:2036
#16 0x000055a0ca9522eb in do_command (thd=0x7fdff0acb960) at /mysql-8.0.32/sql/sql_parse.cc:1439
#17 0x000055a0cab9eaa9 in handle_connection (arg=0x55a0d362bf20) at /mysql-8.0.32/sql/conn_handler/connection_handler_per_thread.cc:302
#18 0x000055a0ccb7aeae in pfs_spawn_thread (arg=0x55a0d3636760) at /mysql-8.0.32/storage/perfschema/pfs.cc:2986
#19 0x00007fe0b1c09ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#20 0x00007fe0b1c9b850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
```
次の step
```
(gdb) s
Filesort_buffer::free_sort_buffer (this=0x7fdfe5092ae0) at /mysql-8.0.32/sql/filesort_utils.cc:414
414 void Filesort_buffer::free_sort_buffer() {
```
filesort_buffer class
https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/filesort_utils.h#L80
の、free_sort_buffer 関数に飛ぶ
https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/filesort_utils.cc#L414
backtrace を辿っていくと、[my_alloc.h:459](https://github.com/mysql/mysql-server/blob/mysql-8.0.32/include/my_alloc.h#L459) がわからない
sql/sql_lex.h:4072 の cleanup() 関数で呼ばれてるのでクエリ実行後?
cleanup 関数のコメントは以下
```cpp
/**
Cleanup this subtree (this Query_block and all nested Query_blockes and
Query_expressions).
@param full if false only partial cleanup is done, JOINs and JOIN_TABs are
kept to provide info for EXPLAIN CONNECTION; if true, complete cleanup is
done, all JOINs are freed.
*/
void cleanup(bool full) override;
```
mysql の query 実行関数は mysql_execute_command()?
https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/sql_parse.cc#L2915
→実際に実行されるのはここっぽい? (mysql_sql_stmt_execute()?)
https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/sql_prepare.cc#L1942
mysql_execute_command() から cleanup() が呼ばれてる
https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/sql_parse.cc#L4907
## 2/6
実行したクエリ
```
SELECT * FROM employeess ORDER BY birth_date LIMIT 3
```
.h のファイルにはブレークポイントを置けないっぽい?ので [/mysql-8.0.32/sql/sql_union.cc:1841](https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/sql_union.cc#L1841) にブレークポイントを置いてステップ実行していく
← .h はヘッダファイル(クラスの型定義とか)、.cpp はソースファイル(ヘッダファイルで定義された型に対する実際の実装)
ここでの this は [Query_expression](https://dev.mysql.com/doc/dev/mysql-server/latest/classQuery__expression.html).
gdb 上で `print this.query_term` とかやってみたらクエリの中身見れるのかと思ったら、そんなことはなかった
次に step 実行したら `std::unique_ptr::reset()` に辿り着く
https://cpprefjp.github.io/reference/memory/unique_ptr/reset.html
← 引数を与えない場合、ポインタから値を開放して、該当ポインタが何も指していない状態になる
20回ぐらい step 実行したら [/mysql-8.0.32/include/my_alloc.h:481](https://github.com/mysql/mysql-server/blob/mysql-8.0.32/include/my_alloc.h#L481) に辿り着く
```
(gdb) print ptr
$1 = (RowIterator *) 0xfffebcad91b8
```
ptr は [RowIterator](https://dev.mysql.com/doc/dev/mysql-server/latest/classRowIterator.html) というクラスのものらしい
Detailed description によれば、選択された取得方法を使用して、テーブルから1行ずつレコードを読み取る単純なイテレータらしい。
なんだか THD が取れる。
```
(gdb) print ptr.thd
$2 = {THD *(const RowIterator * const)} 0xaaaac01a56cc <RowIterator::thd() const>
```
次に step 実行したら、[my_alloc.h:459](https://github.com/mysql/mysql-server/blob/mysql-8.0.32/include/my_alloc.h#L459) に辿り着く
ptr は先ほどの RowIterator なので、RowIterator の destructor が呼ばれている。
→
https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/iterators/row_iterator.h#L86
```c++
class RowIterator {
public:
// NOTE: Iterators should typically be instantiated using NewIterator,
// in sql/iterators/timing_iterator.h.
explicit RowIterator(THD *thd) : m_thd(thd) {}
virtual ~RowIterator() = default;
```
virtual って何!? default って何!?
https://cpprefjp.github.io/lang/cpp11/defaulted_and_deleted_functions.html
デフォルトの動作が定義されていて、特殊なメンバ関数に対してのみ代入できる感じっぽい
https://yohe.gitbooks.io/cpp-14/content/chapter_1/core/explicit_default_func.html
destructor は default を指定すると空の関数になると書いてある...
次の step 実行→ [/mysql-8.0.32/sql/iterators/composite_iterators.h:106](https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/iterators/composite_iterators.h#L106)
```c++
LimitOffsetIterator::~LimitOffsetIterator (this=0xfffebcad91b8, __in_chrg=<optimized out>) at /mysql-8.0.32/sql/iterators/composite_iterators.h:106
class LimitOffsetIterator final : public RowIterator {
```
RowIterator を継承した LimitOffsetIterator の方に処理が移った
次の step 実行
```c++
(gdb) s
std::unique_ptr<RowIterator, Destroy_only<RowIterator> >::~unique_ptr (this=0xfffebcad91c8, __in_chrg=<optimized out>) at /usr/include/c++/11/bits/unique_ptr.h:359
359 auto& __ptr = _M_t._M_ptr();
```
c++ の標準ライブラリを抜けると、次の step 実行
```c++
(gdb) s
Destroy_only<RowIterator>::operator() (this=0xfffebcad91c8, ptr=0xfffebcad9068) at /mysql-8.0.32/include/my_alloc.h:481
481 destroy(ptr);
(gdb) s
destroy<RowIterator> (ptr=0xfffebcad9068) at /mysql-8.0.32/include/my_alloc.h:459
459 if (ptr != nullptr) ptr->~T();
(gdb) print ptr
$5 = (RowIterator *) 0xfffebcad9068
(gdb) s
SortingIterator::~SortingIterator (this=0xfffebcad9068, __in_chrg=<optimized out>) at /mysql-8.0.32/sql/iterators/sorting_iterator.cc:412
412 SortingIterator::~SortingIterator() {
(gdb)
```
[SortingIterator](https://dev.mysql.com/doc/dev/mysql-server/latest/classSortingIterator.html) の destructor に辿り着いた
https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/iterators/sorting_iterator.cc#L412
```c++
SortingIterator::~SortingIterator() {
ReleaseBuffers();
CleanupAfterQuery();
}
```
step 実行、当然 ReleaseBuffers() の中に入る
```c++
(gdb) s
413 ReleaseBuffers();
(gdb) s
SortingIterator::ReleaseBuffers (this=0xfffebcad9068) at /mysql-8.0.32/sql/iterators/sorting_iterator.cc:425
425 m_result_iterator.reset();
(gdb)
```
https://github.com/mysql/mysql-server/blob/mysql-8.0.32/sql/iterators/sorting_iterator.cc#L424
かなりここっぽい... my_free() してるし...
- m_result_iterator
- m_sort_result.io_cache
の二つがどういう意味なのか調べるところから