Dictionary Updates

ClickHouse periodically updates the dictionaries. The update interval for fully downloaded dictionaries and the invalidation interval for cached dictionaries are defined in the <lifetime> tag in seconds.

Dictionary updates (other than loading for first use) do not block queries. During updates, the old version of a dictionary is used. If an error occurs during an update, the error is written to the server log, and queries continue using the old version of dictionaries.

Example of settings:

  1. <dictionary>
  2. ...
  3. <lifetime>300</lifetime>
  4. ...
  5. </dictionary>
  1. CREATE DICTIONARY (...)
  2. ...
  3. LIFETIME(300)
  4. ...

Setting <lifetime>0</lifetime> (LIFETIME(0)) prevents dictionaries from updating.

You can set a time interval for upgrades, and ClickHouse will choose a uniformly random time within this range. This is necessary in order to distribute the load on the dictionary source when upgrading on a large number of servers.

Example of settings:

  1. <dictionary>
  2. ...
  3. <lifetime>
  4. <min>300</min>
  5. <max>360</max>
  6. </lifetime>
  7. ...
  8. </dictionary>

or

  1. LIFETIME(MIN 300 MAX 360)

When upgrading the dictionaries, the ClickHouse server applies different logic depending on the type of source:

  • For a text file, it checks the time of modification. If the time differs from the previously recorded time, the dictionary is updated.
  • For MyISAM tables, the time of modification is checked using a SHOW TABLE STATUS query.
  • Dictionaries from other sources are updated every time by default.

For MySQL (InnoDB), ODBC and ClickHouse sources, you can set up a query that will update the dictionaries only if they really changed, rather than each time. To do this, follow these steps:

  • The dictionary table must have a field that always changes when the source data is updated.
  • The settings of the source must specify a query that retrieves the changing field. The ClickHouse server interprets the query result as a row, and if this row has changed relative to its previous state, the dictionary is updated. Specify the query in the <invalidate_query> field in the settings for the source.

Example of settings:

  1. <dictionary>
  2. ...
  3. <odbc>
  4. ...
  5. <invalidate_query>SELECT update_time FROM dictionary_source where id = 1</invalidate_query>
  6. </odbc>
  7. ...
  8. </dictionary>

or

  1. ...
  2. SOURCE(ODBC(... invalidate_query 'SELECT update_time FROM dictionary_source where id = 1'))
  3. ...

Original article