TOAST/ja
原文最終更新日:27 April 2015
(この情報は少なくともバージョン9.4において正確なものです)
TOASTは"ブロックサイズ"(一般的には8KB)内に1行のデータを保持しようとするPostgreSQLの仕組みです。基本的に、Postgresではデフォルトでそれぞれの最大値が8KBとなる(行が格納された)データ"ブロック"の制限が存在します。ある行がこのサイズを越えて格納される時、TOASTは基本的に大きなカラムのデータを小さな"断片"分解し、TOASTテーブルに格納します。作成したそれぞれのテーブルは、挿入する行のサイズに依存しますが、使用されるされないに関わらず、それ自身に関連した(唯一の)TOASTテーブルを持っています。これらのすべてはユーザに対し透過的であり、デフォルトで有効となっています。
基本的な初回の圧縮、または(十分ではない場合に)TOAST可能なカラムを"ラインから外す(訳注:手動でコマンド実行することで強制的にTOASTを効かせるという意味)"ことによってサイズの縮小を実現できます。ラインから外す仕組みは、大きなカラムを2KBごとに分割し、pg_toast_*テーブルにそれぞれの固まりとして格納することで実現します。データ長とカラムの内容を指し示すpg_toastへの*ポインタ*を格納するそれは普通に格納されます。ポインタシステムが実装された方法の影響で、多くのTOAST可能なカラムタイプは最大で1GBに制限されます。
一般に、最大"1GB"であるどのカラムもTOAST可能なカラムであることを意味しており、BYTEA、VARCHAR、CHARと他のもの(可変長データ"varlena"型のもの)を含みます。
デフォルトのTOASTオプションはEXTENDEDと呼ばれ、最初にカラムのデータを圧縮することを試みます。十分に圧縮されない場合は、コマンド実行により手動でTOASTテーブルへ突っ込んでください。
psqlを開き、以下のコマンド実行にて現在のTOASTオプションを表示できます。
\d+ テーブル名
例:
=> \d+ test_table_name; Table "name_space.test_table_name" Column | Type | Modifiers | Storage | Stats target | Description --------+-------------------+-----------+----------+--------------+------------- foo | character(100000) | | extended | |
以下のようにすることでstorageの型を変更できます。
alter table test_blob alter column column_name set storage EXTENDED;
手動による、TOASTコマンドの発行を含まないオプションにてalterコマンドの発行する前に注意してください。何故ならコマンド発行または行サイズが8KB制限から拡張されない場合に、行挿入時に失敗を生じます(そして例外がスローされることがあります)。
一般に、行が2KB以下となるように圧縮が試され、十分に圧縮されない場合は手動でコマンド実行します。2KBに届かなくても問題なく、行の合計サイズが8KBより小さければ格納可能です。
サイズ制限
ここでの注意事項は、"ライン外"に移動されたそれぞれの行のために一つのOIDが[グローバルOIDカウンタから]生成され、そのテーブルに関連したTOASTテーブル内で追跡するために使用されます。すべてのテーブルに渡ってこれらの行が40億行を超える場合(覚えておいてください、これはグローバル共有ラッピングカウンターです)、OIDカウンタは40億行の制限近づく時に著しい速度の低下を生ずる可能性を"包括します"。http://osdir.com/ml/postgresql-pgsql-hackers/2015-01/msg01901.html を参照してください(もちろん40億行のライン外の行に対するハードリミットが存在します)。これは、TOASTで複数カラム(実際には10カラム、それぞれ大きな挿入値といったもの)を設定する場合、テーブルで制限された合計で40億行より少ない状態で納めるということも意味しています(パーティショニングは回避策となります)。
ここでの良いニュースは、もしそれぞれの行が2KBより少ない場合[特にもしそれが2KBより少ないと保証される場合]、TOASTは使用されず、40億行の制限には当たりません。同様に、行の"最も多く"が2KB制限を越えない場合、問題に奔走することはなく、もしくは修正を要求されず、テーブルごとに40億行以上のデータを持つことができます(本質的に"無制限"です)。
もし主要な型の圧縮が設定されている場合、[基本的に]圧縮を利用して行を8KB以下に圧縮することを試み、8KBいかにならない場合はラインを外すことができます。これは40億行の制限を回避する助けとなるでしょう。
別のオプションとしては、TOAST_TUPLE_THRESHOLDの"デフォルト値"を違うものにしてpostgresを再コンパイルします。