`Ctrl`+`K`

# 7.3.24. `io_flush`

## 7.3.24.1. 概要

バージョン 5.0.5 で追加.

`io_flush` はメモリー上のすべての変更を明示的にディスクに書き出します。通常、明示的に `io_flush` を使う必要はありません。なぜなら、OSが自動的に書き出してくれるからです。また、OSが書き出した方が効率的だからです。

いくつか明示的に `io_flush` を使う必要があるケースがあります。1つは、システムが不意にクラッシュすることがよくあるケースです。もう1つは、Groongaプロセスを通常の終了プロセスで終了できない可能性があるケースです。（通常の終了プロセスとは、例えば、 shutdown を使った終了プロセスです。）これらのケースでは、Groongaデータベースに変更を加えた後に `io_flush` を使うとよいです。以下はGroongaデータベースに変更を加えるコマンドのリストです。

> - column_create

> - column_remove

> - column_rename

> - delete

> - load

> - logical_table_remove

> - object_remove

> - plugin_register

> - plugin_unregister

> - table_create

> - table_remove

> - table_rename

> - truncate

もし、 select の scorer パラメーターをカラムの値を変更するために使っているなら、 select もこのリストに入ります。

`io_flush` は重い処理になる可能性があることに注意してください。もし、メモリー上に多くの変更があるなら、それらをディスクに書き出す処理は重い処理になります。

バージョン 8.0.8 で追加: `io_flush` はフラッシュ中はGroongaのデータベースをロックします。つまり、 `io_flush` 中は次のコマンドを実行できないということです。

> - column_create

> - column_remove

> - column_rename

> - logical_table_remove

> - object_remove

> - plugin_register

> - plugin_unregister

> - table_create

> - table_remove

> - table_rename

## 7.3.24.2. 構文

このコマンドの引数は3つです。

すべての引数は省略可能です:

    io_flush [target_name=null]
             [recursive=yes]
             [only_opened=no]

バージョン 7.0.4 で追加: only_opened が追加されました。

バージョン 9.0.2 で追加: `--recursive dependent` が追加されました。9.0.2以降で対象のオブジェクトを書き出すのにおすすめの方法です。オプションの詳細は recursive を参照してください。

## 7.3.24.3. 使い方

引数無しで実行するとメモリー上のすべての変更をディスクに書き出すことができます。

実行例:

    io_flush
    # [[0, 1337566253.89858, 0.000355720520019531], true]

もし変更点を把握しているなら、書き出し対象を狭めることができます。以下はGroonga 9.0.2以降向けのコマンドと書き出し対象の対応表です。

注釈

Groonga が9.0.1以前の場合( `--recursive dependent` が使えないので)関連するオブジェクトを明示的に書き出す必要があります。それ以降はオブジェクトの書き出し忘れをしないようにするのには `--recursive dependent` を使うのがおすすめです。

コマンド | 書き出し対象 | `io_flush` の引数
--- | --- | ---
load と delete | テーブルとそのテーブルのカラム。 カラムの中に参照カラムがある場合、参照されているテーブルも書き出し対象になる。 インデックスが張られているカラムがある場合、対応するインデックスカラムとそのインデックスカラムのテーブルも書き出し対象になる。 | 対象となるテーブルとそのカラム、参照先のテーブル、インデックスが張られているカラムがある場合、対応するインデックスカラムとそのインデックスカラムのテーブルを書き出すのに `--recursive dependent` を使います。
    io_flush --target_name TABLE_NAME --recursive dependent
truncate | テーブルとそのテーブルのカラム。 カラムの中に参照カラムがある場合、参照されているテーブルも書き出し対象になる。 インデックスが張られているカラムがある場合、対応するインデックスカラムとそのインデックスカラムのテーブルも書き出し対象になる。 データベースも書き出し対象。 | 対象となるテーブルとそのカラム、参照先のテーブル、インデックスが張られているカラムがある場合、対応するインデックスカラムとそのインデックスカラムのテーブルを書き出すのに `--recursive dependent` を使います。
    io_flush --target_name TABLE_NAME --recursive dependent
table_create | 処理対象のテーブルとデータベース。 | テーブル:
    io_flush --target_name TABLE_NAME --recursive dependent
table_remove と table_rename と logical_table_remove | データベース。 | データベース:
    io_flush --recursive no
column_create | 処理対象のカラムとデータベース。 | テーブル:
    io_flush --target_name TABLE_NAME.COLUMN_NAME --recursive dependent
column_remove と column_rename | データベース。 | データベース:
    io_flush --recursive no
plugin_register と plugin_unregister | データベース。 | データベース:
    io_flush --recursive no

もしGroongaが9.0.1以前なら( `--recursive dependent` が使えないので) 明示的にオブジェクトを書き出す必要があります。以下はGroonga 9.0.1以前向けのコマンドと書き出し対象の対応表です。

コマンド | 書き出し対象 | `io_flush` の引数
--- | --- | ---
load と delete | テーブルとそのテーブルのカラム。 カラムの中に参照カラムがある場合、参照されているテーブルも書き出し対象になる。 インデックスが張られているカラムがある場合、対応するインデックスカラムとそのインデックスカラムのテーブルも書き出し対象になる。 | テーブルとそのテーブルのカラム:
    io_flush --target_name TABLE_NAME
参照されているテーブル:
    io_flush --target_name REFERENCED_TABLE_NAME --recursive no
インデックスカラムのテーブル:
    io_flush --target_name TABLE_NAME_OF_INDEX_COLUMN --recursive no
インデックスカラム:
    io_flush --target_name TABLE_NAME_OF_INDEX_COLUMN.INDEX_COLUMN
truncate | テーブルとそのテーブルのカラム。 カラムの中に参照カラムがある場合、参照されているテーブルも書き出し対象になる。 インデックスが張られているカラムがある場合、対応するインデックスカラムとそのインデックスカラムのテーブルも書き出し対象になる。 データベースも書き出し対象。 | テーブルとそのテーブルのカラム:
    io_flush --target_name TABLE_NAME
参照されているテーブル:
    io_flush --target_name REFERENCED_TABLE_NAME --recursive no
インデックスカラムのテーブル:
    io_flush --target_name TABLE_NAME_OF_INDEX_COLUMN --recursive no
インデックスカラム:
    io_flush --target_name TABLE_NAME_OF_INDEX_COLUMN.INDEX_COLUMN
データベース:
    io_flush --recursive no
table_create | 処理対象のテーブルとデータベース。 | テーブル:
    io_flush --target_name TABLE_NAME
データベース:
    io_flush --recursive no
table_remove と table_rename と logical_table_remove | データベース。 | データベース:
    io_flush --recursive no
column_create | 処理対象のカラムとデータベース。 | テーブル:
    io_flush --target_name TABLE_NAME.COLUMN_NAME
データベース:
    io_flush --recursive no
column_remove と column_rename | データベース。 | データベース:
    io_flush --recursive no
plugin_register と plugin_unregister | データベース。 | データベース:
    io_flush --recursive no

## 7.3.24.4. 引数

このセクションではすべての引数について説明します。

### 7.3.24.4.1. 必須引数

必須の引数はありません。

### 7.3.24.4.2. 省略可能引数

いくつか省略可能な引数があります。

#### 7.3.24.4.2.1. `target_name`

対象オブジェクトの名前を指定します。対象オブジェクトはデータベース、テーブル、カラムのどれかです。

このパラメーターを省略すると、データベースが対象オブジェクトになります。

実行例:

    io_flush
    # [[0, 1337566253.89858, 0.000355720520019531], true]

テーブル名を指定すると、そのテーブルが対象オブジェクトになります。

実行例:

    table_create Users TABLE_HASH_KEY ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    io_flush --target_name Users
    # [[0, 1337566253.89858, 0.000355720520019531], true]

カラム名を指定すると、そのカラムが対象オブジェクトになります。

実行例:

    column_create Users age COLUMN_SCALAR UInt8
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    io_flush --target_name Users.age
    # [[0, 1337566253.89858, 0.000355720520019531], true]

#### 7.3.24.4.2.2. `recursive`

書き出し対象オブジェクトの子オブジェクトも対象にするかどうかを指定します。

データベースの子オブジェクトはすべてのテーブルとすべてのカラムです。

テーブルの子オブジェクトはそのテーブルのすべてのカラムです。

カラムの子オブジェクトはありません。

only_opened に `yes` を指定すると `recursive` は無視されます。

`recursive` の値は `yes` または `no` もしくは `dependent` でなければいけません。 `yes` は指定した対象オブジェクトとその子オブジェクトすべてを対象オブジェクトにするという意味です。 `no` は指定した対象オブジェクトのみを対象オブジェクトにするという意味です。`dependent` は指定した対象オブジェクトとその子オブジェクトすべて、参照先のテーブル、インデックスが張られているカラムがある場合、対応するインデックスカラムとそのインデックスカラムのテーブルを対象オブジェクトにするという意味です。

次の `io_flush` はデータベースとすべてのテーブルとすべてのカラムのすべての変更を書き出します。

実行例:

    io_flush --recursive yes
    # [[0, 1337566253.89858, 0.000355720520019531], true]

次の `io_flush` はデータベースの変更だけを書き出します。

実行例:

    io_flush --recursive no
    # [[0, 1337566253.89858, 0.000355720520019531], true]

他の値（つまり、 `yes` でも `no` でもない値）を指定した場合、または `recursive` パラメーターを指定しない場合は `yes` が使われます。

`recursive` 引数の値が不正なので、次のケースでは `yes` が使われます。

実行例:

    io_flush --recursive invalid
    # [[0, 1337566253.89858, 0.000355720520019531], true]

`recursive` パラメーターが指定されていないので、次のケースでは `yes` が使われます。

実行例:

    io_flush
    # [[0, 1337566253.89858, 0.000355720520019531], true]

9.0.2から `--recursive dependent` が追加され、書き出し対象とその子オブジェクトだけでなく、関連したオブジェクトも書き出し対象にするようになりました。関連するオブジェクトは次のとおり:

- 参照されているテーブル

- 関連するインデックスカラム(対象の `TABLE_NAME` にソースカラムがある)

- 関連するインデックスカラムのテーブル(対象の `TABLE_NAME` にソースカラムがある)

関連するオブジェクトのフラッシュ漏れをなくすのに便利です。

例えば、 `--recursive dependent` が `TABLE_NAME` に指定されていると、このオプションは以下と同等のコマンドを内部で実行します。

- テーブルとそのテーブルのカラムをフラッシュ:

      io_flush --target_name TABLE_NAME --recursive yes

- 参照されているテーブルをフラッシュ:

      io_flush --target_name REFERENCED_TABLE_NAME --recursive no

- 関連するインデックスカラムをフラッシュ(対象の `TABLE_NAME` にソースカラムがある):

      io_flush --target_name TABLE_NAME_OF_INDEX_COLUMN.INDEX_COLUMN

- 関連するインデックスカラムのテーブルをフラッシュ(対象の `TABLE_NAME` にソースカラムがある):

      io_flush --target_name TABLE_NAME_OF_INDEX_COLUMN --recursive no

すべての対象となるオブジェクトが正しくフラッシュされたかを確認するにはクエリーログをチェックします:

    > io_flush --recursive "dependent" --target_name "Users"
    :000000000000000 flush[Users]
    :000000000000000 flush[Terms]
    :000000000000000 flush[Terms.users_name]
    :000000000000000 flush[Users.name]
    :000000000000000 flush[(anonymous:table:dat_key)]
    :000000000000000 flush[(anonymous:column:var_size)]
    :000000000000000 flush[(anonymous:table:hash_key)]
    :000000000000000 flush[(anonymous:column:var_size)]
    :000000000000000 flush[(DB)]
    <000000000000000 rc=0

上記の例では、 指定した `Users` テーブルだけでなく、関連する語彙表の `Terms` テーブルとインデックスカラム `Terms.users_name` カラム( `Users.name` がソースカラム)もフラッシュされています。

`flush[(anonymous:...)]` と `flush[(DB)]` はGroongaの内部のオブジェクトがフラッシュされたことを意味します。

ログ | 説明
--- | ---
`flush[(anonymous:table:dat_key)]` | DB内部のオブジェクト名がフラッシュされます。もし `GRN_DB_KEY=pat` が指定されていると `TABLE_PAT_KEY` が使われます。
`flush[(anonymous:column:var_size)]` (1番目に記録されている `(anonymous:column:var_size)` オブジェクト) | 内部のオブジェクトのメタデータ(組込の型だったり、トークンフィルターなど)がフラッシュされます。 可変長のカラムで、内部で使っているオブジェクトのメタデータを保持しています。
`flush[(anonymous:table:hash_key)]` | 設定情報のオブジェクト( `config_set` で設定される)がフラッシュされます。
`flush[(anonymous:column:var_size)]` (2番目に記録されている `(anonymous:column:var_size)` オブジェクト) | 内部のオブジェクトのメタデータ(内部で使っているオブジェクトのオプション。トークナイザーのオプションなど)がフラッシュされます。 可変長のカラムで、内部で使っているオブジェクトのメタデータを保持しています。
`flush[(DB)]` | DBの変更( `io_flush` を実行中にロックを獲得している) がフラッシュされます。

#### 7.3.24.4.2.3. `only_opened`

バージョン 7.0.4 で追加.

すでに開かれているオブジェクトだけフラッシュするかどうかを指定します。

対象のデータベースを変更するプロセスが1つだけの場合、 `only_opened` に `yes` を指定することでフラッシュの性能が改善する可能性があります。これは、不要なフラッシュを省略するからです。

target_name と `only_opened` オプションを一緒に指定することはできません。もし、 target_name を指定した場合は `only_opened` は無視されます。

`only_opened` に `yes` を指定した場合、 recursive は無視されます。

`only_opened` の値は `yes` または `no` でなければいけません。 `yes` の場合はすでに開かれているオブジェクトだけフラッシュします。 `no` の場合は開いているかどうかに関わらず、対象のオブジェクトをフラッシュします。

次の `io_flush` はデータベースとすべてのテーブルとすべてのカラムのすべての変更を書き出します。

実行例:

    io_flush --only_opened yes
    # [[0, 1337566253.89858, 0.000355720520019531], true]

## 7.3.24.5. 戻り値

このコマンドが成功したときは以下のようにボディは `true` になります:

    [HEADER, true]

このコマンドが失敗すると、 `HEADER` にエラーの詳細が含まれます。

`HEADER` については 出力形式 を参照してください。