{"id":13635876,"url":"https://github.com/openresty/drizzle-nginx-module","last_synced_at":"2025-04-19T04:31:39.218Z","repository":{"id":736181,"uuid":"386256","full_name":"openresty/drizzle-nginx-module","owner":"openresty","description":"an nginx upstream module that talks to mysql and drizzle by libdrizzle","archived":false,"fork":false,"pushed_at":"2023-11-23T11:35:42.000Z","size":945,"stargazers_count":334,"open_issues_count":15,"forks_count":59,"subscribers_count":43,"default_branch":"master","last_synced_at":"2024-02-13T10:03:39.996Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://wiki.nginx.org/NginxHttpDrizzleModule","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openresty.png","metadata":{"files":{"readme":"README.markdown","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2009-11-26T09:18:15.000Z","updated_at":"2024-08-02T00:03:29.719Z","dependencies_parsed_at":"2024-08-02T00:13:37.415Z","dependency_job_id":null,"html_url":"https://github.com/openresty/drizzle-nginx-module","commit_stats":{"total_commits":450,"total_committers":12,"mean_commits":37.5,"dds":0.1266666666666667,"last_synced_commit":"fb6cf255d91135e18145a98a93947ead4e703b68"},"previous_names":[],"tags_count":63,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openresty%2Fdrizzle-nginx-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openresty%2Fdrizzle-nginx-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openresty%2Fdrizzle-nginx-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openresty%2Fdrizzle-nginx-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openresty","download_url":"https://codeload.github.com/openresty/drizzle-nginx-module/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223790472,"owners_count":17203355,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T00:00:53.580Z","updated_at":"2024-11-09T05:31:04.559Z","avatar_url":"https://github.com/openresty.png","language":"C","funding_links":[],"categories":["Modules","Third Modules","Third Party Modules","C"],"sub_categories":["C Modules"],"readme":"Name\n====\n\ndrizzle-nginx-module - Upstream module for talking to MySQL and Drizzle directly\n\n*This module is not distributed with the Nginx source.* See [the installation instructions](#installation).\n\nTable of Contents\n=================\n\n* [Status](#status)\n* [Version](#version)\n* [Synopsis](#synopsis)\n* [Description](#description)\n    * [Keepalive connection pool](#keepalive-connection-pool)\n    * [Last Insert ID](#last-insert-id)\n* [Directives](#directives)\n    * [drizzle_server](#drizzle_server)\n    * [drizzle_keepalive](#drizzle_keepalive)\n    * [drizzle_query](#drizzle_query)\n    * [drizzle_pass](#drizzle_pass)\n    * [drizzle_connect_timeout](#drizzle_connect_timeout)\n    * [drizzle_send_query_timeout](#drizzle_send_query_timeout)\n    * [drizzle_recv_cols_timeout](#drizzle_recv_cols_timeout)\n    * [drizzle_recv_rows_timeout](#drizzle_recv_rows_timeout)\n    * [drizzle_buffer_size](#drizzle_buffer_size)\n    * [drizzle_module_header](#drizzle_module_header)\n    * [drizzle_status](#drizzle_status)\n* [Variables](#variables)\n    * [$drizzle_thread_id](#drizzle_thread_id)\n* [Output Format](#output-format)\n    * [RDS Header Part](#rds-header-part)\n    * [RDS Body Part](#rds-body-part)\n        * [Columns](#columns)\n        * [Rows](#rows)\n            * [Row Flag](#row-flag)\n            * [Fields Data](#fields-data)\n    * [RDS buffer Limitations](#rds-buffer-limitations)\n* [Status Code](#status-code)\n* [Caveats](#caveats)\n* [Trouble Shooting](#trouble-shooting)\n* [Known Issues](#known-issues)\n* [Installation](#installation)\n* [Compatibility](#compatibility)\n* [Community](#community)\n    * [English Mailing List](#english-mailing-list)\n    * [Chinese Mailing List](#chinese-mailing-list)\n* [Report Bugs](#report-bugs)\n* [Source Repository](#source-repository)\n* [Test Suite](#test-suite)\n* [TODO](#todo)\n* [Changes](#changes)\n* [Authors](#authors)\n* [Copyright \u0026 License](#copyright--license)\n* [See Also](#see-also)\n\nStatus\n======\n\nThis module is already production ready.\n\nVersion\n=======\n\nThis document describes ngx_drizzle [v0.1.11](https://github.com/openresty/drizzle-nginx-module/tags) released on 19 April 2018.\n\nSynopsis\n========\n\n```nginx\n\n http {\n     ...\n\n     upstream cluster {\n         # simple round-robin\n         drizzle_server 127.0.0.1:3306 dbname=test\n              password=some_pass user=monty protocol=mysql;\n         drizzle_server 127.0.0.1:1234 dbname=test2\n              password=pass user=bob protocol=drizzle;\n     }\n\n     upstream backend {\n         drizzle_server 127.0.0.1:3306 dbname=test\n              password=some_pass user=monty protocol=mysql;\n     }\n\n     server {\n         location /mysql {\n             set $my_sql 'select * from cats';\n             drizzle_query $my_sql;\n\n             drizzle_pass backend;\n\n             drizzle_connect_timeout    500ms; # default 60s\n             drizzle_send_query_timeout 2s;    # default 60s\n             drizzle_recv_cols_timeout  1s;    # default 60s\n             drizzle_recv_rows_timeout  1s;    # default 60s\n         }\n\n         ...\n\n         # for connection pool monitoring\n         location /mysql-pool-status {\n             allow 127.0.0.1;\n             deny all;\n\n             drizzle_status;\n         }\n     }\n }\n```\n\n[Back to TOC](#table-of-contents)\n\nDescription\n===========\n\nThis is an nginx upstream module integrating [libdrizzle](https://launchpad.net/drizzle) into Nginx in a non-blocking and streamming way.\n\nEssentially it provides a very efficient and flexible way for nginx internals to access MySQL, Drizzle, as well as other RDBMS's that support the Drizzle or MySQL wired protocol. Also it can serve as a direct REST interface to those RDBMS backends.\n\nThis module does not generate human-readable outputs, rather, in a binary format called Resty-DBD-Stream (RDS) designed by ourselves. You usually need other components, like [rds-json-nginx-module](http://github.com/openresty/rds-json-nginx-module), [rds-csv-nginx-module](http://github.com/openresty/rds-csv-nginx-module), or [lua-rds-parser](http://github.com/openresty/lua-rds-parser), to work with this module. See [Output Format](#output-format) for details.\n\n[Back to TOC](#table-of-contents)\n\nKeepalive connection pool\n-------------------------\n\nThis module also provides a builtin per-worker connection pool mechanism for MySQL or Drizzle TCP connections.\n\nHere's a sample configuration:\n\n```nginx\n\n upstream backend {\n     drizzle_server 127.0.0.1:3306 dbname=test\n          password=some_pass user=monty protocol=mysql;\n     drizzle_keepalive max=100 mode=single overflow=reject;\n }\n```\n\nFor now, the connection pool uses a simple LIFO algorithm to assign idle connections in the pool. That is, most recently (successfully) used connections will be reused first the next time. And new idle connections will always replace the oldest idle connections in the pool even if the pool is already full.\n\nSee the [drizzle_keepalive](#drizzle_keepalive) directive for more details.\n\n[Back to TOC](#table-of-contents)\n\nLast Insert ID\n--------------\nIf you want to get LAST_INSERT_ID, then ngx_drizzle already returns that automatically for you when you're doing a SQL insert query. Consider the following sample `nginx.conf` snippet:\n```nginx\n\n location /test {\n     echo_location /mysql \"drop table if exists foo\";\n     echo;\n     echo_location /mysql \"create table foo (id serial not null, primary key (id), val real);\";\n     echo;\n     echo_location /mysql \"insert into foo (val) values (3.1415926);\";\n     echo;\n     echo_location /mysql \"select * from foo;\";\n     echo;\n }\n\n location /mysql {\n     drizzle_pass backend;\n     drizzle_module_header off;\n     drizzle_query $query_string;\n     rds_json on;\n }\n```\nThen request `GET /test` gives the following outputs:\n```javascript\n\n {\"errcode\":0}\n {\"errcode\":0}\n {\"errcode\":0,\"insert_id\":1,\"affected_rows\":1}\n [{\"id\":1,\"val\":3.1415926}]\n```\nYou can see the `insert_id` field (as well as the `affected_rows` field in the 3rd JSON response.\n\n[Back to TOC](#table-of-contents)\n\nDirectives\n==========\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_server\n--------------\n**syntax:** *drizzle_server \u0026lt;host\u0026gt; user=\u0026lt;user\u0026gt; password=\u0026lt;pass\u0026gt; dbname=\u0026lt;database\u0026gt;*\n\n**syntax:** *drizzle_server \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt; user=\u0026lt;user\u0026gt; password=\u0026lt;pass\u0026gt; dbname=\u0026lt;database\u0026gt; protocol=\u0026lt;protocol\u0026gt; charset=\u0026lt;charset\u0026gt;*\n\n**default:** *no*\n\n**context:** *upstream*\n\nDirective assigns the name and the parameters of server. For the name it is possible to use a domain name, an address, with an optional port (default: 3306). If domain name resolves to several addresses, then all are used.\n\nThe following options are supported:\n\n**user=**`\u003cuser\u003e`\n\tMySQL/Drizzle user name `\u003cuser\u003e` for login.\n\n**password=**`\u003cpass\u003e`\n\tSpecify mysql password `\u003cpass\u003e`for login. If you have special characters like `#` or spaces in your password text, then you'll have to quote the whole key-value pair with either single-quotes or double-quotes, as in\n\n```nginx\n\n drizzle_server 127.0.0.1:3306 user=monty \"password=a b#1\"\n         dbname=test protocol=mysql;\n```\n\n**dbname=**`\u003cdatabase\u003e`\n\tSpecify default MySQL database `\u003cdatabase\u003e` for the connection. Note that MySQL does allow referencing tables belonging to different databases by qualifying table names with database names in SQL queries.\n\n**protocol=**`\u003cprotocol\u003e`\n\tSpecify which wire protocol to use, `drizzle` or `mysql`. Default to `drizzle`.\n\n**charset=**`\u003ccharset\u003e`\n\tExplicitly specify the character set for the MySQL connections. Setting this option to a non-empty value will make this module send out a `set names '\u003ccharset\u003e'` query right after the mysql connection is established.\n\tIf the default character encoding of the MySQL connection is already what you want, you needn't set this option because it has extra runtime cost.\n\tHere is a small example:\n```nginx\n\n drizzle_server foo.bar.com:3306 user=monty password=some_pass\n                                 dbname=test protocol=mysql\n                                 charset=utf8;\n```\nPlease note that for the mysql server, \"utf-8\" is not a valid encoding name while `utf8` is.\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_keepalive\n-----------------\n**syntax:** *drizzle_keepalive max=\u0026lt;size\u0026gt; mode=\u0026lt;mode\u0026gt;*\n\n**default:** *drizzle_keepalive max=0 mode=single*\n\n**context:** *upstream*\n\nConfigures the keep-alive connection pool for MySQL/Drizzle connections.\n\nThe following options are supported:\n\n**max=**`\u003cnum\u003e`\n\tSpecify the capacity of the connection pool for the current upstream block. The \u003cnum\u003e value *must* be non-zero. If set to `0`, it effectively disables the connection pool. This option is default to `0`.\n\n**mode=**`\u003cmode\u003e`\n\tThis supports two values, `single` and `multi`. The `single` mode means the pool does not distinguish various drizzle servers in the current upstream block while `multi` means the pool will merely reuse connections which have identical server host names and ports. Note that even under `multi`, differences between `dbname` or `user` parameters will be silently ignored. Default to `single`.\n\n**overflow=**`\u003caction\u003e`\n\tThis option specifies what to do when the connection pool is already full while new database connection is required. Either `reject` or `ignore` can be specified. In case of `reject`, it will reject the current request, and returns the `503 Service Unavailable` error page. For `ignore`, this module will go on creating a new database connection.\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_query\n-------------\n**syntax:** *drizzle_query \u0026lt;sql\u0026gt;*\n\n**default:** *no*\n\n**context:** *http, server, location, location if*\n\nSpecify the SQL queries sent to the Drizzle/MySQL backend.\n\nNginx variable interpolation is supported, but you must be careful with SQL injection attacks. You can use the [set_quote_sql_str](http://github.com/openresty/set-misc-nginx-module#set_quote_sql_str) directive, for example, to quote values for SQL interpolation:\n\n```nginx\n\n location /cat {\n     set_unescape_uri $name $arg_name;\n     set_quote_sql_str $quoted_name $name;\n\n     drizzle_query \"select * from cats where name = $quoted_name\";\n     drizzle_pass my_backend;\n }\n```\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_pass\n------------\n**syntax:** *drizzle_pass \u0026lt;remote\u0026gt;*\n\n**default:** *no*\n\n**context:** *location, location if*\n\n**phase:** *content*\n\nThis directive specifies the Drizzle or MySQL upstream name to be queried in the current location. The `\u003cremote\u003e` argument can be any upstream name defined with the [drizzle_server](#drizzle_server) directive.\n\nNginx variables can also be interpolated into the `\u003cremote\u003e` argument, so as to do dynamic backend routing, for example:\n```nginx\n\n upstream moon { drizzle_server ...; }\n\n server {\n     location /cat {\n         set $backend 'moon';\n\n         drizzle_query ...;\n         drizzle_pass $backend;\n     }\n }\n```\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_connect_timeout\n-----------------------\n**syntax:** *drizzle_connect_time \u0026lt;time\u0026gt;*\n\n**default:** *drizzle_connect_time 60s*\n\n**context:** *http, server, location, location if*\n\nSpecify the (total) timeout for connecting to a remote Drizzle or MySQL server.\n\nThe `\u003ctime\u003e` argument can be an integer, with an optional time unit, like `s` (second), `ms` (millisecond), `m` (minute). The default time unit is `s`, i.e., \"second\". The default setting is `60s`.\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_send_query_timeout\n--------------------------\n**syntax:** *drizzle_send_query_timeout \u0026lt;time\u0026gt;*\n\n**default:** *drizzle_send_query_timeout 60s*\n\n**context:** *http, server, location, location if*\n\nSpecify the (total) timeout for sending a SQL query to a remote Drizzle or MySQL server.\n\nThe `\u003ctime\u003e` argument can be an integer, with an optional time unit, like `s` (second), `ms` (millisecond), `m` (minute). The default time unit is `s`, ie, \"second\". The default setting is `60s`.\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_recv_cols_timeout\n-------------------------\n**syntax:** *drizzle_recv_cols_timeout \u0026lt;time\u0026gt;*\n\n**default:** *drizzle_recv_cols_timeout 60s*\n\n**context:** *http, server, location, location if*\n\nSpecify the (total) timeout for receiving the columns metadata of the result-set to a remote Drizzle or MySQL server.\n\nThe `\u003ctime\u003e` argument can be an integer, with an optional time unit, like `s` (second), `ms` (millisecond), `m` (minute). The default time unit is `s`, ie, \"second\". The default setting is `60s`.\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_recv_rows_timeout\n-------------------------\n**syntax:** *drizzle_recv_rows_timeout \u0026lt;time\u0026gt;*\n\n**default:** *drizzle_recv_rows_timeout 60s*\n\n**context:** *http, server, location, location if*\n\nSpecify the (total) timeout for receiving the rows data of the result-set (if any) to a remote Drizzle or MySQL server.\n\nThe `\u003ctime\u003e` argument can be an integer, with an optional time unit, like `s` (second), `ms` (millisecond), `m` (minute). The default time unit is `s`, ie, \"second\". The default setting is `60s`.\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_buffer_size\n-------------------\n**syntax:** *drizzle_buffer_size \u0026lt;size\u0026gt;*\n\n**default:** *drizzle_buffer_size 4k/8k*\n\n**context:** *http, server, location, location if*\n\nSpecify the buffer size for drizzle outputs. Default to the page size (4k/8k). The larger the buffer, the less streammy the outputing process will be.\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_module_header\n---------------------\n**syntax:** *drizzle_module_header on|off*\n\n**default:** *drizzle_module_header on*\n\n**context:** *http, server, location, location if*\n\nControls whether to output the drizzle header in the response. Default on.\n\nThe drizzle module header looks like this:\n\n\n    X-Resty-DBD-Module: ngx_drizzle 0.1.0\n\n\n[Back to TOC](#table-of-contents)\n\ndrizzle_status\n--------------\n**syntax:** *drizzle_status*\n\n**default:** *no*\n\n**context:** *location, location if*\n\n**phase:** *content*\n\nWhen specified, the current Nginx location will output a status report for all the drizzle upstream servers in the virtual server of the current Nginx worker process.\n\nThe output looks like this:\n\n    worker process: 15231\n\n    upstream backend\n      active connections: 0\n      connection pool capacity: 10\n      overflow: reject\n      cached connection queue: 0\n      free'd connection queue: 10\n      cached connection successfully used count:\n      free'd connection successfully used count: 3 0 0 0 0 0 0 0 0 0\n      servers: 1\n      peers: 1\n\n    upstream backend2\n      active connections: 0\n      connection pool capacity: 0\n      servers: 1\n      peers: 1\n\nNote that, this is *not* the global statistics if you do have multiple Nginx worker processes configured in your `nginx.conf`.\n\n[Back to TOC](#table-of-contents)\n\nVariables\n=========\n\nThis module creates the following Nginx variables:\n\n[Back to TOC](#table-of-contents)\n\n$drizzle_thread_id\n------------------\n\nThis variable will be assigned a textual number of the underlying MySQL or Drizzle query thread ID when the current SQL query times out. This thread ID can be further used in a SQL kill command to cancel the timed-out query.\n\nHere's an example:\n```nginx\n\n drizzle_connect_timeout 1s;\n drizzle_send_query_timeout 2s;\n drizzle_recv_cols_timeout 1s;\n drizzle_recv_rows_timeout 1s;\n\n location /query {\n     drizzle_query 'select sleep(10)';\n     drizzle_pass my_backend;\n     rds_json on;\n\n     more_set_headers -s 504 'X-Mysql-Tid: $drizzle_thread_id';\n }\n\n location /kill {\n     drizzle_query \"kill query $arg_tid\";\n     drizzle_pass my_backend;\n     rds_json on;\n }\n\n location /main {\n     content_by_lua '\n         local res = ngx.location.capture(\"/query\")\n         if res.status ~= ngx.HTTP_OK then\n             local tid = res.header[\"X-Mysql-Tid\"]\n             if tid and tid ~= \"\" then\n                 ngx.location.capture(\"/kill\", { args = {tid = tid} })\n             end\n             return ngx.HTTP_INTERNAL_SERVER_ERROR;\n         end\n         ngx.print(res.body)\n     '\n }\n```\nwhere we make use of [headers-more-nginx-module](http://github.com/openresty/headers-more-nginx-module), [lua-nginx-module](http://github.com/openresty/lua-nginx-module), and [rds-json-nginx-module](http://github.com/openresty/rds-json-nginx-module) too. When the SQL query timed out, we'll explicitly cancel it immediately. One pitfall here is that you have to add these modules in this order while building Nginx:\n\n* [lua-nginx-module](http://github.com/openresty/lua-nginx-module)\n* [headers-more-nginx-module](http://github.com/openresty/headers-more-nginx-module)\n* [rds-json-nginx-module](http://github.com/openresty/rds-json-nginx-module)\n\nSuch that, their output filters will work in the *reversed* order, i.e., first convert RDS to JSON, and then add our `X-Mysql-Tid` custom header, and finally capture the whole (subrequest) response with the Lua module. You're recommended to use the [OpenResty bundle](http://openresty.org/) though, it ensures the module building order automatically for you.\n\n[Back to TOC](#table-of-contents)\n\nOutput Format\n=============\n\nThis module generates binary query results in a format that is shared among the various Nginx database driver modules like [ngx_postgres](http://github.com/FRiCKLE/ngx_postgres/). This data format is named `Resty DBD Stream` (RDS).\n\nIf you're a web app developer, you may be more interested in\n\n* using [rds-json-nginx-module](http://github.com/openresty/rds-json-nginx-module) to obtain JSON output,\n* using [rds-csv-nginx-module](http://github.com/openresty/rds-csv-nginx-module) to obain Comma-Separated-Value (CSV) output,\n* or using [lua-rds-parser](http://github.com/openresty/lua-rds-parser) to parse the RDS data into Lua data structures.\n\nFor the HTTP response header part, the `200 OK` status code should always be returned. The `Content-Type` header *must* be set to `application/x-resty-dbd-stream`. And the driver generating this response also sets a `X-Resty-DBD` header. For instance, this module adds the following output header:\n\n    X-Resty-DBD-Module: drizzle 0.1.0\n\nwhere `0.1.0` is this module's own version number. This `X-Resty-DBD-Module` header is optional though.\n\nBelow is the HTTP response body format (version 0.0.3):\n\n[Back to TOC](#table-of-contents)\n\nRDS Header Part\n---------------\n\nThe RDS Header Part consists of the following fields:\n\n**uint8_t**\n\tendian type (1 means big-endian and little endian otherwise)\n\n**uint32_t**\n\tformat version (v1.2.3 is represented as 1002003 in decimal)\n\n**uint8_t**\n\tresult type (0 means normal SQL result type, fixed for now)\n\n**uint16_t**\n\tstandard error code\n\n**uint16_t**\n\tdriver-specific error code\n\n**uint16_t**\n\tdriver-specific error string length\n\n**u_char ***\n\tdriver-specific error string data\n\n**uint64_t**\n\tdatabase rows affected\n\n**uint64_t**\n\tinsert id (if none, 0)\n\n**uint16_t**\n\tcolumn count\n\n[Back to TOC](#table-of-contents)\n\nRDS Body Part\n-------------\n\nWhen the `column count` field in the [RDS Header Part](#rds-header-part) is zero, then the whole RDS Body Part is omitted.\n\nThe RDS Body Part consists of two sections, [Columns](#columns) and [Rows](#rows).\n\n### Columns\n\n\nThe columns part consists of zero or more column data. The number of columns is determined by `column count` field in [RDS Header Part](#rds-header-part).\n\nEach column consists of the following fields\n\n**uint16_t**\n\tnon-zero value for standard column type code and for the column list terminator and zero otherwise.\n\n**uint16_t**\n\tdriver-specific column type code\n\n**uint16_t**\n\tcolumn name length\n\n**u_char ***\n\tcolumn name data\n\n### Rows\n\n\nThe rows part consists of zero or more row data, terminated by a 8-bit zero.\n\nEach row data consists of a [Row Flag](#row-flag) and an optional [Fields Data](#fields-data) part.\n\n#### Row Flag\n\n\n**uint8_t**\n\tvalid row (1 means valid, and 0 means the row list terminator)\n\n#### Fields Data\n\n\nThe Fields Data consists zero or more fields of data. The field count is predetermined by the \u003ccode\u003ecolumn number\u003c/code) specified in [RDS Header Part](#rds-header-part).\n\n**uint32_t**\n\tfield length ((uint32_t) -1 represents NULL)\n\n**u_char ***\n\tfield data in textual representation), is empty (0) if field length == (uint32_t) -1\n\n[Back to TOC](#table-of-contents)\n\nRDS buffer Limitations\n----------------------\n\nOn the nginx output chain link level, the following components should be put into a single `ngx_buf_t` struct:\n\n* the header\n\n* each column and the column list terminator\n\n* each row's valid flag byte and row list terminator\n\n* each field in each row (if any) but the field data can span multiple bufs.\n\n[Back to TOC](#table-of-contents)\n\nStatus Code\n===========\n\nIf the MySQL error code in MySQL's query result is not OK, then a 500 error page is returned by this module, except for the table non-existent error, which results in the `410 Gone` error page.\n\n[Back to TOC](#table-of-contents)\n\nCaveats\n=======\n\n* Other usptream modules like `upstream_hash` and [HttpUpstreamKeepaliveModule](http://wiki.nginx.org/HttpUpstreamKeepaliveModule) *must not* be used with this module in a single upstream block.\n* Directives like [server](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server) *must not* be mixed with [drizzle_server](#drizzle_server) either.\n* Upstream backends that don't use [drizzle_server](#drizzle_server) to define server entries *must not* be used in the [drizzle_pass](#drizzle_pass) directive.\n\n[Back to TOC](#table-of-contents)\n\nTrouble Shooting\n================\n* When you see the following error message in `error.log`:\n\n        failed to connect: 15: drizzle_state_handshake_result_read:\n          old insecure authentication mechanism not supported in upstream, ...\n\n\tthen you may checkout if your MySQL is too old (at least 5.x is required) or your mysql config file explicitly forces the use of old authentication method (you should remove the `old-passwords` line from your `my.cnf` and add the line `secure_auth 1`).\n* When you see the following error message in `error.log`:\n\n        failed to connect: 23: Access denied for user 'root'@'ubuntu'\n          (using password: YES) while connecting to drizzle upstream, ...\n\n\tYou should check if your MySQL account does have got TCP login access on your MySQL server side. A quick check is to use MySQL's official client to connect to your server:\n```bash\n\n     mysql --protocol=tcp -u user --password=password -h foo.bar.com dbname\n```\n\tNote that the `--protocol=tcp` option is required here, or your MySQL client may use Unix Domain Socket to connect to your MySQL server.\n\n[Back to TOC](#table-of-contents)\n\nKnown Issues\n============\n\n* Calling mysql procedures are currently not supported because the underlying libdrizzle library does not support the `CLIENT_MULTI_RESULTS` flag yet :( But we'll surely work on it.\n* Multiple SQL statements in a single query are not supported due to the lack of `CLIENT_MULTI_STATEMENTS` support in the underlying libdrizzle library.\n* This module does not (yet) work with the `RTSIG` event model.\n\n[Back to TOC](#table-of-contents)\n\nInstallation\n============\nYou're recommended to install this module as well as [rds-json-nginx-module](http://github.com/openresty/rds-json-nginx-module) via the OpenResty bundle:\n\n\u003chttp://openresty.org\u003e\n\nThe installation steps are usually as simple as `./configure --with-http_drizzle_module \u0026\u0026 make \u0026\u0026 make install` (But you still need to install the libdrizzle library manually, see [\u003chttp://openresty.org/en/drizzle-nginx-module.html]\u003e(http://openresty.org/en/drizzle-nginx-module.html) for detailed instructions.\n\nAlternatively, you can compile this module with Nginx core's source by hand:\n\n* You should first install libdrizzle 1.0 which is now distributed with the drizzle project and can be obtained from [\u003chttps://launchpad.net/drizzle]\u003e(https://launchpad.net/drizzle). The latest drizzle7 release does not support building libdrizzle 1.0 separately and requires a lot of external dependencies like Boost and Protobuf which are painful to install. The last version supporting building libdrizzle 1.0 separately is `2011.07.21`. You can download it from \u003chttp://agentzh.org/misc/nginx/drizzle7-2011.07.21.tar.gz\u003e . Which this version of drizzle7, installation of libdrizzle 1.0 is usually as simple as\n```nginx\n\n     tar xzvf drizzle7-2011.07.21.tar.gz\n     cd drizzle7-2011.07.21/\n     ./configure --without-server\n     make libdrizzle-1.0\n     make install-libdrizzle-1.0\n```\n\tEnsure that you have the `python` command point to a `python2` interpreter. It's known that on recent : Arch Linux distribution, `python` is linked to `python3` by default, and while running `make libdrizzle-1.0` will yield the error\n```bash\n\n     File \"config/pandora-plugin\", line 185\n         print \"Dependency loop detected with %s\" % plugin['name']\n                                                  ^\n     SyntaxError: invalid syntax\n     make: *** [.plugin.scan] Error 1\n```\n\tYou can fix this by pointing `python` to `python2`.\n* Download the latest version of the release tarball of this module from drizzle-nginx-module [file list](http://github.com/openresty/drizzle-nginx-module/tags).\n* Grab the nginx source code from [nginx.org](http://nginx.org/), for example, the version 1.13.6 (see [nginx compatibility](#compatibility)), and then build the source with this module:\n```bash\n\n     wget 'http://nginx.org/download/nginx-1.13.6.tar.gz'\n     tar -xzvf nginx-1.13.6.tar.gz\n     cd nginx-1.13.6/\n\n     # if you have installed libdrizzle to the prefix /opt/drizzle, then\n     # specify the following environments:\n     # export LIBDRIZZLE_INC=/opt/drizzle/include/libdrizzle-1.0\n     # export LIBDRIZZLE_LIB=/opt/drizzle/lib\n\n     # Here we assume you would install you nginx under /opt/nginx/.\n     ./configure --prefix=/opt/nginx \\\n                 --add-module=/path/to/drizzle-nginx-module\n\n     make -j2\n     make install\n```\n\nYou usually also need [rds-json-nginx-module](http://github.com/openresty/rds-json-nginx-module) to obtain JSON output from the binary RDS output generated by this upstream module.\n\n[Back to TOC](#table-of-contents)\n\nCompatibility\n=============\n\nIf you're using MySQL, then MySQL `5.0 ~ 5.5` is required. We're not sure if MySQL `5.6+` work; reports welcome!\n\nThis module has been tested on Linux and Mac OS X. Reports on other POSIX-compliant systems will be highly appreciated.\n\nThe following versions of Nginx should work with this module:\n\n* 1.16.x\n* 1.15.x    (last tested: 1.15.8)\n* 1.14.x\n* 1.13.x    (last tested: 1.13.6)\n* 1.12.x\n* 1.11.x    (last tested: 1.11.2)\n* 1.10.x\n* 1.9.x     (last tested: 1.9.15)\n* 1.8.x\n* 1.7.x     (last tested: 1.7.10)\n* 1.6.x\n* 1.5.x     (last tested: 1.5.8)\n* 1.4.x     (last tested: 1.4.4)\n* 1.3.x     (last tested: 1.3.7)\n* 1.2.x     (last tested: 1.2.9)\n* 1.1.x     (last tested: 1.1.5)\n* 1.0.x     (last tested: 1.0.8)\n* 0.8.x     (last tested: 0.8.55)\n* 0.7.x \u003e= 0.7.44 (last tested version is 0.7.67)\n\nEarlier versions of Nginx like `0.6.x` and `0.5.x` will *not* work.\n\nIf you find that any particular version of Nginx above `0.7.44` does not work with this module, please consider reporting a bug.\n\n[Back to TOC](#table-of-contents)\n\nCommunity\n=========\n\n[Back to TOC](#table-of-contents)\n\nEnglish Mailing List\n--------------------\n\nThe [openresty-en](https://groups.google.com/group/openresty-en) mailing list is for English speakers.\n\n[Back to TOC](#table-of-contents)\n\nChinese Mailing List\n--------------------\n\nThe [openresty](https://groups.google.com/group/openresty) mailing list is for Chinese speakers.\n\n[Back to TOC](#table-of-contents)\n\nReport Bugs\n===========\n\nPlease submit bug reports, wishlists, or patches by\n\n1. creating a ticket on the [issue tracking interface](http://github.com/openresty/drizzle-nginx-module/issues) provided by GitHub,\n1. or sending an email to the [OpenResty community](#community).\n\n[Back to TOC](#table-of-contents)\n\nSource Repository\n=================\n\nAvailable on github at [openresty/drizzle-nginx-module](http://github.com/openresty/drizzle-nginx-module).\n\n[Back to TOC](#table-of-contents)\n\nTest Suite\n==========\n\nThis module comes with a Perl-driven test suite. The [test cases](http://github.com/openresty/drizzle-nginx-module/tree/master/t/) are\n[declarative](http://github.com/openresty/drizzle-nginx-module/blob/master/t/sanity.t) too. Thanks to the [Test::Nginx](http://search.cpan.org/perldoc?Test::Nginx) module in the Perl world.\n\nTo run it on your side:\n\n```bash\n\n $ PATH=/path/to/your/nginx-with-echo-module:$PATH prove -r t\n```\n\nBecause a single nginx server (by default, `localhost:1984`) is used across all the test scripts (`.t` files), it's meaningless to run the test suite in parallel by specifying `-jN` when invoking the `prove` utility.\n\n[Back to TOC](#table-of-contents)\n\nTODO\n====\n* add the MySQL transaction support.\n* add multi-statement MySQL query support.\n* implement the \"drizzle_max_output_size\" directive. When the RDS data is larger then the size specified, the module will try to terminate the output as quickly as possible but will still ensure the resulting response body is still in valid RDS format.\n* implement the `drizzle_upstream_next` mechanism for failover support.\n* add support for multiple \"drizzle_query\" directives in a single location.\n* implement *weighted* round-robin algorithm for the upstream server clusters.\n* add the `max_idle_time` option to the [drizzle_server](#drizzle_server) directive, so that the connection pool will automatically release idle connections for the timeout you specify.\n* add the `min` option to the \"drizzle_server\" directive so that the connection pool will automatically create that number of connections and put them into the pool.\n* add Unix domain socket support in the `drizzle_server` directive.\n* make the [drizzle_query](#drizzle_query) directive reject variables that have not been processed by a [drizzle_process](#drizzle_process) directive. This will pretect us from SQL injections. There will also be an option (\"strict=no\") to disable such checks.\n\n[Back to TOC](#table-of-contents)\n\nChanges\n=======\n\nThe changes of every release of this module can be obtained from the OpenResty bundle's change logs:\n\n\u003chttp://openresty.org/#Changes\u003e\n\n[Back to TOC](#table-of-contents)\n\nAuthors\n=======\n\n* chaoslawful (王晓哲) \u003cchaoslawful at gmail dot com\u003e\n* Yichun \"agentzh\" Zhang (章亦春) \u003cagentzh at gmail dot com\u003e, OpenResty Inc.\n* Piotr Sikora \u003cpiotr.sikora at frickle dot com\u003e, Google Inc.\n\n[Back to TOC](#table-of-contents)\n\nCopyright \u0026 License\n===================\n\nThis module is licenced under the BSD license.\n\nCopyright (C) 2009-2014, by Xiaozhe Wang (chaoslawful) \u003cchaoslawful@gmail.com\u003e.\n\nCopyright (C) 2009-2018, by Yichun \"agentzh\" Zhang (章亦春) \u003cagentzh@gmail.com\u003e, OpenResty Inc.\n\nCopyright (C) 2010-2014, by FRiCKLE Piotr Sikora \u003cinfo@frickle.com\u003e, Google Inc.\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n[Back to TOC](#table-of-contents)\n\nSee Also\n========\n\n* [rds-json-nginx-module](http://github.com/openresty/rds-json-nginx-module)\n* [rds-csv-nginx-module](http://github.com/openresty/rds-csv-nginx-module)\n* [lua-rds-parser](http://github.com/openresty/lua-rds-parser)\n* [The OpenResty bundle](http://openresty.org)\n* [DrizzleNginxModule bundled by OpenResty](http://openresty.org/#DrizzleNginxModule)\n* [postgres-nginx-module](http://github.com/FRiCKLE/ngx_postgres)\n* [lua-nginx-module](http://github.com/openresty/lua-nginx-module)\n* The [lua-resty-mysql](https://github.com/openresty/lua-resty-mysql) library based on the [lua-nginx-module](http://github.com/openresty/lua-nginx-module) cosocket API.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenresty%2Fdrizzle-nginx-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenresty%2Fdrizzle-nginx-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenresty%2Fdrizzle-nginx-module/lists"}