Sunday, October 15, 2017

Saturday, October 14, 2017

MySQL resolve Host name to IP Address or Vice Versa

MySQL resolve Host name to IP Address or Vice Versa

# resolveip 192.168.5.11

# resolveip mysql-slave

Reference:

https://dev.mysql.com/doc/refman/5.7/en/resolveip.html

Monday, October 9, 2017

Go at Google: Language Design in the Service of Software Engineering

Go at Google: Language Design in the Service of Software Engineering

https://talks.golang.org/2012/splash.article

Good C string library

Good C string library

http://site.icu-project.org/

Reference:

https://stackoverflow.com/questions/4688041/good-c-string-library

Install MySQL 5.7, Apache 2.4, PHP 7.1 on Ubuntu 16.04

Install MySQL 5.7, Apache 2.4, PHP 7.1 on Ubuntu 16.04

Install VMware tools:

VM > Guest > Install/Upgrade VMware Tools

# su -
# df -h
# cd /media/jun/VMware\ Tools/
# ls -la
# tar zxvf VMwareTools-9.4.0-1280544.tar.gz -C /tmp/
# cd /tmp
# ls
# cd vmware-tools-distrib/
# ls
# ./vmware-install.pl -d
# reboot

Note: For more info https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1022525

Move Ubuntu launcher to the bottom:

# gsettings set com.canonical.Unity.Launcher launcher-position Bottom

Update the package repository:

# apt-get update

Upgrades packages with auto-handling of dependencies:

# apt-get dist-upgrade

or

# apt full-upgrade

Install SSH server:

# apt-get install openssh-server
# systemctl status sshd.service
# systemctl restart sshd.service

Compile and install the latest Git 2.14.2 from source code:

# apt-get install dh-autoreconf libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev
# apt-get install curl
# cd /usr/local/src/
# curl -L https://github.com/git/git/archive/v2.14.2.tar.gz -o git.tar.gz
# tar zxvf git.tar.gz
# cd git-2.14.2/
# make configure
# ./configure --prefix=/usr
# make all
# make install

# git --version

git version 2.14.2

Install Git from ppa:

# add-apt-repository ppa:git-core/ppa
# apt-get update

# apt-cache policy git
# apt-cache madison git

# apt-get install git=1:2.11.0-2~ppa0~ubuntu16.04.1

# git --version

Compile and install the latest Vim 8:

# apt-get install libncurses5-dev python-dev ruby-dev libperl-dev ruby-dev liblua5.3-dev exuberant-ctags cscope

// Fix liblua paths
# ln -s /usr/include/lua5.3 /usr/include/lua
# ln -s /usr/lib/x86_64-linux-gnu/liblua5.3.so /usr/local/lib/liblua.so

# cd /usr/local/src
# git clone https://github.com/vim/vim.git

# cd vim
# ./configure --prefix=/usr --with-features=huge --enable-multibyte --enable-pythoninterp --enable-rubyinterp --enable-perlinterp --enable-luainterp --enable-cscope
# make
# make install

# hash -r
# vim --version | head

Install MTA mail server:

# apt-get install postfix

Note: select "Internet site".

Note: If you need to reconfigure the postfix setting, run either one of the following:

# dpkg-reconfigure -plow postfix

or

# apt-get purge postfix

For other mail related packages:

# apt-get install mailutils

Install mail client:

# apt-get install bsd-mailx
# echo "test message" | mailx -s 'test subject' myemail@mydomain.com

For hexdump command:

# apt-get install bsdmainutils

# hexdump -c test.log

Install MySQL5.7:

# apt-cache policy mysql-server
# apt-cache search mysql-server
# apt-cache show mysql-server | less
# apt show mysql-server

# apt-get install mysql-server

# vim /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 0.0.0.0

# vim ~/.my.cnf
[client]
host = localhost
port = 3306
user = root
password = MyPassword

# chmod 400 ~/.my.cnf

# mysql -e "SHOW variables WHERE variable_name REGEXP 'open_files_limit|table_open_cache|max_connections';"
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| max_connections            | 151   |
| open_files_limit           | 1024  |
| table_open_cache           | 431   |
| table_open_cache_instances | 16    |
+----------------------------+-------+

Note: You will see the following error message in the error.log file if you did not change the open files limit:
[Warning] Changed limits: max_open_files: 1024 (requested 5000)
[Warning] Changed limits: table_open_cache: 431 (requested 2000)

# mkdir /etc/systemd/system/mysql.service.d
# vim /etc/systemd/system/mysql.service.d/override.conf

[Service]
#LimitNOFILE=infinity
LimitNOFILE=5000

#LimitMEMLOCK=infinity

# systemctl daemon-reload
# systemctl restart mysql

# mysql -e "SHOW variables WHERE variable_name REGEXP 'open_files_limit|table_open_cache|max_connections';"
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| max_connections            | 151   |
| open_files_limit           | 5000  |
| table_open_cache           | 2000  |
| table_open_cache_instances | 16    |
+----------------------------+-------+

To check MySQL process's limit:

# cat /proc/$(pgrep mysqld$)/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             15614                15614                processes
Max open files            5000                 5000                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       15614                15614                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

Note: https://dev.mysql.com/doc/refman/5.7/en/using-systemd.html

Note: https://stackoverflow.com/questions/30901041/can-not-increase-max-open-files-for-mysql-max-connections-in-ubuntu-15

Note: https://serverfault.com/questions/821695/mysqld-service-for-systemd-failed-to-parse-resource-value-ignoring-40000-l

To move a MySQL data directory to another directory:

# mysql -e "SELECT @@datadir;"
+-----------------+
| @@datadir       |
+-----------------+
| /var/lib/mysql/ |
+-----------------+

# systemctl stop mysql
# systemctl status mysql

# vim /etc/mysql/mysql.conf.d/mysqld.cnf
datadir         = /home/mysql

# vim /etc/apparmor.d/tunables/alias
alias /var/lib/mysql/ -> /home/mysql/,

Note: We need to tell AppArmor to let MySQL write to the new directory by creating an alias between the default directory and the new location.

Note: If you skipped the AppArmor configuration step, you would see the following error message:

Job for mysql.service failed because the control process 
exited with error code. See "systemctl status mysql.service" 
and "journalctl -xe" for details.

# systemctl restart apparmor
# systemctl restart mysql

To move the existing to MySQL directory to /home:

# rsync -av /var/lib/mysql /home

Or, you can run the following commands to initialize the MySQL data directory:

# mkdir /home/mysql \
&& chown mysql:mysql /home/mysql \
&& chmod 700 /home/mysql \
&& mysqld --initialize-insecure

Note: This option is used to initialize a MySQL installation by creating the data directory and populating the tables in the mysql system database.

Note: If you use --initialize, the random initial password is stored at: tail -n 1 /var/log/mysql/error.log.

Note: You can also start mysqld with --skip-grant-tables to access the database and change the password.

# systemctl start mysql && systemctl status mysql

Login MySQL with the above commands if you initialized MySQL data directory with --initialize-insecure option.
# mysql -u root --skip-password
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

Check the current MySQL data directory:

# mysql -e "SELECT @@datadir;"
+--------------+
| @@datadir    |
+--------------+
| /home/mysql/ |
+--------------+

To change the root password if you did not know the current root password:

# vim /root/tmp/mysql-init.txt
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'YourPassWordHere' WITH GRANT OPTION;
GRANT SUPER ON *.* TO 'root'@'localhost';
FLUSH PRIVILEGES;

# mysqld --init-file=/root/tmp/mysql-init.txt

Install PHP7.0:

# command -v add-apt-repository >/dev/null 2>&1 \
|| { echo >&2 "add-apt-repository is not installed. I will install it for you"; apt-get install python-software-properties; }

# add-apt-repository -y ppa:ondrej/php
# apt-get update

# apt-cache policy php7.1

# apt-get install php7.1-fpm
# apt-get install php7.1-xml php7.1-curl php7.1-zip php7.1-gd php7.1-bcmath php7.1-intl php7.1-mbstring php7.1-mcrypt php7.1-mysql
# apt-get install php7.1-json php7.1-opcache
# apt-get install php-xdebug

# php -v
PHP 7.1.10-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Sep 29 2017 17:04:25) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.10-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.5.5, Copyright (c) 2002-2017, by Derick Rethans

# vim /etc/php/7.1/fpm/pool.d/www.conf

;listen = /run/php/php7.1-fpm.sock
listen = 127.0.0.1:9000

Note: You can choose to use either a Unix socket (for local access only) or TCP socket (for the other server on the network to access).

# systemctl restart php7.1-fpm.service && systemctl status php7.1-fpm.service

# ss -an | grep :9000
tcp    LISTEN     0      128    127.0.0.1:9000                  *:*

# vim /etc/php/7.1/fpm/php.ini

date.timezone = America/Vancouver
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
error_log = /var/log/php_errors.log

List all the installed PHP packages:

# dpkg -l | grep php| awk '{print $2}' |tr "\n" " "

Show the available package version:

# apt-cache search php
# apt-cache policy php

Install the specific package version:

# apt-get install php7=7.0+35ubuntu6

Note: You can look up old versions of packages at their site http://www.debian.org/distrib/packages

Install older version of PHP (PHP5.6):

# add-apt-repository ppa:ondrej/php

# apt-get update

# apt-get install php5.6-fpm

# apt-get install php5.6-gd php5.6-intl php5.6-json php5.6-mbstring php5.6-mcrypt php5.6-mysql php5.6-opcache php5.6-xml

# a2disconf php7.0-fpm.conf
# a2enconf php5.6-fpm.conf

# systemctl restart apache2.service

Install Apache2.4:

# command -v add-apt-repository >/dev/null 2>&1 \
|| { echo >&2 "add-apt-repository is not installed. I will install it for you"; apt-get install python-software-properties; }

# add-apt-repository -y ppa:ondrej/apache2
# apt-get update

# apt-cache policy apache2

# apt-get install apache2

Enable the following modules to talk to PHP:

# cat /etc/apache2/conf-available/php7.1-fpm.conf

# a2enmod proxy proxy_fcgi rewrite setenvif ssl
# a2enconf php7.1-fpm.conf

If your apache is talking to PHP through a TCP socket (127.0.0.1:9000) instead of a Unix socket (/run/php/php7.1-fpm.sock), you will need to modify the following line:

# vim /etc/apache2/conf-available/php7.1-fpm.conf
    <FilesMatch ".+\.ph(ar|p|tml)$">
        #SetHandler "proxy:unix:/run/php/php7.1-fpm.sock|fcgi://localhost"
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>

# apache2ctl configtest
# systemctl restart apache2 && systemctl status apache2

Install and enable the following Apache modules if you are connecting to PHP through a TCP socket (127.0.0.1:9000):

# apt-get install libapache2-mod-fastcgi
# a2enmod fastcgi rewrite setenvif


Edit apache2.conf:

# vim /etc/apache2/apache2.conf

AllowOverride All

Set up a virtual host:

# cd /etc/apache2/sites-available
# cp 000-default.conf mag2.local.conf
# vim mag2.local

Check the configuration:

# apache2ctl -V
# apache2ctl -t
# apache2ctl -M
# apache2ctl configtest

Enable the site:

# a2ensite mag2.local

Start MySQL, PHP, and Apache:

# systemctl restart mysql.service
# systemctl restart php7.0-fpm.service
# systemctl restart apache2.service

# ps auxww | grep -i mysql
# ps auxww | grep -i php-fpm
# ps auxww | grep -i apache2

Install PHPStorm:

# cd ~jun/Downloads/
# tar xf PhpStorm-*.tar.gz -C /opt/
# cd /opt/PhpStorm-163.10504.2/
# ./bin/phpstorm.sh

Generate a self-signed SSL certificate:

# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -subj "/C=CA/ST=British Columbia/L=Vancouver/O=My Company Name/CN=erp.local" -keyout /etc/ssl/private/test.local.key -out /etc/ssl/certs/test.local.crt

Reference:

https://www.digitalocean.com/community/tutorials/how-to-move-a-mysql-data-directory-to-a-new-location-on-ubuntu-16-04

Content-Length not sent when gzip compression enabled in Apache?

Content-Length not sent when gzip compression enabled in Apache?

Philippe: "Apache uses chunked encoding only if the compressed file size is larger than the DeflateBufferSize. Increasing this buffer size will therefore prevent the server using chunked encoding also for larger files, causing the Content-Length to be sent even for zipped data."

Reference:

https://serverfault.com/questions/183843/content-length-not-sent-when-gzip-compression-enabled-in-apache/183856#183856

https://stackoverflow.com/questions/2287950/how-do-you-set-the-correct-content-length-header-when-the-webserver-automaticall

Sunday, October 8, 2017

Jet Profiler for MySQL

Jet Profiler for MySQL

is a real-time query performance and diagnostics tool for the MySQL database server. It's core features:

Query, table and user performance
Graphical visualisation
Low overhead
User friendly

Reference:

https://www.jetprofiler.com/

InnoDB memory usage buffer pool status

InnoDB memory usage buffer pool status

Making sense of INNODB buffer pool stats

After having read this page in the mysql documentation, I tried to make sense of our current InnoDB usage. Currently, we allocate 6GB of RAM for the buffer pool. Our database size is about the same. Here's the output from show engine innodb status\G (we're running v5.5)

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 6593445888; in additional pool allocated 0
Dictionary memory allocated 1758417
Buffer pool size   393215
Free buffers       853
Database pages     360515
Old database pages 133060
Modified db pages  300
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 7365790, not young 23099457
0.00 youngs/s, 0.00 non-youngs/s
Pages read 1094342, created 185628, written 543182148
0.00 reads/s, 0.00 creates/s, 37.32 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 360515, unzip_LRU len: 0
I/O sum[2571]:cur[0], unzip sum[0]:cur[0]

I wanted to know how well we're utilizing the buffer cache. After initially glancing at the output, it appeared that we are indeed using it, based off of the Pages made young and not young have numbers in them and Buffer pool hit rate is 1000 / 10000 (which I saw elsewhere on the web that this means it's being used pretty heavily. True?)

What's throwing me through a loop is why the young-making rate and not are both at 0/1000 and the young/s and non-young/s accesses are both at 0. Those would all indicate that it's not being used at all, right?

Can anyone help make sense of this?

This is in pages not bytes:

The Buffer pool size   393215

To see the Buffer Pool size in GB run this:

Note: As of MySQL 5.7.6 the "information_schema" is merged into performance_schema. So just change "information_schema" to "performance_schema" in the query to make it work.

SELECT FORMAT(BufferPoolPages*PageSize/POWER(1024,3),2) BufferPoolDataGB FROM
(SELECT variable_value BufferPoolPages FROM information_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_total') A,
(SELECT variable_value PageSize FROM information_schema.global_status
WHERE variable_name = 'Innodb_page_size') B;

This is the number of pages with data inside the Buffer Pool:

Database pages     360515

To see the amount of data in the Buffer Pool size in GB run this:

SELECT FORMAT(BufferPoolPages*PageSize/POWER(1024,3),2) BufferPoolDataGB FROM
(SELECT variable_value BufferPoolPages FROM information_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_data') A,
(SELECT variable_value PageSize FROM information_schema.global_status
WHERE variable_name = 'Innodb_page_size') B;

To see the percentage of the Buffer Pool in use, run this:

SELECT CONCAT(FORMAT(DataPages*100.0/TotalPages,2),' %') BufferPoolDataPercentage FROM
(SELECT variable_value DataPages FROM information_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_data') A,
(SELECT variable_value TotalPages FROM information_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_total') B;

This is the number of pages in the Buffer Pool that have to be written back to the database. They are also referred to as dirty pages:

Modified db pages  300

To see the Space Taken Up by Dirty Pages, run this:

SELECT FORMAT(DirtyPages*PageSize/POWER(1024,3),2) BufferPoolDirtyGB FROM
(SELECT variable_value DirtyPages FROM information_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_dirty') A,
(SELECT variable_value PageSize FROM information_schema.global_status
WHERE variable_name = 'Innodb_page_size') B;

To see the Percentage of Dirty Pages, run this:

SELECT CONCAT(FORMAT(DirtyPages*100.0/TotalPages,2),' %') BufferPoolDirtyPercentage FROM
(SELECT variable_value DirtyPages FROM information_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_dirty') A,
(SELECT variable_value TotalPages FROM information_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_pages_total') B;

As for the other things in the display, run this:

SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool%';

You'll see all the status variables for the Buffer Pool. ou can apply the same queries against whatever you need to examine.

The buffer pool is divided into two part, a young list and a not-young list. The making rate shows how many pages in the buffer pools are being shuffled between the two lists.

Pages made young are not-young pages being made (i.e. being read out of the cache. Pages made not-young are pages moved from the young list because either they are too old, or because the young list is full.

The rate at pages are moved between the two depends upon how much of the buffer pool is currently being used vs the size of the young pool. Set at zero means your active set (the pages you are using) is smaller than the young pool.

Reference:

http://dba.stackexchange.com/questions/56494/making-sense-of-innodb-buffer-pool-stats

http://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool.html

How much memory do I need for InnoDB buffer pool?

How much memory do I need for InnoDB buffer pool?

The following query gives you the recommended InnoDB buffer pool size based on all InnoDB Data and Indexes with an additional 60%:

SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) AS RIBPS_GB FROM
(SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
FROM information_schema.tables WHERE engine='InnoDB') A;

+-------+
| RIBPS |
+-------+
|     8 |
+-------+

With this output, you would set the following in /etc/my.cnf:

[mysqld]
innodb_buffer_pool_size=8G

After few days, run this query to see the actualy GB of memory in use in the InnoDB buffer pool:

SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM
(SELECT variable_value PagesData
FROM performance_schema.global_status
WHERE variable_name='Innodb_buffer_pool_pages_data') A,
(SELECT variable_value PageSize
FROM performance_schema.global_status
WHERE variable_name='Innodb_page_size') B;

You need buffer pool a bit (say 10%) larger than your data (total size of Innodb TableSpaces):

If you want to accommodate an addition 10%, plus account for 25% increase in data and indexes over time, the following query will produce exactly what you need to set innodb_buffer_pool_size in /etc/mysql/mysql.conf.d/mysqld.cnf:

SET @growth = 1.25;

SELECT
 CONCAT(
  CEILING(RIBPS / POWER(1024, pw)),
  SUBSTR(' KMGT', pw + 1, 1)
 ) Recommended_InnoDB_Buffer_Pool_Size
FROM
 (
  SELECT
   RIBPS,
   FLOOR(LOG(RIBPS) / LOG(1024)) pw
  FROM
   (
    SELECT
     SUM(data_length + index_length) * 1.1 * @growth AS RIBPS
    FROM
     information_schema. TABLES AAA
    WHERE
     ENGINE = 'InnoDB'
    GROUP BY
     ENGINE
   ) AA
 ) A;

Reference:

http://blog.ijun.org/2016/02/innodb-memory-usage-buffer-pool-status.html

https://dba.stackexchange.com/questions/27328/how-large-should-be-mysql-innodb-buffer-pool-size

https://dba.stackexchange.com/questions/125164/information-schema-global-variables-alternative-in-5-7-more-info-about-show-com

http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/

Disable TLS 1.0 and 1.1 in Apache 2.4

Disable TLS 1.0 and 1.1 in Apache 2.4:

# vim /etc/apache2/mods-available/ssl.conf

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

Verify if TLS 1.0 and 1.1 are supported:

# openssl s_client -connect mydomain.com:443 -tls1

# openssl s_client -connect mydomain.com:443 -tls1_1

Note: If you get the certificate chain and the handshake you know the system in question supports TLS 1.1.

Reference:

https://serverfault.com/questions/638691/how-can-i-verify-if-tls-1-2-is-supported-on-a-remote-web-server-from-the-rhel-ce

When checking Apache's gzip deflate compression, I realized Apache was sending "Transfer-Encoding: chunked" and not sending the "Content-Length" header

When checking Apache's gzip deflate compression, I realized Apache was sending "Transfer-Encoding: chunked" and not sending the "Content-Length" header

Andy: "Chunked output occurs when Apache doesn't know the total output size before sending, as is the case with compressed transfer (Apache compresses data into chunks when they reach a certain size, then despatches them to the browser/requester while the script is still executing). You could be seeing this because you have mod_deflate or mod_gzip active.

You can disable mod_deflate per file like so (more here)

    SetEnvIfNoCase Request_URI get_file\.php$ no-gzip dont-vary

It's best left on in general as it greatly increases the speed of data transfer.
"

Reference:

https://serverfault.com/questions/59047/apache-sending-transfer-encoding-chunked

Friday, October 6, 2017

Manually obtaining TLS/SSL certificates from Let's Encrypt

Official build of EFF's Certbot tool for obtaining TLS/SSL certificates from Let's Encrypt.

https://hub.docker.com/r/certbot/certbot/

# certbot certonly --manual --preferred-challenges http --email me@example.com -d mydomain.com