本章節中,我們會介紹ClickHouse資料庫客戶端連線的介面種類與連線的方式。
ClickHouse資料庫提供了三種網路連線的介面方式,相關的介面如下:
clickhouse-client
指令。在先前的客戶端指令與相關的操作,我們都是使用clickhouse-client
的指令來進行完成執行SQL語句的操作,以下是其他有關於此客戶端指令的進階用法:
$ echo -ne "1, 'some text', '2016-08-14 00:00:00'\n2, 'some more text', '2016-08-14 00:00:01'" | clickhouse-client --password --database=test --query="INSERT INTO test FORMAT CSV";
我們以上面的用法來示範一個範例,相關的範例與執行所輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password
ClickHouse client version 22.8.4.7 (official build).
Password for user (default):
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 22.8.4 revision 54460.
Warnings:
* Linux is not using a fast TSC clock source. Performance can be degraded. Check /sys/devices/system/clocksource/clocksource0/current_clocksource
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :) DROP DATABASE IF EXISTS test;
DROP DATABASE IF EXISTS test
Query id: ab6297d5-9c78-490c-841d-0d8f7b78fedf
Ok.
0 rows in set. Elapsed: 0.001 sec.
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :) CREATE DATABASE IF NOT EXISTS test;
CREATE DATABASE IF NOT EXISTS test
Query id: a7f7dff4-af44-447a-8fe2-a019b03d1dee
Ok.
0 rows in set. Elapsed: 0.004 sec.
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :) CREATE TABLE test.test
(
`id` UInt32,
`text` String,
`datetime` DateTime('Asia/Taipei'),
)
ENGINE = MergeTree
ORDER BY id
SETTINGS index_granularity = 8192
CREATE TABLE test.test
(
`id` UInt32,
`text` String,
`datetime` DateTime('Asia/Taipei'),
)
ENGINE = MergeTree
ORDER BY id
SETTINGS index_granularity = 8192
Query id: 1f91422e-bbcc-434f-8411-45c4a0332de9
Ok.
0 rows in set. Elapsed: 0.007 sec.
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :) exit;
Bye.
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# echo -ne "1, 'some text', '2016-08-14 00:00:00'\n2, 'some more text', '2016-08-14 00:00:01'" | clickhouse-client --password --database=test --query="INSERT INTO test FORMAT CSV";
Password for user (default):
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password
ClickHouse client version 22.8.4.7 (official build).
Password for user (default):
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 22.8.4 revision 54460.
Warnings:
* Linux is not using a fast TSC clock source. Performance can be degraded. Check /sys/devices/system/clocksource/clocksource0/current_clocksource
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :) select * from test.test;
SELECT *
FROM test.test
Query id: 8dcc2e39-0610-4dea-8fc2-22d2aeea140b
┌─id─┬─text─────────────┬────────────datetime─┐
│ 1 │ 'some text' │ 2016-08-14 00:00:00 │
│ 2 │ 'some more text' │ 2016-08-14 00:00:01 │
└────┴──────────────────┴─────────────────────┘
2 rows in set. Elapsed: 0.002 sec.
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :)
從上面執行的輸出訊息可以知道,可以使用echo -ne
來建立一個CSV格式的字串,-n
參數是讓echo
指令不會在最後的字串中加入換行的字元,而-e
參數則是讓字串中的拖逸字元備進行解析。
從上面的匯入執行範例可以知道,我們使用了echo -ne
來建立兩行符合CSV格式的字串,接著用|
管線方式將前面的輸出轉成輸入給管線後面的指令使用,clickhouse-client
指令搭配下列參數:
--password
參數,在連線到ClickHouse資料庫伺服器時候,需要提示輸入使用者的密碼。--databaase
參數,在連線到ClickHouse資料庫伺服器的時候,指定連上的資料庫名稱。--query
參數,連線到ClickHouse資料庫伺服器的時候,所要執行的SQL語句,執行的是INSERT INTO test FORMAT CSV
,相關的輸入字串即是管線前面所輸出兩行的CSV字串。另外,我們也可以用下列方式將資料寫入進去,下列是執行該指令的輸出訊息:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat <<_EOF | clickhouse-client --database=test --password --query="INSERT INTO test FORMAT CSV";
3, 'some text', '2016-08-14 00:00:00'
4, 'some more text', '2016-08-14 00:00:01'
_EOF
Password for user (default):
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
上述的作法是利用cat
指令並搭配<< _EOF
將CSV字串定義出來當作輸入,最後用管線給clickhouse-client
指令作使用。下列是另一種方式,也是最常見的方式:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# echo "5, 'some text', '2016-08-14 00:00:00'" >> file.csv
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# echo "6, 'some text', '2016-08-14 00:00:00'" >> file.csv
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat file.csv
5, 'some text', '2016-08-14 00:00:00'
6, 'some text', '2016-08-14 00:00:00'
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat file.csv | clickhouse-client --database=test --password --query="INSERT INTO test FORMAT CSV";
Password for user (default):
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
從上述執行的指令與輸出的訊息可以知道,首先先利用echo
指令分別將兩個CSV字串寫入到file.csv
的檔案中,接著使用cat
指令輸出該CSV檔案內容進行確定,接著再次執行cat file.csv
並搭配管線方式將前面輸出的檔案內容當作輸入傳遞給clickhouse-client
指令進行使用。
執行過的指令都會被寫入到該使用者目錄底下的.clickhouse-client-history
檔案中,路徑位置即:~/.clickhouse-client-history
,執行過的歷史檔案內容範例如下:
......
### 2022-09-29 02:57:39.889
exit;
### 2022-09-29 02:58:39.419
select * from test.test;
......
從上述的範例內容可以知道,每次執行過的指令語句之紀錄會有兩行,第一行是### 時間
,即什麼時候執行這個語句,第二行則是執行的語句。
我們在使用指令模式的時候,還可以透過定義參數,並將定義好的參數傳遞給查詢語句作使用,相關的範例如下:
clickhouse-client --password --param_keyword='123' --query="SELECT {keyword:String}"
clickhouse-client --password --param_keyword='123' --query="SELECT {keyword:UInt32}"
clickhouse-client --password --param_keyword='[123]' --query="SELECT {keyword:Array(UInt8)}"
從上述的範例可以知道,首先可以用--param_
當作前綴字串,後面接的是名稱,以keyword
名稱,表示此參數是要傳遞給SQL語句作使用。
後面的--query
參數帶的SQL語句中要使用前面定義的參數時,需要使用{
與}
包起來,接著裡面的格式是:參數名稱:參數值型別
,參數值型別即欄位資料型別。
相關上述的範例所執行輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password --param_keyword='test' --query="SELECT {keyword:String}"
Password for user (default):
test
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password --param_keyword='123' --query="SELECT {keyword:UInt32}"
Password for user (default):
123
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password --param_keyword='[123]' --query="SELECT {keyword:Array(UInt8)}"
Password for user (default):
[123]
除了用上述的方式設定參數之外,我們也可以在SQL語句中設定,即使用SET
語句來達成,相關的範例如下:
$ clickhouse-client -nq "
SET param_parName='[1, 2]';
SELECT {parName:Array(UInt16)}"
指令模式的-nq
參數指的是讓語句可以以分號進行分開,這樣就可以讓ClickHouse的客戶端進行個別的執行SQL語句,將上述的範例執行所輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password -n -q "
SET param_parName='[1, 2]';
SELECT {parName:Array(UInt16)}"
Password for user (default):
[1,2]
更多的範例如下:
$ clickhouse-client --param_tuple_in_tuple="(10, ('dt', 10))" -q "SELECT * FROM table WHERE val = {tuple_in_tuple:Tuple(UInt8, Tuple(String, UInt8))}"
$ clickhouse-client --param_tbl="numbers" --param_db="system" --param_col="number" --query "SELECT {col:Identifier} FROM {db:Identifier}.{tbl:Identifier} LIMIT 10"
使用clickhouse-client
時候,可以用下列的方式進行設定:
指令模式下可以用的參數如下:
--host
或短參數-h
– 資料庫伺服器的名稱,預設值是localahost
,我們可以指定的值可以是網域名稱、IPv4或是IPv6網路位址。--port
– 設定要連到伺服器的埠號,預設值是9000
,我們要注意的是HTTP
介面與原生的介面連線方式使用不同的埠號進行連線。--user
或短參數-u
– 指連上資料庫伺服器所使用的使用者名稱,預設值是default
。--password
– 連上該資料庫伺服器所使用的使用者密碼,預設值是空字串。--ask-password
- 會有使用者輸入地方等待使用者輸入密碼。--query
或短參數-q
– 當使用非互動模式時,這個參數後面帶的SQL語句會被處理與執行,我們需要指定此參數或是下列的參數,該參數是必填值選項。--queries-file
– 指定SQL語句的檔案路徑讓客戶端讓期可以讀取該檔案出來進行SQL語句執行,該參數是必填選項。--database
或短參數-d
– 選擇確切的資料庫當作連上資料庫伺服器之後的預設進入的資料庫,預設值是定義在ClickHouse資料庫伺服器設定檔案中的值,預設值是default
。--multiline
或短參數-m
– 如果這個參數已經指定,則可以允許多個SQL語句,不要在設定此參數值時輸入enter鍵,這將導致還沒有設定好的語句就直接送出與執行。--multiquery
或短參數-n
– 如果該參數已經指定,則可以允許設定多個SQL語句,並讓各個SQL語句以分號分開。--format
或短參數-f
– 設定使用什麼檔案格式來輸出SQL語句執行後的結果。--vertical
或短參數-E
– 如果設定此參數,則會用Vertical
當作輸出結果的格式,這個參數選項設定可以等價於:--format=Vertical
。--time
或短參數-t
– 如果指定了此參數,則會在非互動模式中將查詢的執行時間輸出到stderr
管線中,輸出值得單位為秒。--stacktrace
參數 – 如果指定了此參數,如果例外的情形發生時,會將發生例外的堆疊追蹤訊息顯示出來。--config-file
– 指定設定檔案路徑。--secure
– 如果此參數有指定的話,則將會以TLS的方式進行安全的資料庫連線,我們可能需要在設定檔中設定我們的CA憑證,可用的設定是給伺服器端的TLS設定。--history_file
— 指定執行的歷史SQL語句指令要存放到哪個檔案路徑。--param_<name>
— 用來定義用在SQL查詢語句中的參數。--hardware-utilization
— 在進度列中輸出硬體資源使用的相關資訊。--print-profile-events
– 輸出ProfileEvents的封包訊息。--profile-events-delay-ms
– 延遲每個ProfileEvents封包訊息間隔時間,單位為millisecond。下列幾個是有關於使用上列參數的範例:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password --time --query="SELECT 1"
Password for user (default):
1
0.001
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password --time --query="SELECT 1" > result.log
Password for user (default):
0.001
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat result.log
1
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password --time --query="SELECT 1" > result.log 2>&1
Password for user (default):
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat result.log
1
0.001
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password --time --query="SELECT 1" > result.log 2> time.log
Password for user (default):
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat result.log
1
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat time.log
0.001
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
從上面可以知道有關於--time
參數的範例,在一般的Shell Script中,預設只會把在stdout
管線的內容重新導向到指定的檔案中,如果要連stderr
管線的內容也需要重新導向到指定的檔案,則可以加入2>&1
,這指的是將stderr
的內容導向到stdout
中並輸出內容後導向到result.log
之檔案中。
若要導向到不同的檔案,則可以將2>&1
改成2> time.log
,time.log
可以自己指定導向的檔案名稱或路徑。
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password --print-profile-events
ClickHouse client version 22.8.4.7 (official build).
Password for user (default):
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 22.8.4 revision 54460.
Warnings:
* Linux is not using a fast TSC clock source. Performance can be degraded. Check /sys/devices/system/clocksource/clocksource0/current_clocksource
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :) SHOW TABLES;
SHOW TABLES
Query id: d681df77-d1f1-428d-b029-f5996173950f
┌─name────────────────────┐
│ describe_example │
│ example_back │
│ insert_select_testtable │
│ limit_by │
│ simple_table │
│ t1 │
│ t2 │
│ table_from_file │
│ table_with_comment │
│ table_with_ttl │
│ temp │
│ ttt │
└─────────────────────────┘
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 10636 ] FunctionExecute: 1 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 10636 ] SelectedRows: 12 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 10636 ] SelectedBytes: 429 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 10636 ] ContextLock: 2 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 10636 ] RWLockAcquiredReadLocks: 12 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 10636 ] MemoryTrackerUsage: 10936 (gauge)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] Query: 2 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] SelectQuery: 1 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] FunctionExecute: 4 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] NetworkSendElapsedMicroseconds: 63 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] NetworkSendBytes: 209 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] SelectedRows: 12 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] SelectedBytes: 429 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] ContextLock: 20 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] RWLockAcquiredReadLocks: 13 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] RealTimeMicroseconds: 336 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] OSReadChars: 435 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] OSWriteChars: 152 (increment)
[ubuntu-s-4vcpu-8gb-amd-sgp1-01] 2022.09.29 06:49:21 [ 0 ] MemoryTrackerUsage: 10936 (gauge)
12 rows in set. Elapsed: 0.002 sec.
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :)
從上述的執行範例可以知道,使用--print-profile-events
參數後可以將每次執行的SQL語句背後的ProfileEvents
進行輸出。
從clickhouse-client
之20.5
版本之後,執行語句的語法高亮度會自動啟用。
使用clickhouse-client
指令時,使用的設定檔案路徑優先順序如下:
--config-file
參數,則會以此參數值的設定檔路徑。./clickhouse-client.xml
。~/.clickhouse-client/config.xml
。/etc/clickhouse-client/config.xml
。下列是設定檔案的範例內容:
<config>
<user>username</user>
<password>password</password>
<secure>true</secure>
<openSSL>
<client>
<caConfig>/etc/ssl/cert.pem</caConfig>
</client>
</openSSL>
</config>
在每個SQL查詢語句執行時候,都會有一個查詢的id,即看到下列的字串:
Query id: 927f137d-00f1-4175-8914-0dd066365e96
預設的查詢id格式是長上述的格式,我們也可以透過設定的方式id格式:
<config>
<query_id_formats>
<speedscope>http://speedscope-host/#profileURL=qp%3Fid%3D{query_id}</speedscope>
</query_id_formats>
</config>
相關設定的方法如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# vim /etc/clickhouse-client/config.xml
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat /etc/clickhouse-client/config.xml | tail -n 5
-->
<query_id_formats>
<speedscope>http://speedscope-host/#profileURL=qp%3Fid%3D{query_id}</speedscope>
</query_id_formats>
</config>
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# clickhouse-client --password
ClickHouse client version 22.8.4.7 (official build).
Password for user (default):
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 22.8.4 revision 54460.
Warnings:
* Linux is not using a fast TSC clock source. Performance can be degraded. Check /sys/devices/system/clocksource/clocksource0/current_clocksource
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :) SELECT 1;
SELECT 1
speedscope:http://speedscope-host/#profileURL=qp%3Fid%3D2d785293-5d12-40db-a334-297503970c8e
┌─1─┐
│ 1 │
└───┘
1 row in set. Elapsed: 0.001 sec.
ubuntu-s-4vcpu-8gb-amd-sgp1-01 :)
從上述執行的指令與輸出的訊息可以得知,首先先利用vim
指令將/etc/clickhouse-client/config.xml
檔案進行編輯,接著使用cat
指令將此檔案的後五行印出,這五行中即是使用上個指令加入下列這三行:
<query_id_formats>
<speedscope>http://speedscope-host/#profileURL=qp%3Fid%3D{query_id}</speedscope>
</query_id_formats>
設定好之後,接著使用clickhouse-client
指令連上資料庫,並執行簡易的SQL查詢語句來驗證查詢id之格式已經完成更改的設定了。
使用HTTP介面可以讓我們透過HTTP通訊協定來與ClickHouse資料庫伺服器的RESTful API進行溝通,這樣一來不會遇到原生介面的限制且可以支援更多的程式語言作使用。
在預設情形下,clickhouse-server
會將此HTTP協定的API監聽在8123的埠號上,這個埠號也可以在伺服器設定進行修改。而HTTPS協定預設會是設定監聽在8443的埠號上。
假設我們的終端機中已經有curl
指令,如果以GET方法請求/
之路徑,則相關執行指令與輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# curl 'http://localhost:8123/'
Ok.
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
預設訊息可以修改伺服器之http_server_default_response設定,設定值預設為Ok.
。
在先前章節有提到可以使用瀏覽器並輸入http://localhost:8123/play
網址可以在網頁上進行輸入SQL查詢的介面。
我們也可以透過下列的方式進行ClickHouse資料庫伺服器目前的健康狀態,相關指令與輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# curl 'http://localhost:8123/ping'
Ok.
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
也可以用下列指令其他的複製節點(replica)的健康狀態,相關指令與輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# curl 'http://localhost:8123/replicas_status'
Ok.
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
預設ClickHouse資料庫網址大小為1 MB
,這個設定可以透過http_max_uri_size
來進行網址大小的設定。
如果請求成功話,我們會收到回應的內容以及200
的HTTP狀態碼;如果有錯誤發生,則我們會收到錯誤的回應,以及500
的HTTP狀態碼。
當使用GET
方法進行請求時,通常都是唯讀的動作,換句話說,需要輸入檔案等動作則需要使用POST
方法進行請求,相關的範例如下:
$ curl 'http://localhost:8123/?query=SELECT%201'
1
$ wget -nv -O- 'http://localhost:8123/?query=SELECT 1'
1
$ echo -ne 'GET /?query=SELECT%201 HTTP/1.0\r\n\r\n' | nc localhost 8123
HTTP/1.0 200 OK
Date: Wed, 27 Nov 2019 10:30:18 GMT
Connection: Close
Content-Type: text/tab-separated-values; charset=UTF-8
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
1
從上述的指令可以得知,使用curl
指令來請求帶有query參數的網址時,其後面的參數值需要經過URL編碼才可以確切的運作,而wget
指令可以不用這樣,但是在HTTP 1.1
版本下,設定keep-alive
與Transfer-Encoding: chunked
等標頭時,則無法良好的運作,因此我們可以使用curl
指令並搭配下列方法避免需要將SQL語句進行URL編碼:
$ echo 'SELECT 1' | curl 'http://localhost:8123/' --data-binary @-
1
$ echo 'SELECT 1' | curl 'http://localhost:8123/?query=' --data-binary @-
1
$ echo '1' | curl 'http://localhost:8123/?query=SELECT' --data-binary @-
1
使用上述的方法時,需要注意的是,SQL語句的關鍵字不可以分開,這樣會導致輸出錯誤的訊息,相關的範例如下:
$ echo 'ECT 1' | curl 'http://localhost:8123/?query=SEL' --data-binary @-
Code: 59, e.displayText() = DB::Exception: Syntax error: failed at position 0: SEL
ECT 1
, expected One of: SHOW TABLES, SHOW DATABASES, SELECT, INSERT, CREATE, ATTACH, RENAME, DROP, DETACH, USE, SET, OPTIMIZE., e.what() = DB::Exception
預設的情形下,使用HTTP介面所回應的內容格式皆為TSV
格式,我們可以在請求的標頭中加入X-ClickHouse-Format
標頭定義回應內容的格式或是用default_format
加入到請求網址的參數。
或者是在SQL語句中進行輸出的格式定義,相關的範例如下:
$ echo 'SELECT 1 FORMAT Pretty' | curl 'http://localhost:8123/?' --data-binary @-
┏━━━┓
┃ 1 ┃
┡━━━┩
│ 1 │
└───┘
下列的範例是建立資料表與寫入資料等方法,相關的範例如下:
# 建立資料表
$ echo 'CREATE TABLE t (a UInt8) ENGINE = Memory' | curl 'http://localhost:8123/' --data-binary @-
# 使用寫入的SQL語句將資料寫入到指定的資料表
$ echo 'INSERT INTO t VALUES (1),(2),(3)' | curl 'http://localhost:8123/' --data-binary @-
# 資料可以與寫入的SQL語句分開
$ echo '(4),(5),(6)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20VALUES' --data-binary @-
# 可以指定任意的資料格式進行資料的寫入
$ echo '(7),(8),(9)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20FORMAT%20Values' --data-binary @-
# 指定TabSeparated格式進行資料的寫入
$ echo -ne '10\n11\n12\n' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20FORMAT%20TabSeparated' --data-binary @-
# 讀取資料的內容的請求網址
$ curl 'http://localhost:8123/?query=SELECT%20a%20FROM%20t'
7
8
9
10
11
12
1
2
3
4
5
6
# 刪除資料表
$ echo 'DROP TABLE t' | curl 'http://localhost:8123/' --data-binary @-
我們可以使用壓縮的方式來減少網路流量,當設定compress=1
在請求網址的參數,則資料庫伺服器會回應壓縮的檔案內容,ClickHouse資料庫支持下列壓縮的方法:
我們可以在使用POST
方法請求的時候,可以帶入Content-Encoding
的請求標頭來傳送壓縮的資料,對應的標頭值為上述所列的壓縮方法,相關的範例如下:
# 傳送壓縮的資料給ClickHouse資料庫伺服器
$ echo "SELECT 1" | gzip -c | \
curl -sS --data-binary @- -H 'Content-Encoding: gzip' 'http://localhost:8123/'
我們也可以加入Accept-Encoding
的請求標頭來接收伺服器回應的壓縮內容,相關的範例如下:
# Receiving compressed data archive from the server
$ curl -vsS "http://localhost:8123/?enable_http_compression=1" \
-H 'Accept-Encoding: gzip' --output result.gz -d 'SELECT number FROM system.numbers LIMIT 3'
$ zcat result.gz
0
1
2
# Receiving compressed data from the server and using the gunzip to receive decompressed data
$ curl -sS "http://localhost:8123/?enable_http_compression=1" \
-H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 3' | gunzip -
0
1
2
我們可以使用X-ClickHouse-Database
的標頭加入到請求標頭設定預設連上的資料庫名稱,或是使用database
參數加入到網址的參數中,相關的範例如下:
$ echo 'SELECT number FROM numbers LIMIT 10' | curl 'http://localhost:8123/?database=system' --data-binary @-
0
1
2
3
4
5
6
7
8
9
我們可以使用HTTP基本驗證(HTTP Basic Authentication)方式將ClickHouse資料庫使用者名稱與密碼帶入,相關的範例如下:
$ echo 'SELECT 1' | curl 'http://user:password@localhost:8123/' -d @-
我們也可以使用網址參數的方式將使用者名稱與密碼帶入到請求網址,相關的範例如下:
$ echo 'SELECT 1' | curl 'http://localhost:8123/?user=user&password=password' -d @-
我們也可以透過X-ClickHouse-User
與X-ClickHouse-Key
的標頭放入到請求的標頭來定義使用者名稱與密碼,相關的範例如下:
$ echo 'SELECT 1' | curl -H 'X-ClickHouse-User: user' -H 'X-ClickHouse-Key: password' 'http://localhost:8123/' -d @-
我們也可以使用--data-urlencode
參數將需要UEL編碼的字串進行帶入與使用,這個參數將會幫我們自動的將字串進行編碼的動作,相關的範例與執行所輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# curl --get --data-urlencode "query=SELECT 1" --data-urlencode "user=user" --data-urlencode "password=password" "http://localhost:8123/"
1
我們也可以透過下列方式設定回應的緩衝(response buffering)大小,相關的範例如下:
$ curl -sS 'http://localhost:8123/?max_result_bytes=4000000&buffer_size=3000000&wait_end_of_query=1' -d 'SELECT toUInt8(number) FROM system.numbers LIMIT 9000000 FORMAT RowBinary'
我們也可以用cURL指令的-d
參數的方式將網址參數與資料帶入,相關的範例如下:
$ curl -sS "<address>?param_id=2¶m_phrase=test" -d "SELECT * FROM table WHERE int_column = {id:UInt8} and string_column = {phrase:String}"
我們也可以預設先將透過HTTP介面連線查詢的SQL語句先定義好。首先,我們可以將下列的設定寫入到伺服器的設定檔中:
<http_handlers>
<rule>
<url>/predefined_query</url>
<methods>POST,GET</methods>
<handler>
<type>predefined_query_handler</type>
<query>SELECT * FROM system.metrics LIMIT 5 FORMAT Template SETTINGS format_template_resultset = 'prometheus_template_output_format_resultset', format_template_row = 'prometheus_template_output_format_row', format_template_rows_between_delimiter = '\n'</query>
</handler>
</rule>
<rule>...</rule>
<rule>...</rule>
</http_handlers>
執行上述的設定指令與輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# vim /etc/clickhouse-server/config.d/handler.xml
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat /etc/clickhouse-server/config.d/handler.xml
<clickhouse>
<http_handlers>
<rule>
<url>/predefined_query</url>
<methods>POST,GET</methods>
<handler>
<type>predefined_query_handler</type>
<query>SELECT * FROM default.ttt</query>
</handler>
</rule>
</http_handlers>
</clickhouse>
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# systemctl restart clickhouse-server.service --no-page
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# systemctl status clickhouse-server.service --no-page
● clickhouse-server.service - ClickHouse Server (analytic DBMS for big data)
Loaded: loaded (/lib/systemd/system/clickhouse-server.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-09-29 10:38:44 UTC; 2s ago
Main PID: 10549 (clckhouse-watch)
Tasks: 203 (limit: 4915)
CGroup: /system.slice/clickhouse-server.service
├─10549 clickhouse-watchdog --config=/etc/clickhouse-server/config.xml --pid-file=/run/clickho…id
└─10567 /usr/bin/clickhouse-server --config=/etc/clickhouse-server/config.xml --pid-file=/run/…id
Sep 29 10:38:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Processing configuration file '…l'.
Sep 29 10:38:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Merging configuration file '/et…l'.
Sep 29 10:38:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Logging trace to /var/log/click…log
Sep 29 10:38:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Logging errors to /var/log/clic…log
Sep 29 10:38:45 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Processing configuration file '…l'.
Sep 29 10:38:45 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Merging configuration file '/et…l'.
Sep 29 10:38:45 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Saved preprocessed configuratio…l'.
Sep 29 10:38:45 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Processing configuration file '…l'.
Sep 29 10:38:45 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Merging configuration file '/et…l'.
Sep 29 10:38:45 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[10549]: Saved preprocessed configuratio…l'.
Hint: Some lines were ellipsized, use -l to show in full.
從上述的執行指令與輸出的訊息可以得知,先使用vim
文字編輯器指令新增一個叫做handler.xml
檔案並放到/etc/clickhouse-server/config.d/
路徑中,接著重新啟動ClickHouse伺服器被背景服務,重新啟動後再利用systemctl status
指令檢查資料庫服務的狀態,以確定背景服務有正確的運作。
接著執行下列的指令,相關的輸出訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# curl -v 'http://localhost:8123/predefined_query?user=user&password=password'
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8123 (#0)
> GET /predefined_query?user=default&password=password HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Thu, 29 Sep 2022 10:46:59 GMT
< Connection: Keep-Alive
< Content-Type: text/tab-separated-values; charset=UTF-8
< X-ClickHouse-Server-Display-Name: ubuntu-s-4vcpu-8gb-amd-sgp1-01
< Transfer-Encoding: chunked
< X-ClickHouse-Query-Id: 0c06852f-427c-4c8f-9015-6623657e6b0c
< X-ClickHouse-Format: TabSeparated
< X-ClickHouse-Timezone: Etc/UTC
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"128","read_bytes":"1024","written_rows":"0","written_bytes":"0","total_rows_to_read":"128","result_rows":"0","result_bytes":"0"}
<
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
* Connection #0 to host localhost left intact
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
更進一步的predefined_query_handler
設定範例如下:
<http_handlers>
<rule>
<url><![CDATA[/query_param_with_url/\w+/(?P<name_1>[^/]+)(/(?P<name_2>[^/]+))?]]></url>
<methods>GET</methods>
<headers>
<XXX>TEST_HEADER_VALUE</XXX>
<PARAMS_XXX><![CDATA[(?P<name_1>[^/]+)(/(?P<name_2>[^/]+))?]]></PARAMS_XXX>
</headers>
<handler>
<type>predefined_query_handler</type>
<query>SELECT value FROM system.settings WHERE name = {name_1:String}</query>
<query>SELECT name, value FROM system.settings WHERE name = {name_2:String}</query>
</handler>
</rule>
<defaults/>
</http_handlers>
從上述的範例可以知道,我們可以定義規則的網址、允許的HTTP方法、HTTP標頭以及查詢處理的類型與所要執行的語句。
dynamic_query_handler
的範例如下:
<http_handlers>
<rule>
<headers>
<XXX>TEST_HEADER_VALUE_DYNAMIC</XXX> </headers>
<handler>
<type>dynamic_query_handler</type>
<query_param_name>query_param</query_param_name>
</handler>
</rule>
<defaults/>
</http_handlers>
設定完成後,則可以執行下列的cURL指令:
$ curl -H 'XXX:TEST_HEADER_VALUE_DYNAMIC' 'http://localhost:8123/own?max_threads=1&max_final_threads=2¶m_name_1=max_threads¶m_name_2=max_final_threads&query_param=SELECT%20name,value%20FROM%20system.settings%20where%20name%20=%20%7Bname_1:String%7D%20OR%20name%20=%20%7Bname_2:String%7D'
max_threads 1
max_final_threads 2
static
類型的範例設定如下:
<http_handlers>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/hi</url>
<handler>
<type>static</type>
<status>402</status>
<content_type>text/html; charset=UTF-8</content_type>
<response_content>Say Hi!</response_content>
</handler>
</rule>
<defaults/>
</http_handlers>
從上述的範例可以知道static
類型可以自己定義請求的路徑、回應的標頭與內容格式和內容,定義好之後執行cURL指令的範例如下:
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/hi'
* Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /hi HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 402 Payment Required
< Date: Wed, 29 Apr 2020 03:51:26 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
<
* Connection #0 to host localhost left intact
Say Hi!%
我們也可以使用static
類型來指定某個檔案路徑並輸出內容,相關的範例設定如下:
<http_handlers>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/get_absolute_path_static_handler</url>
<handler>
<type>static</type>
<content_type>text/html; charset=UTF-8</content_type>
<response_content>file:///absolute_path_file.html</response_content>
</handler>
</rule>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/get_relative_path_static_handler</url>
<handler>
<type>static</type>
<content_type>text/html; charset=UTF-8</content_type>
<response_content>file://./relative_path_file.html</response_content>
</handler>
</rule>
</http_handlers>
執行cURL指令後的範例輸出訊息如下:
$ user_files_path='/var/lib/clickhouse/user_files'
$ sudo echo "<html><body>Relative Path File</body></html>" > $user_files_path/relative_path_file.html
$ sudo echo "<html><body>Absolute Path File</body></html>" > $user_files_path/absolute_path_file.html
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
* Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_absolute_path_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:18:16 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
<
<html><body>Absolute Path File</body></html>
* Connection #0 to host localhost left intact
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
* Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_relative_path_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:18:31 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
<
<html><body>Relative Path File</body></html>
* Connection #0 to host localhost left intact
執行上述的指令範例與輸出的訊息如下:
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# vim /etc/clickhouse-server/config.d/static.xml
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat /etc/clickhouse-server/config.d/static.xml
<clickhouse>
<http_handlers>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/get_config_file</url>
<handler>
<type>static</type>
<content_type>text/xml; charset=UTF-8</content_type>
<response_content>file:///user.xml</response_content>
</handler>
</rule>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/get_user_file</url>
<handler>
<type>static</type>
<content_type>text/xml; charset=UTF-8</content_type>
<response_content>file://./user.xml</response_content>
</handler>
</rule>
</http_handlers>
</clickhouse>
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# systemctl restart clickhouse-server.service
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# systemctl status clickhouse-server.service --no-pager
● clickhouse-server.service - ClickHouse Server (analytic DBMS for big data)
Loaded: loaded (/lib/systemd/system/clickhouse-server.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-09-29 11:04:43 UTC; 35s ago
Main PID: 11600 (clckhouse-watch)
Tasks: 205 (limit: 4915)
CGroup: /system.slice/clickhouse-server.service
├─11600 clickhouse-watchdog --config=/etc/clickhouse-server/config.xml --pid-file=/run/clickho…id
└─11615 /usr/bin/clickhouse-server --config=/etc/clickhouse-server/config.xml --pid-file=/run/…id
Sep 29 11:04:43 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Merging configuration file '/et…l'.
Sep 29 11:04:43 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Logging trace to /var/log/click…log
Sep 29 11:04:43 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Logging errors to /var/log/clic…log
Sep 29 11:04:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Processing configuration file '…l'.
Sep 29 11:04:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Merging configuration file '/et…l'.
Sep 29 11:04:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Merging configuration file '/et…l'.
Sep 29 11:04:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Saved preprocessed configuratio…l'.
Sep 29 11:04:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Processing configuration file '…l'.
Sep 29 11:04:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Merging configuration file '/et…l'.
Sep 29 11:04:44 ubuntu-s-4vcpu-8gb-amd-sgp1-01 clickhouse-server[11600]: Saved preprocessed configuratio…l'.
Hint: Some lines were ellipsized, use -l to show in full.
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# vim /var/lib/clickhouse/user_files/user.xml
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# cat /var/lib/clickhouse/user_files/user.xml
<clickhouse></clickhouse>
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_config_file?user=user&password=password'
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8123 (#0)
> GET /get_config_file?user=default&password=password HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.58.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Thu, 29 Sep 2022 11:11:31 GMT
< Connection: Keep-Alive
< Content-Type: text/xml; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","result_rows":"0","result_bytes":"0"}
<
<clickhouse></clickhouse>
* Connection #0 to host localhost left intact
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~# curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_user_file?user=user&password=password'
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8123 (#0)
> GET /get_user_file?user=default&password=password HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.58.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Thu, 29 Sep 2022 11:11:57 GMT
< Connection: Keep-Alive
< Content-Type: text/xml; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","result_rows":"0","result_bytes":"0"}
<
<clickhouse></clickhouse>
* Connection #0 to host localhost left intact
root@ubuntu-s-4vcpu-8gb-amd-sgp1-01:~#
從上述的執行指令與輸出的訊可以知道,首先以vim
文字編輯器建立/etc/clickhouse-server/config.d/static.xml
檔案並定義/get_config_file
與/get_user_file
路徑,分別設定以絕對和相對路徑方式讀取檔案,只能讀取/var/lib/clickhouse/user_files
目錄下的檔案,接著設定請求標頭需要帶入XXX
名稱且對應的值為xxx
。
設定完成後,就可以重新啟動資料庫服務,接著使用cURL
指令分別發送請求給上述定義的路徑,加入-vv
則是讓cURL指令執行過程中輸出請求跟回應的過程訊息。
從本章節中,我們了解了HTTP與原生介面的連線方式,在下一章節將繼續介紹其他的連線介面方式。