Wietse Venema via Postfix-users:
> > My conclusion to hard-solve this issue on my system is transform all
> > tables to utf8mb4.
> >
> > But:
> > - I don't see any option to change default charset on mysql_table
> > connector, maybe should be interesting add this option on configuration
> > file.
>
> Is there such an API?
Based on documentation, perhaps mysql_set_character_set() can do that.
https://dev.mysql.com/doc/c-api/8.0/en/mysql-set-character-set.html
Attached is patch 20230417-mysql-charset-patch.txt that adds a
"charset" parameter to the Postfix MySQL configuration file.
I don't have a MySQL testbed; someone else would have to test this,
or this would have to wait until I have time to set up MySQL.
> > - mix collation error should raise 1 error, but next queries should be
> > work ok, this could be considered and issue right?.
>
> For the Postfix MySQL client the expected result of a query is:
>
> - found,
>
> - not found,
>
> - error.
>
> The client does not distinguish between errors, and all errors have
> the same result (skip this connection for 60s). That code is almost
> 20 years old, so I wonder if you are doing something unusal that
> other people aren't doing.
>
> Based on https://dev.mysql.com/doc/c-api/8.0/en/mysql-next-result.html
> I suppose that the client could distinguish between
> errors that indicate a connection error and other errors. But that
> would be a major code change.
It is possible to distinguish between errors without having tp
restructure code.
Attached is patch 20230417-mysql-retry-patch.txt that more selectively
backs off from a server connection.
Again if someone else can test this, great, otherwise this will
have to wait.
Wietse
20230417
Cleanup: in the MySQL client, temporarily stay away from a
server only if the last error was caused by connection-level
failure. File: global/dict_mysql.c.
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur
/var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c ./src/global/dict_mysql.c
--- /var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c 2023-04-16
16:44:39.000000000 -0400
+++ ./src/global/dict_mysql.c 2023-04-17 11:07:47.000000000 -0400
@@ -108,6 +108,7 @@
/* Application-specific. */
#include "dict_mysql.h"
+#include "mysql/errmsg.h"
/* MySQL 8.x API change */
@@ -546,7 +547,14 @@
* See what we got.
*/
if (query_error) {
- plmysql_down_host(host);
+ switch (mysql_errno(host->db)) {
+ case CR_COMMANDS_OUT_OF_SYNC:
+ case CR_SERVER_GONE_ERROR:
+ case CR_SERVER_LOST:
+ plmysql_down_host(host);
+ default:
+ break;
+ }
if (errno == 0)
errno = ENOTSUP;
if (first_result) {
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur
/var/tmp/postfix-3.9-20230416/HISTORY ./HISTORY
--- /var/tmp/postfix-3.9-20230416/HISTORY 2023-04-16 17:09:29.000000000
-0400
+++ ./HISTORY 2023-04-17 11:01:00.531589777 -0400
@@ -27055,3 +27055,9 @@
Cleanup: in source-code comments, replaced redundant (and
sometimes incomplete) lookup table configuration info with
a reference to the corresponding *_table(5) manpage.
+
+20230417
+
+ Cleanup: in the MySQL client, make the default characterset
+ (and collation) configurable (the MySQL defaults are latin1
+ and latin1_swedish_ci). File: global/dict_mysql.c.
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur
/var/tmp/postfix-3.9-20230416/proto/mysql_table ./proto/mysql_table
--- /var/tmp/postfix-3.9-20230416/proto/mysql_table 2022-12-27
18:01:00.000000000 -0500
+++ ./proto/mysql_table 2023-04-17 11:24:16.000000000 -0400
@@ -79,6 +79,11 @@
# .nf
# dbname = customer_database
# .fi
+# .IP "\fBcharset\fR (empty for backwards compatibility)"
+# The default client character set (and implicitly, the
+# collation order). According to MySQL documentation the
+# built-in default is "latin1"; for SMTP, "utf8" would be
+# more appropriate.
# .IP "\fBquery\fR"
# The SQL query template used to search the database, where \fB%s\fR
# is a substitute for the address Postfix is trying to resolve,
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur
/var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c ./src/global/dict_mysql.c
--- /var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c 2023-04-16
16:44:39.000000000 -0400
+++ ./src/global/dict_mysql.c 2023-04-17 11:09:35.000000000 -0400
@@ -147,6 +147,7 @@
char *username;
char *password;
char *dbname;
+ char *charset;
ARGV *hosts;
PLMYSQL *pldb;
#if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 40000
@@ -602,6 +603,13 @@
host->port,
(host->type == TYPEUNIX ? host->name : 0),
CLIENT_MULTI_RESULTS)) {
+ if (*dict_mysql->charset != 0
+ && mysql_set_character_set(host->db, dict_mysql->charset) != 0) {
+ msg_warn("dict_mysql: mysql_set_character_set '%s' failed: %s",
+ dict_mysql->charset, mysql_error(host->db));
+ plmysql_down_host(host);
+ return;
+ }
if (msg_verbose)
msg_info("dict_mysql: successful connection to host %s",
host->hostname);
@@ -646,6 +654,7 @@
dict_mysql->username = cfg_get_str(p, "user", "", 0, 0);
dict_mysql->password = cfg_get_str(p, "password", "", 0, 0);
dict_mysql->dbname = cfg_get_str(p, "dbname", "", 1, 0);
+ dict_mysql->charset = cfg_get_str(p, "charset", "", 1, 0);
dict_mysql->result_format = cfg_get_str(p, "result_format", "%s", 1, 0);
dict_mysql->option_file = cfg_get_str(p, "option_file", NULL, 0, 0);
dict_mysql->option_group = cfg_get_str(p, "option_group", "client", 0, 0);
@@ -826,6 +835,7 @@
myfree(dict_mysql->username);
myfree(dict_mysql->password);
myfree(dict_mysql->dbname);
+ myfree(dict_mysql->charset);
myfree(dict_mysql->query);
myfree(dict_mysql->result_format);
if (dict_mysql->option_file)
_______________________________________________
Postfix-users mailing list -- [email protected]
To unsubscribe send an email to [email protected]