OceanBaseデータベースは、Memleakツールを使用してメモリリークを診断します。その仕組みとしては、トレースモジュールのメモリ割り当てスタックを記録し、特定のスタックの累積回数が一定期間にわたって増加し続ける場合、そのスタックに対応するメモリ割り当てコンテキストでメモリリークが発生している可能性があります。しかし、Memleakを有効にするタイミングは一般的にメモリリークが発生した後であり、Memleakを有効にした後にメモリリークが止まってしまうと、リークが発生したモジュールを追跡できなくなり、再現を待つしかありません。そのため、ノーマライズドMemleakを使用して、メモリ割り当て情報のサンプリングをリアルタイムで保存し、サンプリング結果に基づいてメモリリークが発生する可能性のあるモジュールを分析する必要があります。
ノーマライズドMemleakは、構成パラメータ_min_malloc_sample_intervalと_max_malloc_sample_intervalを使用して、メモリ割り当て情報のサンプリング率を制御します。
| パラメータ | 説明 | 値の範囲 | デフォルト値 |
|---|---|---|---|
| _min_malloc_sample_interval | 連続する2回のサンプリング間におけるob_mallocの最小回数 | [1,10000] | 16 |
| _max_malloc_sample_interval | 連続する2回のサンプリング間におけるob_mallocの最大回数 | [1,10000] | 256 |
構成パラメータを設定してメモリ割り当て情報のサンプリング率を制御する方法は、以下の3つのモードに分かれます:
ゼロサンプリングモード:このモードでは、システムはメモリ割り当て情報の記録を停止します。
obclient> ALTER SYSTEM SET _min_malloc_sample_interval=10000; Query OK, 0 rows affected obclient> ALTER SYSTEM SET _max_malloc_sample_interval=10000; Query OK, 0 rows affectedフルサンプリングモード:このモードでは、システムはすべてのメモリ割り当て情報を記録します。このモードでは、OceanBaseデータベースのパフォーマンスが大幅に低下します。
obclient> ALTER SYSTEM SET _min_malloc_sample_interval=1; Query OK, 0 rows affected obclient> ALTER SYSTEM SET _max_malloc_sample_interval=1; Query OK, 0 rows affectedノーマライズドモード:このモードでは、システムは設定されたサンプリング間隔に従って、メモリ割り当て情報のサンプリングを行います。
obclient> ALTER SYSTEM SET _min_malloc_sample_interval=16; Query OK, 0 rows affected obclient> ALTER SYSTEM SET _max_malloc_sample_interval=256; Query OK, 0 rows affected
注意
- OceanBaseデータベースでは、名前が「_」で始まる構成パラメータは隠れた構成パラメータと呼ばれ、開発者が障害調査や緊急運用時にのみ使用します。
- 構成パラメータの値を設定する際には、以下の要件を満たす必要があります:
_min_malloc_sample_interval <= _max_malloc_sample_interval。 - 構成パラメータ
_min_malloc_sample_intervalと_max_malloc_sample_intervalは、ユーザーが無闇に変更することは推奨されません。不適切な変更はクラスタのパフォーマンスを低下させる原因となります。
ノーマライゼーションMemleakを使用したメモリリーク診断
rootユーザーでクラスタのsysテナントにログインします。バーチャルテーブル
__all_virtual_malloc_sample_infoを使用して、メモリリークが発生したと疑われるモジュールのメモリ割り当て情報を照会します。以下は、モジュール
glibc_mallocを例に、そのメモリ割り当て情報を照会する方法です:obclient [oceanbase]> SELECT * FROM __all_virtual_malloc_sample_info WHERE mod_name='glibc_malloc' ORDER BY alloc_bytes DESC limit 10; +-------------+----------+-----------+--------+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+-------------+-------------+ | svr_ip | svr_port | tenant_id | ctx_id | mod_name | back_trace | ctx_name | alloc_count | alloc_bytes | +-------------+----------+-----------+--------+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+-------------+-------------+ | xx.xx.xx.xx | 25224 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e2919 0x187f31a6 0x188a867a 0x188aa126 0x15c53d3f 0x16b06ae2 0x16b369ef 0x16b32d7e 0x15c8bcf8 0x15c8606a | GLIBC | 3 | 9437232 | | xx.xx.xx.xx | 25225 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e2919 0x187f31a6 0x188a867a 0x188aa126 0x15c53d3f 0x16b06ae2 0x16b369ef 0x16b32d7e 0x15c8bcf8 0x15c8606a | GLIBC | 3 | 9437232 | | xx.xx.xx.xx | 25226 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e2919 0x187f31a6 0x188a867a 0x188aa126 0x15c53d3f 0x16b06ae2 0x16b369ef 0x16b32d7e 0x15c8bcf8 0x15c8606a | GLIBC | 3 | 9437232 | | xx.xx.xx.xx | 25224 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x19dee05c 0x19e00077 0xb49139a 0x5f6d17f 0x7fc3a6c85445 0x5f6abe1 0x0 0x0 0x0 0x0 0x0 | GLIBC | 1 | 4194320 | | xx.xx.xx.xx | 25225 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x19dee05c 0x19e00077 0xb49139a 0x5f6d17f 0x7ff8c02b3445 0x5f6abe1 0x0 0x0 0x0 0x0 0x0 | GLIBC | 1 | 4194320 | | xx.xx.xx.xx | 25226 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x19dee05c 0x19e00077 0xb49139a 0x5f6d17f 0x7f06f1b63445 0x5f6abe1 0x0 0x0 0x0 0x0 0x0 | GLIBC | 1 | 4194320 | | xx.xx.xx.xx | 25224 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e2919 0x187f31a6 0x15c76adf 0xb49e963 0xb4915b6 0x5f6d17f 0x7fc3a6c85445 0x5f6abe1 0x0 0x0 | GLIBC | 1 | 3145744 | | xx.xx.xx.xx | 25225 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e2919 0x187f31a6 0x15c76adf 0xb49e963 0xb4915b6 0x5f6d17f 0x7ff8c02b3445 0x5f6abe1 0x0 0x0 | GLIBC | 1 | 3145744 | | xx.xx.xx.xx | 25226 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e2919 0x187f31a6 0x15c76adf 0xb49e963 0xb4915b6 0x5f6d17f 0x7f06f1b63445 0x5f6abe1 0x0 0x0 | GLIBC | 1 | 3145744 | | xx.xx.xx.xx | 25224 | 500 | 22 | glibc_malloc | 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e28d9 0x161a7a6b 0x161a7148 0x161aa227 0x64f4472 0x64f003c 0x64b9e68 0x64b1d45 0x6520720 0x651e8db | GLIBC | 2 | 131120 | +-------------+----------+-----------+--------+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+-------------+-------------+ 10 rows in set (0.012 sec)バーチャルテーブルの照会を通じて分析した結果、
0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e2919 0x187f31a6 0x188a867a 0x188aa126 0x15c53d3f 0x16b06ae2 0x16b369ef 0x16b32d7e 0x15c8bcf8 0x15c8606aのスタックのalloc_bytesが最も大きいため、メモリリークが発生した可能性があると疑われます。フィールドの説明:
列名 タイプ 説明 svr_ip varchar:MAX_IP_ADDR_LENGTH IPアドレス svr_port bigint(20) ポート番号 tenant_id bigint(20) テナントID ctx_id bigint(20) CTX ID mod_name varchar:OB_MAX_CHAR_LENGTH モジュール名 back_trace varchar:DEFAULT_BUF_LENGTH メモリ割り当てのスタック ctx_name varchar:OB_MAX_CHAR_LENGTH CTX名 alloc_count bigint(20) メモリ割り当て回数 alloc_bytes bigint(20) メモリ割り当ての合計サイズ バーチャルテーブルの照会結果に基づいて、
alloc_bytesが大きいスタックback_traceを分析します:$addr2line -pCfe bin/observer 0x5f8bf23 0x5c5a5bd 0x5c52ec3 0x198ed1c6 0x5d788ba 0x1d8e28a5 0x1d8e2919 0x187f31a6 0x188a867a 0x188aa126 0x15c53d3f 0x16b06ae2 0x16b369ef 0x16b32d7e 0x15c8bcf8 0x15c8606a void* oceanbase::lib::ObTenantCtxAllocator::common_alloc<oceanbase::lib::ObjectMgr>(long, oceanbase::lib::ObMemAttr const&, oceanbase::lib::ObTenantCtxAllocator&, oceanbase::lib::ObjectMgr&) at /home/distcc/tmp/./deps/oblib/src/lib/alloc/ob_tenant_ctx_allocator.cpp:414 (discriminator 2) oceanbase::lib::ObTenantCtxAllocator::alloc(long, oceanbase::lib::ObMemAttr const&) at /home/distcc/tmp/./deps/oblib/src/lib/alloc/ob_tenant_ctx_allocator.cpp:35 oceanbase::lib::ObMallocAllocator::alloc(long, oceanbase::lib::ObMemAttr const&) at ??:? oceanbase::common::ob_malloc(long, oceanbase::lib::ObMemAttr const&) at ./build_sanity/deps/oblib/src/lib/../../../../../deps/oblib/src/lib/allocator/ob_malloc.h:39 ob_malloc_hook(unsigned long, void const*) at ??:? operator new(unsigned long) at ??:? operator new[](unsigned long, std::nothrow_t const&) at ??:? oceanbase::share::schema::ObSchemaMgrCache::init(long, oceanbase::share::schema::ObSchemaMgrCache::Mode) at ./build_sanity/src/share/./src/share/schema/ob_schema_mgr_cache.cpp:153 oceanbase::share::schema::ObSchemaStore::init(unsigned long, long, long) at ./build_sanity/src/share/./src/share/schema/ob_schema_store.cpp:29 oceanbase::share::schema::ObSchemaStoreMap::create(unsigned long, long, long) at ./build_sanity/src/share/./src/share/schema/ob_schema_store.cpp:131 (discriminator 2) oceanbase::share::schema::ObMultiVersionSchemaService::init_multi_version_schema_struct(unsigned long) at ./build_sanity/src/share/./src/share/schema/ob_multi_version_schema_service.cpp:218 (discriminator 52) oceanbase::share::schema::ObServerSchemaService::update_schema_mgr(oceanbase::common::ObISQLClient&, oceanbase::share::schema::ObRefreshSchemaStatus const&, oceanbase::share::schema::ObSchemaMgr&, long, oceanbase::share::schema::ObServerSchemaService::AllSchemaKeys&) at ./build_sanity/src/share/./src/share/schema/ob_server_schema_service.cpp:4232 (discriminator 54) oceanbase::share::schema::ObServerSchemaService::refresh_increment_schema(oceanbase::share::schema::ObRefreshSchemaStatus const&) at ./build_sanity/src/share/./src/share/schema/ob_server_schema_service.cpp:5663 (discriminator 4) oceanbase::share::schema::ObServerSchemaService::refresh_schema(oceanbase::share::schema::ObRefreshSchemaStatus const&) at ./build_sanity/src/share/./src/share/schema/ob_server_schema_service.cpp:5288 oceanbase::share::schema::ObMultiVersionSchemaService::refresh_tenant_schema(unsigned long) at ??:? operator() at ./build_sanity/src/share/./src/share/schema/ob_multi_version_schema_service.cpp:2328 (discriminator 4)alloc_bytesが最大のスタックをaddr2lineコマンドで解析し、技術サポート担当者に連絡して、このスタックでメモリリークが発生しているかどうかを分析してもらいます。