启动数据库服务
启动数据库服务¶
在任何人可以访问数据库前,必须启动数据库服务。
数据库服务程序是seaboxsql
,它必须知道在哪里能找到它要用的数据。这是用-D
选项实现的。 因此,启动服务最简单的方法是:
$ seaboxsql -D /usr/local/sdsql/data
这将把服务放在前台运行。这个步骤同样必须以SeaboxSQL用户帐户登录来操作。如果没有-D
选项,服务将尝试使用环境变量SDDATA
命名的目录。如果这个环境变量也没有提供则导致失败。
通常最好在后台启动seaboxsql
。要这样做,使用常用的 Unix shell 语法:
$ seaboxsql -D /usr/local/sdsql/data >logfile 2>&1 &
如上所示,把服务的stdout和stderr输出存储到某个地方是非常重要的。这将对审计目的和诊断问题有所帮助(更深入的有关日志文件处理的讨论请见(日志文件维护)。
seaboxsql
还接受其它一些命令行选项。更多的信息请见seaboxsql参考页和下面的服务配置。
我们提供了包装器程序sd_ctl
以简化一些任务。例如:
sd_ctl start -l logfile
将在后台启动服务并且把输出放到指定的日志文件中。-D
选项和seaboxsql
中的一样。sd_ctl
还可以用于停止服务。
通常,你会希望在计算机启动的时候启动数据库服务。自动启动脚本是操作系统相关的。SeaboxSQL在contrib/start-scripts
目录中提供了几种。安装将需要root 权限。
不同的系统在引导时有不同的启动守护进程的习惯。许多系统有一个文件/etc/rc.local
或/etc/rc.d/rc.local
。其他的使用init.d
或rc.d
目录。不管你做什么,服务必须由SeaboxSQL用户账户 而不是root 或任何其他用户启动。因此你可能应该在你的命令中使用su seaboxs -c '...'
这种形式。例如:
su seaboxsql -c 'sd_ctl start -D /usr/local/sdsql/data -l serverlog'
下面是一些更加与操作系统相关的建议(在每一种情况中要确保在我们展示通用值的地方使用正确的安装目录和用户名)。
在Linux系统上将
/usr/local/sdsql/bin/sd_ctl start -l logfile -D /usr/local/sdsql/data
加入到/etc/rc.d/rc.local
或/etc/rc.local
中。
在使用systemd时,可以使用下面的服务单元文件(例如/etc/systemd/system/seaboxsql.service
):
[Unit]
Description=SeaboxSQL database server
Documentation=man:seaboxs(1)
[Service]
Type=notify
User=seaboxs
ExecStart=/usr/local/sdsql/bin/seaboxs -D /usr/local/sdsql/data
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=0
[Install]
WantedBy=multi-user.target
要仔细地考虑超时设置。在写作这份文档时,systemd的默认超时时长是90秒,并且将会杀死没有在这段时间内报告准备好的进程。但是SeaboxSQL服务可能因为执行崩溃恢复而导致启动过程大大超过这个默认时间。建议的值是0,即禁用超时逻辑。
当服务在运行时,它的PID被保存在数据目录中的seaboxmaster.pid
文件。这样做可以防止多个服务实例运行在同一个数据目录中,并且也可以被用来关闭服务。
服务启动失败¶
有几个常见的原因会导致服务启动失败。通过检查服务日志或使用手工启动的方法(不做标准输出或标准错误的重定向),就可以看到出现什么错误消息。下面我们详细地解释一些最常见的错误消息。
LOG: could not bind IPv4 address "127.0.0.1": Address already in use
HINT: Is another seaboxmaster already running on port 7300? If not, wait a few seconds and retry.
FATAL: could not create any TCP/IP sockets
正如这个消息所说的,这表示:你试图在一个已经有服务运行着的端口上再启动另一个服务。不过,如果核心错误消息不是Address already in use
或其变体,那就有可能是别的问题。 例如,试图在一个被保留的端口上启动服务会收到下面这样的消息:
$ seaboxsql -p 666
LOG: could not bind IPv4 address "127.0.0.1": Permission denied
HINT: Is another seaboxmaster already running on port 666? If not, wait a few seconds and retry.
FATAL: could not create any TCP/IP sockets
像这样的消息:
FATAL: could not create shared memory segment: Invalid argument
DETAIL: Failed system call was shmget(key=5440001, size=4011376640, 03600).
可能意味着你的内核对共享内存区的限制小于SeaboxSQL试图创建的工作区域(本例中是4011376640 字节)。或者可能意味着根本就没有 System V 风格的共享内存支持被配置在你的内核中。作为一种临时的解决方案,你可以试着以小于正常数量的缓冲区(shared_buffers
)启动服务。
你最终还是会希望重新配置内核以增加共享内存允许的尺寸。当你试图在同一台机器上启动多个服务,并且它们所需的总空间超过了内核的限制,也会报这个错。
一个这样的错误:
FATAL: could not create semaphores: No space left on device
DETAIL: Failed system call was semget(5440126, 17, 03600).
并不意味着你已经用光了磁盘空间。它的意思是你的内核对System V信号量的限制小于SeaboxSQL想创建的数量。和上面一样,你可以通过减少允许的连接数(max_connections
)来绕开这个限制,但最终你还是会希望提高内核的限制。
如果你收到一个“illegal system call”错误,那么很有可能是你的内核根本不支持共享内存或者信号量。这种情况下你唯一的选择就是重新配置内核并且把这些特性打开。
关于配置System V IPC功能的细节请见共享内存和信号量。
客户端连接问题**¶
尽管可能在客户端出现的错误情况范围宽广而且是应用相关的,但的确有几种与服务的启动方式直接相关。除了下面提到的几种错误之外的问题都应该在相应的客户端应用文档中。
ssql: could not connect to server: Connection refused
Is the server running on host "server.joe.com" and accepting
TCP/IP connections on port 7300?
这是常见的“I couldn't find a server to talk to”失败。上面的情况看起来是发生在尝试 TCP/IP 通信时。常见的错误是忘记把服务配置成允许 TCP/IP 连接。
另外,当试图通过 Unix 域套接字与本地服务通信时,你会看到这个:
ssql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.SDSQL.7300"?
最后一行可以验证客户端是不是尝试连接到正确的位置。如果实际上没有服务在那里运行,典型的核心错误消息将是Connection refused
或No such file or directory
(值得注意的是这种环境中的Connection refused
并不表示服务得到了你的连接请求并拒绝了它。那种情况会产生一个不同的消息,如认证问题中所示)。其它像Connection timed out
这样的消息可能表示更基础的问题,如缺少网络连接。