Can I change the global port number without my.cnf file? - mysql

I made the following mysql container in the docker.
docker run -p 3307:3307 --name todolist -e MYSQL_ROOT_PASSWORD=1234 -e MYSQL_DATABASE=todolist -e MYSQL_USER=allssu -e MYSQL_PASSWORD=1234 -d mysql
However, I confirmed that the port of mysql on the docker is still 3306. So I tried to modify the port number in the my.cnf file in the /etc/mysql path. But, only the conf.d file exists in the /etc/mysql folder, and there is no my.cnf file.
To make matters worse, an error occurs in my bash that the apt-get command does not work.
bash-4.4# apt-get update
bash: apt-get: command not found
bash-4.4# apt-get install vim
bash: apt-get: command not found
First, I want to find the invisible my.cnf file in the etc/mysql folder. Also I want to set the port of this container(name:todolist) to 3307, is there any way?
And, I want to use the vi command in bash.
I would appreciate it if you could consider this matter together.

I tried the following and still couldn't find my.cnf.
bash-4.4# mysqld --verbose --help | grep -A 1 'Default options'
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
result:
bash-4.4# pwd
/etc/mysql
bash-4.4# ls
conf.d

Related

MySQL Docker file : sed: couldn't open temporary file

I am trying to create new MySQL image and deploying in Kubernetes.
FROM oraclelinux:7-slim
USER root
ARG MYSQL_SERVER_PACKAGE=mysql-community-server-minimal-8.0.19
ARG MYSQL_SHELL_PACKAGE=mysql-shell-8.0.19
# Install server
RUN yum install -y https://repo.mysql.com/mysql-community-minimal-release-el7.rpm \
https://repo.mysql.com/mysql-community-release-el7.rpm \
&& yum-config-manager --enable mysql80-server-minimal \
&& yum install -y \
$MYSQL_SERVER_PACKAGE \
$MYSQL_SHELL_PACKAGE \
libpwquality \
&& yum clean all \
&& mkdir /docker-entrypoint-initdb.d
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /entrypoint.sh
COPY healthcheck.sh /healthcheck.sh
ENTRYPOINT ["/entrypoint.sh"]
HEALTHCHECK CMD /healthcheck.sh
EXPOSE 3306 33060
RUN chmod +rwx /entrypoint.sh
RUN chmod +rwx /healthcheck.sh
RUN groupadd -r mysql && useradd -r -g mysql mysql
EXPOSE 3306
CMD ["mysqld"]
It's working fine in the container. But throwing error when I deployed in Kubernetes like below:
How can I understand this issue?
ADDED
docker-entrypoint.sh:
if [ -n "$MYSQL_LOG_CONSOLE" ] || [ -n "console" ]; then
# Don't touch bind-mounted config files
if ! cat /proc/1/mounts | grep "/etc/my.cnf"; then
sed -i 's/^log-error=/#&/' /etc/my.cnf
fi
fi
P.S : I have added content of the file.
The problem is related with sed's in-place editing implementation. When you edit a file using the -i or --in-place option, the edition doesn't actually happen in-place. sed saves the changes into a temporary file and then uses it to replace the original one.
It happens that you don't have write permission to /etc directory, where sed is trying to create its temporary file.
As suggested in comments most probably the command is run by user mysql. For sure it is not run as root as it has enough privileges to be able to write to /etc:
bash-4.2# ls -ld /etc
drwxr-xr-x 1 root root 4096 Mar 27 15:04 /etc
As you can see others don't have write permission. Changing permissions or owner of /etc directory itself is a really bad idea and I won't advise you to run this command as root user either.
The simplest solution is to give up on using --in-place option, save the result in a directory such as /tmp, to which everyone has access:
bash-4.2# ls -ld /tmp
drwxrwxrwt 1 root root 4096 Mar 27 16:39 /tmp
and after that replace the content of the original file with the content of the temporary one.
Your command may look like this:
sed 's/^log-error=/#&/' /etc/my.cnf > /tmp/my.cnf && cat /tmp/my.cnf > /etc/my.cnf
One important caveat:
You need to make sure you have write permission on /etc/my.cnf file. As you can see below, by default you don't have such permission either, so the error will occur later, when the command will try to write to the original config file.
bash-4.2# ls -l /etc/my.cnf
-rw-r--r-- 1 root root 1239 Mar 27 15:04 /etc/my.cnf
You need to modify it in your Dockerfile either by making it availeble for edit by everyone:
RUN chmod 666 /etc/my.cnf
or better option:
RUN chown mysql /etc/my.cnf
to change its owner to mysql, if this is the user that executes the entrypoint.sh script.
Please let me know if it helps.

Reinstall MySQL (mariadb) in Debian Stretch

I removed mysql completely including configuration files and when I try to reinstall, there is no mysql.socket (I searched in /var/lib/mysql/ and there's nothing.
Typically you will see mysql.sock file when you start the mysql daemon process. This is create the sock file.
But you can also search and see whether it has created somewhere.
netstat -ln | grep -o -m 1 -E '\S*mysqld?\.sock'
or
you can check with this command:
% mysqladmin variables
If you want to create the file, you can do this
mkdir /var/mysql
ln -s /tmp/mysql.sock /var/mysql/mysql.sock
This thread explains things in more details.

Docker: MySQL refuses host IP unless I restart it manually

Here is my Dockerfile:
FROM debian:jessie-backports
RUN apt-get update --yes && apt-get upgrade --yes
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git \
curl \
build-essential\
libssl-dev\
ca-certificates\
mysql-server\
redis-server\
elasticsearch
USER root
ENV HOME /root
# MYSQL SETUP
RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/#bind-address = 0.0.0.0/" /etc/mysql/my.cnf
RUN sed -i -e"s/^#max_connections\s*=\s*100/max_connections = 200/" /etc/mysql/my.cnf
RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf
VOLUME ["/var/lib/mysql", "/var/log/mysql"]
EXPOSE 3306
# REDIS SETUP
RUN echo "daemonize yes\nbind 0.0.0.0" >> /etc/redis/redis-serve.conf
RUN sed 's/^daemonize no/daemonize yes/' -i /etc/redis/redis.conf \
&& sed 's/^bind 127.0.0.1/bind 0.0.0.0/' -i /etc/redis/redis.conf \
&& sed 's/^# unixsocket /unixsocket /' -i /etc/redis/redis.conf \
&& sed 's/^# unixsocketperm 755/unixsocketperm 777/' -i /etc/redis/redis.conf \
&& sed '/^logfile/d' -i /etc/redis/redis.conf
VOLUME ["/var/lib/redis", "/var/log/redis"]
EXPOSE 6379 6380
# ELASTICSEARCH SETUP
RUN sed 's/^#START_DAEMON=true/START_DAEMON=true/' -i /etc/default/elasticsearch
VOLUME ["/opt/elasticsearch/data", "/opt/elasticsearch/logs"]
EXPOSE 9200 9300
ADD docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
The entrypoint:
#!/bin/bash
/etc/init.d/mysql start
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
And the command I'm running to start the container:
docker run -i -t -p 3306:3306 -p 6379:6379 -p 9200:9200 -p 9300:9300 assethost
I want to connect to the MySQL server running in the container from the host, but this is what happens when I try to connect:
ERROR 1130 (HY000): Host '192.168.99.1' is not allowed to connect to this MySQL server
Both Redis and Elasticsearch expose themselves just fine. MySQL will only begin accepting external hosts if I restart it manually from the Bash shell that comes up from the entrypoint when I run the container. I have to run /etc/init.d/mysql restart. Only then, can I successfully connect from the host using the MySQL client.
Note that I am using docker-machine, so I have to give the MySQL client the host IP in order to connect.
How can I be able to connect from the host to the MySQL instance running in the container without having to manually restart MySQL?
Docker version 1.12.1, build 23cf638
I figured out a way to get the skip-grant-tables option to be applied on start.
Workaround
In docker-entrypoint.sh, I changed
/etc/init.d/mysql start to
HOME=/etc/mysql /usr/bin/mysqld_safe > /dev/null 2>&1 &
Other changes
Since there was already a [mysqld] section in my.cnf, I changed the following line in Dockerfile
RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf
to
RUN sed -i '/\[mysqld\]/ a skip-grant-tables\nskip-name-resolve' /etc/mysql/my.cnf
I added skip-name-resolve so mysql doesn't attempt to resolve names for local ip addresses.
Caveats
The workaround no longer works when /etc/init.d/mysql restart is executed, but /etc/init.d/mysql stop; /etc/init.d/mysql start preserved the 'skip-grant-tables' option.
I'm guessing MySQL has already started after your installation and running sed to change configuration won't take effect. Entry point you have has mysql start but it is probably seeing that MySQL is already running and not doing anything. Try changing that command to mysql restart, so your entry point bash script becomes:
#!/bin/bash
/etc/init.d/mysql restart
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
You're using skip-grant-tables flag to login without password. I think due to some reasons of /etc/init.d/mysql script, the flag is ignored on the first start, making the connection from the root#192.168.99.1 rejected. I believe Docker has nothing to do with this issue.
To answer your question, you don't have to restart by hand, you can change your entrypoint to either:
#!/bin/bash
/etc/init.d/mysql start
# Wait for mysql to be fully up, then restart (e.g., 5 seconds)
sleep 5
/etc/init.d/mysql restart
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
Or, don't use /etc/init.d/mysql start, instead invoke mysqld directly
#!/bin/bash
mysqld &
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
In addition, although creating one more [mysqld] group in my.cnf is not an issue, you should append new configuration to the existing group:
RUN sed -i '/\[mysqld\]/a skip-grant-tables' /etc/mysql/my.cnf
Refer the doc for several ways to start/stop Mysql server

MySQL Start Error

I am trying to install MySQL 5.6.17 on Ubuntu Linux and I am having difficulties doing so. I opened the MySQL Reference and opened "Installing MySQL on Unix/Linux Using Generic Binaries". I followed the following step:
shell> groupadd mysql
shell> useradd -r -g mysql mysql
shell> cd /usr/local
shell> tar zxvf /path/to/mysql-VERSION-OS.tar.gz
shell> ln -s full-path-to-mysql-VERSION-OS mysql
shell> cd mysql
shell> chown -R mysql .
shell> chgrp -R mysql .
shell> scripts/mysql_install_db --user=mysql
shell> chown -R root .
shell> chown -R mysql data
shell> bin/mysqld_safe --user=mysql &
//Next command is optional
shell> cp support-files/mysql.server /etc/init.d/mysql.server
After that when I try to start MySQL using /etc/init.d/mysql.server start I get the following error:
Couldn't find MySQL server (/usr/bin/mysqld_safe)
I looked in /usr/bin and I found mysqld_safe. Any suggestions on how to fix that problem. Please reply with a detailed solution.
Thank You
It seems you have installed Mysql in "/usr/local" and init script is looking for binaries in "/usr"
Change the "basedir" in /etc/init.d/mysql.server to :
basedir=/usr/local
The fact that you found /usr/bin/mysqld_safe suggests that MySQL in some shape or form was preinstalled on your OS. This can cause some confusion, in particular due to location of config files.
So for instance, on some versions of Ubuntu, the packages mysql-common is pre-installed, which means you might have an /etc/mysql/my.conf file with some defaults in it. When you install from the tar file to /usr/local, follow the INSTALL-BINARIES (or equivalent) instructions, and try to start /etc/init.d/mysql.server start you might get errors as the one you report ("Couldn't find MySQL server (/usr/bin/mysqld_safe)"), because the default configuration in /etc/init.d/mysql.server and any /etc/my.cnf that you created (optional step during install) is getting over-ridden by a setting in the OS installed /etc/mysql/my.conf. Note that this might happen even if you change the values in /etc/init.d/mysql.server and/or /etc/my.cnf.
One way out is to merge /etc/my.cnf and /etc/mysql/my.cnf into a single file at one of these locations, with the correct defaults that you wish to use.

Changing the tmp folder of mysql

Our Mysql queries use temporary tables which creates temporary files in the process. Currently the files are written to /tmp. How exactly can the path of the temp folder to which mysql writes to be changed?
You should edit your my.cnf
tmpdir = /whatewer/you/want
and after that restart mysql
P.S. Don't forget give write permissions to /whatewer/you/want for mysql user
Here is an example to move the mysqld tmpdir from /tmp to /run/mysqld which already exists on Ubuntu 13.04 and is a tmpfs (memory/ram):
sudo vim /etc/mysql/conf.d/local.cnf
Add:
[mysqld]
tmpdir = /run/mysqld
Then:
sudo service mysql restart
Verify:
SHOW VARIABLES LIKE 'tmpdir';
==================================================================
If you get an error on MySQL restart, you may have AppArmor enabled:
sudo vim /etc/apparmor.d/local/usr.sbin.mysqld
Add:
# Site-specific additions and overrides for usr.sbin.mysqld.
# For more details, please see /etc/apparmor.d/local/README.
/run/mysqld/ r,
/run/mysqld/** rwk,
Then:
sudo service apparmor reload
sources: http://2bits.com/articles/reduce-your-servers-resource-usage-moving-mysql-temporary-directory-ram-disk.html, https://blogs.oracle.com/jsmyth/entry/apparmor_and_mysql
This is answered in the documentation:
Where MySQL Stores Temporary Files
On Unix, MySQL uses the value of the TMPDIR environment variable as
the path name of the directory in which to store temporary files. If
TMPDIR is not set, MySQL uses the system default, which is usually
/tmp, /var/tmp, or /usr/tmp.
On Windows, Netware and OS2, MySQL checks in order the values of the
TMPDIR, TEMP, and TMP environment variables. For the first one found
to be set, MySQL uses it and does not check those remaining. If none
of TMPDIR, TEMP, or TMP are set, MySQL uses the Windows system
default, which is usually C:\windows\temp.
if you dont have apparmor or selinux issues, but still get errorcode 13's:
mysql must be able to access the full path. I.e. all folders must be mysql accessible, not just the one you intend in pointing to.
example, you try using this in your mysql configuration: tmp = /some/folder/on/disk
# will work, as user root:
mkdir -p /some/folder/on/disk
chown -R mysql:mysql /some
# will not work, also as user root:
mkdir -p /some/folder/on/disk
chown -R mysql:mysql /some/folder/on/disk
This maybe helpful for MySql with AppArmor
stop mysql :
sudo /etc/init.d/mysql stop
Create directory called /somewhere/tmp
Edit Config:
sudo vim /etc/mysql/my.cnf # or perhaps sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
change
tmpdir = /somewhere/tmp/
Then
sudo vim /etc/apparmor.d/usr.sbin.mysqld
Add
# Allow data dir access
/somewhere/ r,
/somewhere/** rwk,
sudo chown -R root:root /somewhere
sudo chmod -R 1777 /somewhere
Restart
sudo /etc/init.d/apparmor reload
sudo /etc/init.d/mysql restart
You can also set the TMPDIR environment variable.
In some situations (Docker in my case) it's more convenient to set an environment variable than to update a config file.
Works for 5.7 on centos 8
mkdir /tmp/1 /tmp/1
semanage fcontext -a -t mysqld_db_t "/tmp/1(/.*)?"
restorecon -Rv /tmp/1
semanage fcontext -a -t mysqld_db_t "/tmp/2(/.*)?"
restorecon -Rv /tmp/2
to my.cnf tmpdir=/tmp/1:/tmp/2
sudo service mysql restart
If you are a MariaDB user, all this above apply, by don't forget to unlock the "home" protection by doing this.
touch /etc/systemd/system/mariadb.service.d/override.conf
nano /etc/systemd/system/mariadb.service.d/override.conf
Inside override.conf put this content and save.
[Service]
ProtectHome=false
Then run the following commands :
systemctl daemon-reload
/scripts/restartsrv_mysql
After restarting mysql, the variables can be checked by :
mysqladmin variables|grep tmp