@@ -1,6 +1,7 @@
|
|||||||
"""Database related tools."""
|
"""Database related tools."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import pwd
|
import pwd
|
||||||
import stat
|
import stat
|
||||||
|
|
||||||
@@ -124,32 +125,51 @@ class MySQL(Database):
|
|||||||
"""MySQL backend."""
|
"""MySQL backend."""
|
||||||
|
|
||||||
packages = {
|
packages = {
|
||||||
"deb": ["mysql-server", "libmysqlclient-dev"],
|
"deb": ["mariadb-server"],
|
||||||
"rpm": ["mariadb", "mariadb-devel", "mariadb-server"],
|
"rpm": ["mariadb", "mariadb-devel", "mariadb-server"],
|
||||||
}
|
}
|
||||||
service = "mariadb" if package.backend.FORMAT == "rpm" else "mysql"
|
service = "mariadb"
|
||||||
|
|
||||||
|
def _escape(self, query):
|
||||||
|
"""Replace special characters."""
|
||||||
|
return query.replace("'", "'\"'\"'")
|
||||||
|
|
||||||
def install_package(self):
|
def install_package(self):
|
||||||
"""Preseed package installation."""
|
"""Preseed package installation."""
|
||||||
package.backend.preconfigure(
|
name, version, _id = platform.linux_distribution()
|
||||||
"mysql-server", "root_password", "password", self.dbpassword)
|
if name == "debian":
|
||||||
package.backend.preconfigure(
|
mysql_name = "mysql" if version.startswith("8") else "mariadb"
|
||||||
"mysql-server", "root_password_again", "password", self.dbpassword)
|
self.packages["deb"].append("lib{}client-dev".format(mysql_name))
|
||||||
super(MySQL, self).install_package()
|
super(MySQL, self).install_package()
|
||||||
if package.backend.FORMAT == "rpm":
|
if name == "debian" and version.startswith("8"):
|
||||||
utils.exec_cmd("mysqladmin -u root password '{}'".format(
|
package.backend.preconfigure(
|
||||||
self.dbpassword))
|
"mariadb-server", "root_password", "password",
|
||||||
|
self.dbpassword)
|
||||||
|
package.backend.preconfigure(
|
||||||
|
"mariadb-server", "root_password_again", "password",
|
||||||
|
self.dbpassword)
|
||||||
|
else:
|
||||||
|
queries = [
|
||||||
|
"UPDATE user SET plugin='' WHERE user='root'",
|
||||||
|
"UPDATE user SET password=PASSWORD('{}') WHERE USER='root'"
|
||||||
|
.format(self.dbpassword),
|
||||||
|
"flush privileges"
|
||||||
|
]
|
||||||
|
for query in queries:
|
||||||
|
utils.exec_cmd(
|
||||||
|
"mysql -D mysql -e '{}'".format(self._escape(query)))
|
||||||
|
|
||||||
def _exec_query(self, query, dbname=None, dbuser=None, dbpassword=None):
|
def _exec_query(self, query, dbname=None, dbuser=None, dbpassword=None):
|
||||||
"""Exec a mysql query."""
|
"""Exec a mysql query."""
|
||||||
if dbuser is None and dbpassword is None:
|
if dbuser is None and dbpassword is None:
|
||||||
dbuser = self.dbuser
|
dbuser = self.dbuser
|
||||||
dbpassword = self.dbpassword
|
dbpassword = self.dbpassword
|
||||||
cmd = "mysql -h {} -u {} -p{}".format(self.dbhost, dbuser, dbpassword)
|
cmd = "mysql -h {} -u {}".format(self.dbhost, dbuser)
|
||||||
|
if dbpassword:
|
||||||
|
cmd += " -p{}".format(dbpassword)
|
||||||
if dbname:
|
if dbname:
|
||||||
cmd += " -D {}".format(dbname)
|
cmd += " -D {}".format(dbname)
|
||||||
query = query.replace("'", "'\"'\"'")
|
utils.exec_cmd(cmd + """ -e '{}' """.format(self._escape(query)))
|
||||||
utils.exec_cmd(cmd + """ -e '{}' """.format(query))
|
|
||||||
|
|
||||||
def create_user(self, name, password):
|
def create_user(self, name, password):
|
||||||
"""Create a user."""
|
"""Create a user."""
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ CREATE TABLE policy (
|
|||||||
-- SELECT COUNT(*) FROM T statement, InnoDB must scan an index of the table,
|
-- SELECT COUNT(*) FROM T statement, InnoDB must scan an index of the table,
|
||||||
-- which takes some time if the index is not entirely in the buffer pool.
|
-- which takes some time if the index is not entirely in the buffer pool.
|
||||||
--
|
--
|
||||||
-- Wayne Smith adds: When using MySQL with InnoDB one might want to
|
-- Wayne Smith adds: When using MySQL with InnoDB one might want to
|
||||||
-- increase buffer size for both pool and log, and might also want
|
-- increase buffer size for both pool and log, and might also want
|
||||||
-- to change flush settings for a little better performance. Example:
|
-- to change flush settings for a little better performance. Example:
|
||||||
-- innodb_buffer_pool_size = 384M
|
-- innodb_buffer_pool_size = 384M
|
||||||
@@ -157,22 +157,22 @@ CREATE TABLE msgs (
|
|||||||
dsn_sent char(1), -- was DSN sent? Y/N/q (q=quenched)
|
dsn_sent char(1), -- was DSN sent? Y/N/q (q=quenched)
|
||||||
spam_level float, -- SA spam level (no boosts)
|
spam_level float, -- SA spam level (no boosts)
|
||||||
message_id varchar(255) DEFAULT '', -- mail Message-ID header field
|
message_id varchar(255) DEFAULT '', -- mail Message-ID header field
|
||||||
from_addr varchar(255) CHARACTER SET utf8mb4 COLLATE utf8_bin DEFAULT '',
|
from_addr varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '',
|
||||||
-- mail From header field, UTF8
|
-- mail From header field, UTF8
|
||||||
subject varchar(255) CHARACTER SET utf8mb4 COLLATE utf8_bin DEFAULT '',
|
subject varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '',
|
||||||
-- mail Subject header field, UTF8
|
-- mail Subject header field, UTF8
|
||||||
host varchar(255) NOT NULL, -- hostname where amavisd is running
|
host varchar(255) NOT NULL, -- hostname where amavisd is running
|
||||||
PRIMARY KEY (partition_tag,mail_id)
|
PRIMARY KEY (partition_tag,mail_id),
|
||||||
FOREIGN KEY (sid) REFERENCES maddr(id) ON DELETE RESTRICT
|
FOREIGN KEY (sid) REFERENCES maddr(id) ON DELETE RESTRICT
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
CREATE INDEX msgs_idx_sid ON msgs (sid);
|
CREATE INDEX msgs_idx_sid ON msgs (sid);
|
||||||
CREATE INDEX msgs_idx_mess_id ON msgs (message_id); -- useful with pen pals
|
CREATE INDEX msgs_idx_mess_id ON msgs (message_id); -- useful with pen pals
|
||||||
CREATE INDEX msgs_idx_time_num ON msgs (time_num);
|
CREATE INDEX msgs_idx_time_num ON msgs (time_num);
|
||||||
-- alternatively when purging based on time_iso (instead of msgs_idx_time_num):
|
-- alternatively when purging based on time_iso (instead of msgs_idx_time_num):
|
||||||
-- CREATE INDEX msgs_idx_time_iso ON msgs (time_iso);
|
CREATE INDEX msgs_idx_time_iso ON msgs (time_iso);
|
||||||
-- When using FOREIGN KEY contraints, InnoDB requires index on a field
|
-- When using FOREIGN KEY contraints, InnoDB requires index on a field
|
||||||
-- (an the field must be the first field in the index). Hence create it:
|
-- (an the field must be the first field in the index). Hence create it:
|
||||||
-- CREATE INDEX msgs_idx_mail_id ON msgs (mail_id);
|
CREATE INDEX msgs_idx_mail_id ON msgs (mail_id);
|
||||||
|
|
||||||
-- per-recipient information related to each processed message;
|
-- per-recipient information related to each processed message;
|
||||||
-- NOTE: records in msgrcpt without corresponding msgs.mail_id record are
|
-- NOTE: records in msgrcpt without corresponding msgs.mail_id record are
|
||||||
@@ -191,12 +191,14 @@ CREATE TABLE msgrcpt (
|
|||||||
wl char(1) DEFAULT ' ', -- sender whitelisted by this recip
|
wl char(1) DEFAULT ' ', -- sender whitelisted by this recip
|
||||||
bspam_level float, -- per-recipient (total) spam level
|
bspam_level float, -- per-recipient (total) spam level
|
||||||
smtp_resp varchar(255) DEFAULT '', -- SMTP response given to MTA
|
smtp_resp varchar(255) DEFAULT '', -- SMTP response given to MTA
|
||||||
PRIMARY KEY (partition_tag,mail_id,rseqnum)
|
PRIMARY KEY (partition_tag,mail_id,rseqnum),
|
||||||
FOREIGN KEY (rid) REFERENCES maddr(id) ON DELETE RESTRICT,
|
FOREIGN KEY (rid) REFERENCES maddr(id) ON DELETE RESTRICT,
|
||||||
FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
|
FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
|
CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
|
||||||
CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
|
CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
|
||||||
|
-- Additional index on rs since Modoboa uses it to filter its quarantine
|
||||||
|
CREATE INDEX msgrcpt_idx_rs ON msgrcpt (rs);
|
||||||
|
|
||||||
-- mail quarantine in SQL, enabled by $*_quarantine_method='sql:'
|
-- mail quarantine in SQL, enabled by $*_quarantine_method='sql:'
|
||||||
-- NOTE: records in quarantine without corresponding msgs.mail_id record are
|
-- NOTE: records in quarantine without corresponding msgs.mail_id record are
|
||||||
@@ -206,6 +208,6 @@ CREATE TABLE quarantine (
|
|||||||
mail_id varbinary(16) NOT NULL, -- long-term unique mail id
|
mail_id varbinary(16) NOT NULL, -- long-term unique mail id
|
||||||
chunk_ind integer unsigned NOT NULL, -- chunk number, starting with 1
|
chunk_ind integer unsigned NOT NULL, -- chunk number, starting with 1
|
||||||
mail_text blob NOT NULL, -- store mail as chunks of octets
|
mail_text blob NOT NULL, -- store mail as chunks of octets
|
||||||
PRIMARY KEY (partition_tag,mail_id,chunk_ind)
|
PRIMARY KEY (partition_tag,mail_id,chunk_ind),
|
||||||
FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
|
FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
|
|||||||
@@ -173,6 +173,8 @@ CREATE TABLE msgrcpt (
|
|||||||
);
|
);
|
||||||
CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
|
CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
|
||||||
CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
|
CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
|
||||||
|
-- Additional index on rs since Modoboa uses it to filter its quarantine
|
||||||
|
CREATE INDEX msgrcpt_idx_rs ON msgrcpt (rs);
|
||||||
|
|
||||||
-- mail quarantine in SQL, enabled by $*_quarantine_method='sql:'
|
-- mail quarantine in SQL, enabled by $*_quarantine_method='sql:'
|
||||||
-- NOTE: records in quarantine without corresponding msgs.mail_id record are
|
-- NOTE: records in quarantine without corresponding msgs.mail_id record are
|
||||||
|
|||||||
Reference in New Issue
Block a user