Drug preguntas

Mysql Server Optimization for DBA

MySql No Comments »

MySQL is the most widely used multi-user, multi-threading SQL database management system. To optimize MySQL performance, a DBA should have reasonable knowledge of MySQL system variables. This article covers the basics of MySQL server optimization. We will first discuss MySQL optimization during installation. Then we will discuss the seven most important and common system variables. Plus, a brief note on how to optimize the server using those seven variables.

We will also discuss MySQL status variables. This article would be very useful for a newbie MySQL DBA when setting up a MySQL server.

1. How to optimize the MySQL Installation.

Most server owners prefer to have a control panel software (like cPanel, Plesk etc) installed in their server so that they can easily manage their servers. In that case, MySQL installation will be customized according to the control panel software installed.

If you are planning to compile MySQL by your own, following are a few points which you should consider for faster performance.

  1. While compiling MySQL, compile it statically ( -static option). This will require more disk space but runs faster.
  2. Enable debug option if you actually need it. Enabling debug mode installs a safe Memory Allocation (SAFEMALLOC) checker. Running SAFEMALLOC is slow. So if you have enabled debug mode and is having performance problems, you should start mysqld with -skip-safemallaoc option.
  3. Compile without frame pointers (-fomit-frame-pointer). Frame Pointer is a pointer to the current stack frame. Frame pointer is mainly used for debugging purpose. Compiling without frame pointers make mysqld run 1-4% faster.
  4. Standard binary distributions from MySQL are compiled with support for all character sets. When you are compiling by yourself, use the character sets required for your application only. This can be specified by the -with-charset option in the configure option. Or you can use the minimum character set using the -with-extra-charsets=none option.

2. Compilation over.. Now what??

Now according to your requirement, you have compiled your MySQL server and now we can go forward with optimizing it.

Optimizing MySQL is done based on the server specifications and the applications which are running on the server. The MySQL server configuration file should be named my.cnf and is usually placed in DATADIR/my.cnf. You can specify the location to the my.cnf file using the âdefault-file argument during installation. This helps associate configuration files with particular server instances.

Fortunately, MySQL itself is providing some sample my.cnf files which fit to most of the systems. The different config files that MySQL provide are my-huge.cnf, my-large.cnf, my-medium.cnf and my-small.cnf.

Each config file is designed for different systems and it is always recommended to select the sample config according to your system specs.

  • my-huge.cnf : recommended for systems that have at least 1GB memory, and run mainly MySQL
  • my-large.cnf : for systems with slightly less memory (512MB), and also mainly running MySQL.
  • my-medium.cnf : tweaked for a system where MySQL and a Web server are running together with around 128MB, or around 64MB
  • my-small.cnf : for system with less than 64MB

So choose the right config file for your system and your server should work good. But you can get better results if you tweak the variables properly. For this you need to know the different system and status variables and how they are linked together. Remember, changing the system variables improperly may lead to worse situations.There are several MySQL system variables which can be tweaked for improving performance. But here, we will be discussing about 7 variables, tuning which can change the performance drastically.

3. Is the sample config enough for me?

I would say NO. Each database server will be running different applications in it and so you MUST fine tune your server according to the applications and resourse utilization. Now.. how can I identify the variables that need to be tweaked? And how should I go for it?

Below are the 7 most important system variables that need to be tweaked in normal case.

3.1. table_cache

Each time MySQL accesses a table, it places the table in the cache. If your application accesses many tables, it is always good to have them in cache so that data retrieve is faster.

You can check whether your system needs to have the table_cache value increased by checking the open_tables and opened_tables status variables during peak time.

open_tables is the number of tables opened in cache. Whereas opened_tables is the total number of tables open. Since MySQL supports multi-threading, several queries might be executed on the same table at the same time. So each of these queries will open a table.

The default value to table_cache is 64. Lets consider a sample scenario.

table_cache = 64
mysql> SHOW STATUS LIKE "open%tables%";
open_tables = 64
opened_tables = 5426787

Here table_cache has maxed out and opened_tables is fairly high. In this case, if you have enough memory, increase table_cache to reduce the number of opened_tables.

3.2. query_cache_size

Query caching has been introduced from MySQL 4 onwards. If your application executes a particular query again and again, MySQL can cache the result set, thereby avoiding the overhead of running through the data over and over and thereby increase the execution time.

You can enable query caching by setting the server variable query_cache_type=1 and setting the cache size in the variable query_cache_size. If either of the above is set to 0, query caching will not be enabled.

There are three status for query caching;

  1. Disabled - query_cache_type = 0
  2. Enabled - query_cache_type = 1
  3. On Demand - query_cache_type = 2

Some sample scenarios:

If you have enabled query caching and do not want the result of a particular query to be cached, you can mention it in your query by specifying SQL_NO_CACHE.

eg: SELECT SQL_NO_CACHE id, name FROM employee_info WHERE employee_rank < 5;

In the above case, the result of the query will not be cached. Similarly, you can enable query caching in ON DEMAND query caching by specifying SQL_CACHE in your query.

eg: SELECT SQL_CACHE id, name FROM employee_info WHERE employee_rank < 5;

After executing the query the result will be added to the cache memory and will used if the query is executed again.

How to check the query cache status variables

mysql> SHOW STATUS LIKE "%qcache%";
+-------------+-----+
| Variable_name | Value |
+-------------+-----+
| Qcache_free_blocks | 2253 |
| Qcache_free_memory | 9184200 |
| Qcache_hits | 247217 |
| Qcache_inserts | 50012 |
| Qcache_lowmem_prunes | 15666 |
| Qcache_not_cached | 13269 |
| Qcache_queries_in_cache | 5215 |
| Qcache_total_blocks | 13117 |
+-------------+-----+

8 rows in set (0.00 sec)

This is a result from a server with query_cache_type set to 1 ( Enabled). Now lets see what all these status variables stand for.

  • Qcache_free_blocks: The number of free memory blocks in the cache memory.
  • Qcache_free_memory: The amount of free memory for the query cache.
  • Qcache_hits : The number of query cache hits.
  • Qcache_inserts : The number of queries added to the query cache.
  • Qcache_lowmem_prunes : The number of queries that were deleted from the query cache because of low memory.
  • Qcache_not_cached : The number of non-cached queries (not cache-able, or not cached due to the query_cache_type setting).
  • Qcache_queries_in_cache : The number of queries registered in the query cache. Qcache_total_blocks: The total number of blocks in the query cache.

Qcache_free_blocks is an indication of fragmentation and if this is high in relation to the Qcache_total_blocks, it means that the cache space is wasted. The default block size for query cache is 4KB. If your query result is small and you see fragmentation, you should decrease the block size. You can use the system variable query_cache_min_res_unit to redefine the block size. And if the query result is large, you should increase the block size.
To defragment the query cache, you can use the command

mysql> FLUSH QUERY CACHE;
Query OK, 0 rows affected (0.07 sec)
mysql> show status like "%qcache%";
+-------------+-----+
| Variable_name | Value |
+-------------+-----+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 9090576 |
| Qcache_hits | 248169 |
| Qcache_inserts | 50147 |
| Qcache_lowmem_prunes | 15666 |
| Qcache_not_cached | 13316 |
| Qcache_queries_in_cache | 5273 |
| Qcache_total_blocks | 10979 |
+-------------+-----+
8 rows in set (0.00 sec)

Now the cache memory has been defragmented and you can see that the Qcache_free_blocks has reduced.There are situations when a query is not cached, such as returning current time, random number etc. Any queries making use of the following commands / types / functions will not be cached:

User-Defined Functions
BENCHMARK CONNECTION_ID CURDATE CURRENT_DATE  CURRENT_TIME CURRENT_TIMESTAMP CURTIME DATABASE
ENCRYPT (with one parameter) FOUND_ROWS GET_LOCK LAST_INSERT_ID LOAD_FILE MASTER_POS_WAIT NOW RAND
RELEASE_LOCK SYSDATE UNIX_TIMESTAMP (without parameters) USER 

query contains user variables
query references the mysql system database
Queries like these
    SELECT ... IN SHARE MODE
    SELECT ... INTO OUTFILE ...
    SELECT ... INTO DUMPFILE ...
    SELECT * FROM AUTOINCREMENT_FIELD IS NULL
queries inside transactions (in MySQL 4.0.x)

Some interesting facts about Query Caching:

Query caching is case sensitive:

Eg: mysql> show status like "%qcache%";
+-------------+-----+ |
Variable_name | Value |
+-------------+-----+
| Qcache_free_blocks | 1|
| Qcache_free_memory | 12574168 |
| Qcache_hits | 0 |
|Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached |0 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+-------------+-----+
8 rows in set (0.00 sec)
mysql>
select * from wp_post2cat where category_id=14;
+----+----+---+
+-----+-------+
15 rows in set (0.03 sec)
mysql>
select * from wp_post2cat where category_id=14;

+----+-----+-------+
+----+-----+-------+

15 rows in set (0.00 sec)
mysql> show status like "%qcache%";
+-------------+-----+
| Variable_name | Value |
+-------------+-----+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 12571408 |
| Qcache_hits | 1 |
| Qcache_inserts | 1 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 1 |
| Qcache_total_blocks | 4 |
+-------------+-----+
8 rows in set (0.00 sec)

If you check the status variables,Before executing the query, the Qcache_inserts and Qcache_hits was 0. And the query took 0.03secs to execute for the first time.

When the query was executed for the second time, the Qcache_inserts and Qcache_hits was increased by 1 and took less time to execute.

Now I am executing the same query with a small difference:

mysql> SELECT * FROM wp_post2cat where category_id=14;
+----+-----+-------+
+----+-----+-------+
15 rows in set (0.02 sec)

mysql> show status like "%qcache%";
+-------------+-----+
| Variable_name | Value |
+-------------+-----+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 12569160 |
| Qcache_hits | 1 |
| Qcache_inserts | 2 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 2 |
| Qcache_total_blocks | 6 |
+-------------+-----+
8 rows in set (0.00 sec)

Now you can see that the Qcache_inserts has increased and the query took 0.02 secs to execute. MySQL has inserted another query in the cache since it is considering this as a separate query. So if you are a programmer, make sure that you write all the query in a standard format so that your program utilizes query caching properly.

Query cache Clearing:

MySQL is clever enough to clear the query results whenever a change is made to the table. Any of INSERT, UPDATE, DELETE, TRUNCATE, ALTER, DROP TABLE or DROP DATABASE will remove queries from the cache. You can manually clear the query cache with RESET QUERY CACHE.

3.3. key_buffer_size:

key_buffer_size is the size of buffer used by all the indexes. Ideally, it should be large enough to contain all the indexes ie., total size of all the .MYI files in the server. A rule of thumb is to set to to at least a quarter of the memory available, half the memory to the maximum but not more than that.

When to increase your key_buffer_size:

The status variables you should be checking to find this are Key_read_requests, Key_reads, Key_write_requests and Key_writes.

Key_read_requests : The number of requests to read a key block from the cache.

Key_reads : The number of physical reads of a key block from disk.

Key_write_requests : The number of requests to write a key block to the cache.

Key_writes : The number of physical writes of a key block to disk.

The optimum solution is to keep the ratio Key_reads : Key_read_requests should be 1:100 and Key_writes / Key_write_requests should always be less than 1.

If the Key_reads value is high compared to Key_read_requests, it is high time you increase your key_buffer_size.

3.4. sort_buffer_size:

Improves large and complex sorts. Each thread that needs to do a sort allocates a buffer of this size. Increase this value for faster ORDER BY or GROUP BY operations. The default value for sort_buffer_size is 2MB. Please note this buffer is at a per client level.

When to increase sort_buffer_size:

Queries that sort rows, either by GROUP BY or ORDER BY undergo three processes.

1.Find the rows

2.sort the rows

3.read the sorted rows

MySQL first tries to sort the rows to the memory, the size of which is controlled by sort_buffer_size system variable. If the memory is not sufficient, it creates a temporary file to create the sorted rows, however the temporary file need to be sorted too after all the rows have been found from step 1. The re-sorting of the temporary file counts to the status variable Sort_merge_passes. MySQL actually creates a second temporary file into which it puts the sorted contents of the first file. Therefore, its common to see almost exactly twice as many created temporary files as Sort_merge_passes.

Sort_merge_passes can be reduced by increasing sort_buffer_size.

3.5. read_rnd_buffer_size:

read_rnd_buffer_size is used after a sort for reading the rows in the sorted order. If your application has a lot of queries with ORDER BY, increasing this can improve the performance. This is buffer is also at a per client basis. The default value for read_rnd_buffer_size is 128K. A general rule of thumb is to allocate 1MB for every 1GB memory.

3.6. tmp_table_size:

Sometimes for executing a statement, a temporary table needs to be created. This variable determines the maximum size for a temporary table in memory.

Always try to avoid temporary table creation by optimizing your query. But if it is unavoidable, make sure that the table is created in the memory. If the memory is not sufficient, a MyISAM table will be created in the disk.

When to increase tmp_table_size:

Check the processlist and see if any query is using temporary tables and is taking too long to resolve. In this case, you should increase the tmp_table_size.

You can also check the status variables Created_tmp_disk_tables and Created_tmp_tables.

Created_tmp_disk_tables : Number of temporary tables created on disk while executing a statement Created_tmp_tables : Number of in-memory tables created.

If a large number of tables are created in the disk, its high time you increase your tmp_table_size. Please note memory is allocated in per client basis (per thread basis).

3.7. thread_cache:

If your server is busy is making a lot of new connections ie., if you high max_connections, then the server will create a lot of new threads at a very high rate. This may eat up a lot of CPU time.

So the solution is to increase the thread_cache. When a client disconnects, the client’s threads are put in the cache if there aren’t more than thread_cache from before. All new threads are first taken from the cache, and only when the cache is empty is a new thread created. This variable can be increased to improve performance if you have a lot of new connections. (Normally this doesn’t give a notable performance improvement if you have a good thread implementation.) By examining the difference between the status variables Connections and Threads_created you can see how efficient the current thread cache is for you.â

If Threads_created is big, you may want to increase the thread_cache_size variable. The cache hit rate can be calculated with Threads_created/Connections.

4. Can I keep on increasing the size….?

The answer is NO!!. You should be aware of the resources available while tweaking the system variables. Here are some points you should take care of while optimizing your server.

4.1. DO NOT allocate too much memory.

Using less memory than available can reduce the performance, but using more memory than available can lead to worse performance or even crashes. A general resource allocation formula is

memory=key_buffer+(sort_buffer_size+read_buffer_size)*max_connections

4.2. Never let your box use the swap space actively.

Using swap space will affect the server performance badly.

4.3. Do not just scale the sample config file blindly.

If the my-huge.cnf (for 1GB memory) has some variable=1MB. And suppose you are having 16GB so you should set it to 16MB.. NO!! Set the variables wisely.

4.4. Consider per session variable.

Suppose you have set the sort_buffer_size for your server as 1MB and you have one query which requires more sort_buffer_size (say 16MB). Do NOT set sort_buffer_size=16M globally.

Use SET command to increase the sort_buffer_size

execute the command and

change it to 1MB using SET command.

5. All set….??.. NO!!

Mentioned above are only 7 of the 100+ system variables. There are several other variables which can be tweaked.

Tuning server parameters can increase the performance. But this doesn’t mean that MySQL optimization is only Server parameters’ optimization. No.. The database design and the SQL queries used also plays an equally important role. In fact, I would say Schema and Queries hold an upper hand. If the database is properly designed and the queries are properly created, tuning server parameters will make your server / site lightning speed..

Enjoy using MySQL….

Running Multiple MySQL versions

MySql No Comments »

Sometimes we may require to run multiple versions of MySQL on the same Server. This can happen if you either need to test a new MySQL release or you need a new MySQL version and you don’t want to make any changes to the existing system.

The whole idea behind this is to compile the new MySQL server with different TCP/IP ports and Unix socket files so that each one is listening on different network interfaces. Compiling in different base directories for each installation also results in separate compiled-in data directory, log file, and PID file location for each server.

First download the source the tar file from mysql.com.

$> tar xfz mysql.tar.gz
$> cd mysql.XX

* Important **
“/etc/my.cnf ” is the default file that is used by a mysql server. When the new version is tested it will load the default configuration’s in /etc/my.cnf.

To resolve this I replaced every instance of ” cnf ” inside the source folder to ” conf ” by using this following command.

find ./ -type f | xargs perl -pi -w -e 's/cnf/conf/g;'

1) The default user generally is “mysql”. Add another user and group for example mysqlt for the new version of MySQL.

2) A typical ./configure command…

./configure --prefix=/usr/local/mysql --enable-local-infile
--with-tcp-port=4444 --with-mysqld-user=mysqlt
--with-base_dir=/usr/local/mysql --with-log=/usr/local/mysql/mysqld.log
--with-pid_file=/usr/local/mysql/mysqld.pid
-with-unix-socket-path=/tmp/mysqlt.sock --localstatedir=/var/lib/mysqlt

The new values you will use for your new MySQL server are:

Port number : 4444

mysql user : mysqlt

base_dir :  /usr/local/mysql

data directory : /var/lib/mysqlt

log file : /usr/local/mysql/mysqld.log

3) Compile and Install

make && make install

4)Create your new MySQL config file.

cp support-files/my-medium.conf /etc/my.conf
cd /usr/local/mysql
bin/mysql_install_db --user=mysqlt
( this will install all the needed databases )
bin/mysqld_safe --user=mysqlt &

TO SET A PASSWORD FOR THE MySQL root USER

/usr/local/mysql/bin/mysqladmin -u root -h hostname password 'new-password'

/usr/local/mysql/bin/mysqladmin -u root password 'new-password'

5) To start the service

cd /usr/local/mysql

./share/mysql/mysql.server start

6) To test

#telnet localhost 4444

and you should see this
Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

+ 4.0.26-logIE^*THL

And you are done. You can copy mysql.server >> rc.d to start it when the server is rebooted.

With these steps, you can download and configure different mysql versions to use different values for port, datadirectory, mysql user, configuration file etc….

Warning: You should never have two servers that update data in the same databases.

How to set up Database replication in MySQL

MySql No Comments »

This article describes how to set up database replication in MySQL. MySQL replication allows you to have an exact copy of a database from a master server on another server (say we can call it as slave), and all updates to the database on the master server are immediately replicated to the database on the slave server so that both databases are in sync.

This is not a backup method or policy because an accidentally issued DELETE or ALTER command will also be carried out on the slave; but replication can help protect against hardware failures though.

2. Configure The Master:

We can configure the master server for replication using the mysql configuration file /etc/my.cnf. We have to enable networking for MySQL, and MySQL should listen on all IP addresses, therefore we will comment these lines (if already existing in my.cnf)

 #skip-networking
 #bind-address            = 127.0.0.1

Now we have to configure the MySQL server for which database it should write logs (these logs are used by the slave to see what has changed on the master) and we have to specify that this MySQL server is the master. We want to replicate the database db_test, so we put the following lines into /etc/my.cnf

log-bin
binlog-do-db=db_test
server-id=1

Then restart MySQL:

 # /etc/rc.d/init.d/mysql restart

Then we need to log into the MySQL database as root and create a user with replication privileges:

mysql> GRANT REPLICATION SLAVE ON *.* TO 'u1@%' IDENTIFIED BY 'p1';
mysql> FLUSH PRIVILEGES;

Next (still on the MySQL shell) do this:

mysql> USE db_test;
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;

The sample master status will be as follows:

mysql> show master status;
+----------------+----------+--------------+------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| rs2-bin.000063 |       79 | db_test      |                  |
+----------------+----------+--------------+------------------+
1 row in set (0.00 sec)

We need this information later on for the slave configuration Then leave the MySQL shell:

mysql> quit;

3.Configure The Slave:

We can configure the slave server for replication using the file /etc/my.cnf. We have to tell MySQL on the slave that it is the slave, that the master is H1, and that the master database to watch is db_test. Therefore we add the following lines to /etc/my.cnf

server-id=2
master-host=H1
master-user=u1
master-password=p1
master-connect-retry=100
replicate-do-db=db_test

The master-user and master-password are those to which we set when we granted REPLICATION SLAVE permission on the master. The server-id must be a unique number, different to the master or any other slaves in the system. The master-connect-retry is time in seconds for the slave to attempt to reconnect if the master goes down. 60 seconds is default.

Then restart MySQL:

# /etc/rc.d/init.d/mysql restart

4.Data Transfer:

There are two possibilities to get the existing tables and data from db_test from the master to the slave. The first one is to make a database dump, the second one is to use the LOAD DATA FROM MASTER; command on the slave.

(a)For Mysqldump method:

On master server, please take the dump of the database using

# mysqldump  db_test>db_test.sql
Then scp the file db_test.sql to slave server.
# Scp db_test.sql root@slave_serverip:/root
root@slaveip's password:

Restore the db_test.sql file at slave server

# mysqldump db_test < db_test.sql

(b)To LOAD DATA FROM MASTER:

Please perform the following at Master end:

# mysql -u root -p
Enter password:
mysql> UNLOCK TABLES;
mysql> quit;

Please perform the following at Slave end:

# mysql -u root -p
Enter password:
mysql> LOAD DATA FROM MASTER;
mysql> quit;

5. Replication in action:

Once the mysql master and slave configuration completed, we can check the replication action using the command ‘SHOW SLAVE STATUS’.

We can check if the slave is running correctly by looking at the Slave_IO_Running and Slave_SQL_Running. The most important field is the Last_Error field.

Mysql> SHOW SLAVE STATUSG

This will give the result as follows:
mysql> SHOW SLAVE STATUSG
*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: H1
                Master_User: u1
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: rs2-bin.000063
        Read_Master_Log_Pos: 346
             Relay_Log_File: vrh-relay-bin.000001
              Relay_Log_Pos: 312
      Relay_Master_Log_File: rs2-bin.000063
           Slave_IO_Running: Yes
          Slave_SQL_Running: Yes
            Replicate_Do_DB: db_test
        Replicate_Ignore_DB:
         Replicate_Do_Table:
     Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
                 Last_Errno: 0
                 Last_Error:
               Skip_Counter: 0
        Exec_Master_Log_Pos: 346
            Relay_Log_Space: 312
            Until_Condition: None
             Until_Log_File:
              Until_Log_Pos: 0
         Master_SSL_Allowed: No
         Master_SSL_CA_File:
         Master_SSL_CA_Path:
            Master_SSL_Cert:
          Master_SSL_Cipher:
             Master_SSL_Key:
      Seconds_Behind_Master: 0
1 row in set (0.00 sec)

If you need to force the slave to begin at a certain point, usually when the master has been running with an active binary log, you can do so as follows ( refer the master status value). The following starts with the 63rd binary log, as position 79.

mysql> CHANGE MASTER TO MASTER_HOST='H1',
MASTER_USER='u1',MASTER_PASSWORD='p1', MASTER_LOG_FILE='rs2-bin.000063', MASTER_LOG_POS=79;
MASTER_HOST is the IP address or hostname of the master (in this example it is H1).
MASTER_USER is the user we granted replication privileges on the master.
MASTER_PASSWORD is the password of MASTER_USER on the master.
MASTER_LOG_FILE is the file MySQL gave back when you ran SHOW MASTER STATUS; on the master.
MASTER_LOG_POS is the position MySQL gave back when you ran SHOW MASTER STATUS; on the master.

The SLAVE START and SLAVE STOP commands are used to manually stop and start the slave. The slave will also always stop if it comes across an error while replicating.

mysql> SLAVE STOP;
mysql> SLAVE START;

On active databases, the binary logs tend to grow quite quickly. We can use RESET MASTER to clear them. The RESET MASTER command tells the master to flush all its binary logs and start fresh. But while replication in action, we will have to execute the following.

mysql> PURGE MASTER LOGS TO 'rs2-bin.000063';

6. Options:

By default, the slave will replicate everything, but you can change this behavior with the following options in the slave configuration file (my.cnf).

replicate-do-db=db_name (replicate this database)
replicate-ignore-db=db_name (don't replicate this database)
replicate-do-table=db_name.table_name (replicate this table)
replicate-ignore-table=db_name.table_name (don't replicate this table)

7. Testing:

At master end if you are modifying the database db_test, it will reflect on slave server in real time using replication.

Example: On master slave if we are inserting the values as follows:-

mysql> use db_test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------+
| Tables_in_db_test |
+-------------------+
| staffactive       |
+-------------------+
1 row in set (0.00 sec)
mysql> desc staffactive;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| username | varchar(20) |      |     |         |       |
| date     | varchar(20) |      |     |         |       |
+----------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> INSERT INTO staffactive (username,date) VALUES ('savi','20070305');
Query OK, 1 row affected (0.02 sec)
mysql> INSERT INTO staffactive (username,date) VALUES ('testuser', 'testdate');
Query OK, 1 row affected (0.00 sec)
mysql> select * from staffactive;
+----------+----------+
| username | date     |
+----------+----------+
| savi     | 20070305 |
| testuser | testdate |
+----------+----------+
2 rows in set (0.00 sec)

mysql> q

Bye

This will reflect on the slave server in real time as follows:-

mysql> use db_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from staffactive;
+----------+----------+
| username | date     |
+----------+----------+
| savi     | 20070305 |
| testuser | testdate |
+----------+----------+
2 rows in set (0.00 sec)

mysql> q

Bye

How and why do e-mails bounce?

Exim No Comments »

When the intended recipient does not receive an e-mail and it is sent back to the sender, it is said that the e-mail has bounced. The sender receives an error message to that effect. But what exactly happens when an email bounces?

When an e-mail has been sent the sender’s e-mail system makes contact with the recipient’s mail server. The mail server checks for any message to allow or disallow such a mail to pass through. Some of the circumstances under which an email bounces are these:

Hard Bounce:

  1. The mail server has barred receiving of mails from the sender’s address. (For example, if the address of the sender is blocked.)
  2. The recipient’s mail server is too busy to handle the request.

Soft Bounce:

  1. The e-mail address does not exist on the recipient’s mail server.
  2. The e-mail address is erroneous or miss spelt.
  3. The recipient exists but does not have enough disk space to accept the message.
  4. If the message size is much bigger than the message size pre-decided by the server.

Sometimes, an e-mail may bounce back due to network failure on the recipient’s server

How to get the process id of my shell/connection

Linux No Comments »

To get the process id of my shell/connection using a single command
The answer is echo $$

#echo $$

The Kernel Debugging Tools for Linux

Linux No Comments »

Your Kernel just crashed or one of your drive is not working!! What do you do?

Well, this article gives an introduction to some kernel debugging tools for Linux. These tools makes the kernel internals more transparent. These tools help you to trace the kernel execution process and examine its memory and data structures.

The tools discussed here are :

1. Kernel debugger, kdb

2. Kernel GNU debugger, kgdb

3. GNU debugger, gdb

4. JTAG- based debuggers.

Of the mentioned tools, the kdb and kgdb were introduced as patches to the kernel code. The plain debugger gdb doesn’t need the patching process with kernel code. The JTAG (Joint Test Action Group) based debuggers are hardware assisted and powerful tools, but are expensive.

Here I will explain the installation and usage of the kdb tool. The rest of the tools are briefed.

Kernel debugger, kdb

Kdb is a project maintained by the Silicon Graphics. The main advantage of kdb is that you can debug the kernel that you are running on.

To install the kernel debugger:

1. Download and unzip the patches and apply them to your linux source tree.

Of the 2 patches, the ‘common’ patch contains the changes for the generic kernel code, and the other is the

2. You can get the required patches from

ftp://oss.sgi.com/projects/kdb/download/latest

You should choose the patches depending upon the kernel you are compiling. I compiled the latest 2.6.26 kernel. So I chose the following patches :

kdb-v4.4-2.6.26-rc9-common-1

kdb-v4.4-2.6.26-rc9-x86-1

3. Patch them to your kernel tree.

# cd /usr/src/kernels/linux – Path to your untarred linux kernel source

# patch -p1 < kdb-v4.4-2.6.9-rc4-common-1

# patch -p1 < kdb-v4.4-2.6.9-rc4-i386-1

If your patches are not successful you will get files with extensions .rej in the directory.

3. If successful, recompile the new kernel with the patches enabled using xconfig/menuconfig.

While compiling make sure the CONFIG_KDB option is enabled. You can also enable CONFIG_FRAME_POINTER for better debugging. But this uses an extra register and slightly slower kernel code. These options comes under ‘Kernel Hacking’ section.

The KDB commands to be executed during the initialization process can be defined in a plain text file called kdb_cmds, which exists in the kdb directory of the linux source tree. This file can also be used to define environment variables for setting the display and print options.

For me file was in this path : /usr/src/kernels/linux/kdb

The flags passed to kdb are of three

These flags can be passed at boot time to ensure that the KDB is On/Off. The Early flag helps to troubleshoot the problems during boot time.

KDB commands

KDB allows memory and register modification, applying breakpoints, and stack tracing.

Memory display and modification

Commonly used commands are : md, mdr, mm, and mmW.

1. The md command takes an address/symbol and a line count and displays memory starting at the address for line-count number of lines.

2. The mdr command takes an address/symbol and a byte count and displays the raw contents of memory starting at the specified address for byte-count number of bytes.

3. The mm command modifies memory contents.

4. The mmW command changes W bytes starting at the address.

Register display and modification

Commonly used commands are : rd, rm, and ef.

1. The rd command (without any arguments) displays the contents of the processor registers.

2. The rm command modifies the contents of a register.

3. The ef command takes an address as an argument and displays an exception frame at the specified address.

Stack tracing

The main stack tracing commands are bt, btp, btc, and bta.

1. The bt command attempts to provide information on the stack for the current thread.

2. The btp command takes a process ID as an argument and does a stack traceback for that particular

3. The btc command does a stack traceback for the running process on each live CPU.

4. The bta command does a traceback for all processes in a particular state. Without any argument, it does a traceback for all processes. Optionally, various arguments can be passed to this command. The processes in a particular state will be processed depending on the argument. The options and the corresponding states are as follows:

* D: Uninterruptible state

* R: Running

* S: Interruptible sleep

* T: Traced or stopped

* Z: Zombie

* U: Unrunnable

Breakpoints

The commonly used breakpoint commands are bp, bc, bd, be, and bl.

1. The bp command takes an address/symbol as an argument and applies a breakpoint at the address. It is similar to the bpa command except that it forces the use of a hardware register.

2. The bd command disables a particular breakpoint.

3. The be command enables a breakpoint. The argument to this command is also the breakpoint number.

4. The bl command lists the current set of breakpoints. It includes both the enabled and the disabled breakpoints.

5. The bc command removes a breakpoint from the breakpoint table. It takes either a specific breakpoint number as an argument or it takes *, in which case it will remove all breakpoints.

Kernel GNU debugger, kgdb

The kgdb developed initially as a patch is now included in the official 2.6.26 kernel. This source level debugging tool is much easier to use. It requires two machines to be connected via a serial connection (a RS-232 interface using null modem/a UDP/IP networking protocol).

The gdb is used along with kgdb to trace through kernel code. The gdb runs on the host machine and the kgdb patched kernel runs on the target machine.

GNU debugger, gdb

This is also a powerful stand alone tool used for debugging. But with this tool you can’t set the breakpoint or trace the kernel code. Instead you can use gdb to debug the core files which are dumped when an error occurs.

It leads us with clues on how to troubleshoot the problem.

JTAG- based debuggers

JTAG debuggers use hardware assistance to debug code. This needs a monitor and a front end API to debug the code. It can be used to debug the BIOS, the bootloader, real mode Linux kernel initialization code, and the protected mode kernel.

You can start the debugging mode via command line parameters that you pass to the kernel while booting up or using hardware or software break points. A break point is referred to as the point where the debugger takes in charge when the control is transferred at a point of execution.

If the instruction stops on flash memory and if the corresponding instruction cannot be replaced by the debugger you can use hardware breakpoint. A hardware breakpoint needs processor support. A software breakpoint can be set either using debugger commands or by inserting them into your code. Besides debugging, the second purpose of the JTAG interface is allowing device programmer hardware to transfer data into internal non-volatile device memory.

Conclusion:

After reading through you might be thinking, which one is the best debugger?

The commonly used ones are kdb and kgdb. These tools are aimed at different working environments. The decision depends upon mainly the design.

The kdb home page says like, “This debugger is part of the Linux kernel and provides a means of examining kernel memory and data structures while the system is operational. Additional commands may be easily added to format and display essential system data structures given an identifier or address of the data structure.”

The kgdb home page says like, “The kgdb is a source level debugger for Linux kernel. It is used along with gdb to debug Linux kernel.”

So try the tool you find suitable for your environment, then read more and hack your kernel…

Tips for successful Kernel Recompilation in Linux

Linux No Comments »

“Kernel compilation is a tough nut to crack” - Most frequently this would be followed by a sigh if the recompiled kernel is not booting up. Though the nut has the look of a tough one to crack, kernel recompilation is still an inescapable affair that every Linux system administrator runs into, sooner or later. I too had to. With this article, I intend to walk you through the phases of compiling a kernel. I am sure it will inspire confidence in you so that compiling a kernel is no longer a “mission impossible”.

What is a kernel?

Keeping it simple, kernel is the central part of most of the operating systems. The main functions of kernel include process management,resource management etc. It is the first part of operating system that is loaded in to the RAM when the machine is booted and it will remain in the main memory. Since the kernel stays in the main memory, it is important that it should be as small as possible.

In Linux, kernel is a single file called vmlinuz which is stored in the folder /boot, where vm represents virtual memory and z at the end of the filename denotes that it is compressed.
When do we recompile a kernel?
To reduce the size of the kernel:

Suppose you are a Linux fanatic and you need an OS in your mobile. The typical OS you get has the all the miscellaneous components and has size in many MB s, which you can’t afford in your mobile. If I were you, I would do a kernel recompilation, and remove unwanted modules.

When the size of the kernel is reduced removing the unwanted items, less memory will be used which in turn will increase the resource available to applications.
To add or remove support for devices:

For each device, a device driver is needed for communicating with the operating system. For example, if a USB device is attached to a computer, we need to enable the corresponding device driver for it to work. In technical terms, the support for USB driver is to be enabled in the kernel.
To modify system parameters:

System parameters include high memory support, quota support etc. For managing physical memory above 4 GB, high memory support (64 GB) needs to be enabled.
How do we recompile a kernel?

1. Verify and update the packages required
2. Obtain kernel source
3. Obtain current hardware details
4. Configure kernel
5. Build kernel
6. Configure the Boot loader
7. Reboot the server

1. Verify and update the packages required

You need to do this step only if you upgrade the kernel from version 2.4 to 2.6. You can skip this step if it is a 2.6.x to 2.6.x upgrade.

Before upgrading the kernel, you need to make sure that your system is capable of accepting the new kernel. Check the utilities that interact with your system, and verify that they are up-to-date. If they are not, go ahead and upgrade them first.

The main packages to be checked and upgraded are : binutils, e2fsprogs, procps, gcc and module-init-tools

You should take extreme care while upgrading module-init-tools. A module is a piece of code that can be inserted into the kernel on demand. Module-init-tools provide utilities for managing Linux kernel modules - for loading, unloading,listing and removing modules.

The main utilities available are :

* insmod
* rmmod
* modprobe
* depmod
* lsmod

Both modprobe and insmod are used to insert modules. The only difference is that insmod doesn’t know the location of the module and is unaware of dependencies. Modprobe does this by parsing the file /lib/modules/<kernel version>/modules.dep

How to install module-init-tools

Get the source http://www.kernel.org/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.2.2.tar.gz to the server using wget and untar it.

tar -zxf module-init-tools-3.2.2.tar.gz

2. Configure it.

cd module-init-tools-3.2.2
./configure –prefix=/

3. Rename the existing 2.4 version of this utility as utility.old

make moveold

4. Build and install.

make
make install

5. Run the script generate-modprobe.conf to convert the entries in the module configuration file for kernel version 2.4 ( /etc/modules.conf ) to a file used by kernel version 2.6 (/etc/modprobe.conf)

./generate-modprobe.conf /etc/modprobe.conf

6. Check the version of current module-init-tools

depmod -V

2. Obtain the Kernel Source

Get the kernel source from http://www.kernel.org/pub/linux/kernel/v2.6/

You can download the source to the /usr/src/kernels folder in your server. If you are planning to recompile your kernel to version 2.6.19.2, the steps would be :

[root]#cd /usr/src/kernels
[root]#wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.19.2.tar.gz
[root]#tar zxf linux-2.6.19.2.tar.gz
[root]#cd linux-2.6.19.2

3. Obtain the Current Hardware Details

The current Hardware details can be obtained using the following commands:
lspci

This utility gives the details about the network card and all devices attached to the machine. If you type lspci and get an error “lscpi: command not found”, you will have to install pciutils-2.1.99.test8-3.4 rpm in the server.

A typical lspci output will be as follows :

[root@XXXXX ~]# lspci
00:01.0 PCI bridge: Broadcom BCM5785 [HT1000] PCI/PCI-X Bridge
00:02.0 Host bridge: Broadcom BCM5785 [HT1000] Legacy South Bridge
00:02.1 IDE interface: Broadcom BCM5785 [HT1000] IDE
00:02.2 ISA bridge: Broadcom BCM5785 [HT1000] LPC
00:03.0 USB Controller: Broadcom BCM5785 [HT1000] USB (rev 01)
00:03.1 USB Controller: Broadcom BCM5785 [HT1000] USB (rev 01)
00:03.2 USB Controller: Broadcom BCM5785 [HT1000] USB (rev 01)
00:05.0 VGA compatible controller: ATI Technologies Inc Rage XL (rev 27)
00:18.0 Host bridge: Advanced Micro Devices [AMD]
K8 [Athlon64/Opteron] HyperTransport Technology Configuration
00:18.1 Host bridge: Advanced Micro Devices [AMD]
K8 [Athlon64/Opteron] Address Map
00:18.2 Host bridge: Advanced Micro Devices [AMD]
K8 [Athlon64/Opteron] DRAM Controller
00:18.3 Host bridge: Advanced Micro Devices [AMD]
K8 [Athlon64/Opteron] Miscellaneous Control
01:0d.0 PCI bridge: Broadcom BCM5785 [HT1000]
PCI/PCI-X Bridge (rev b2)
01:0e.0 RAID bus controller: Broadcom BCM5785 [HT1000]
SATA (Native SATA Mode)
02:03.0 Ethernet controller: Broadcom Corporation
NetXtreme BCM5704 Gigabit Ethernet (rev 10)
02:03.1 Ethernet controller: Broadcom Corporation
NetXtreme BCM5704 Gigabit Ethernet (rev 10)
[root@XXXXX ~]#

cat /proc/cpuinfo

The processor details can be obtained from the file /proc/cpuinfo

[root@XXXX ~]# cat /proc/cpuinfo
processor : 0
vendor_id : AuthenticAMD
cpu family : 15
model : 35
model name : Dual Core AMD Opteron(tm) Processor 170
stepping : 2
cpu MHz : 1996.107
cache size : 1024 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 1
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
cmov pat pse36 clflush mmx fxsr sse sse2 ht pni syscall nx mmxext fxsr_opt
lm 3dnowext 3dnow pni
bogomips : 3992.34
[root@XXXXX ~]#

modinfo

Another useful tool to obtain hardware information is modinfo. It gives detailed description about modules. Before using modinfo, you may need to find out currently loaded modules. lsmod is the utility that lists currently loaded modules.

[root@XXXXXX ~]# lsmod
libata 105757 1 sata_svw
[root@ XXXXXX~]#

lsmod displays a module sata_svw and more details of this module can be obtained as shown below.

[root@XXXXX ~]# modinfo sata_svw
filename: /lib/modules/2.6.9-55.ELsmp/kernel/drivers/ata/sata_svw.ko
author: Benjamin Herrenschmidt
description: low-level driver for K2 SATA controller
license: GPL
version: 2.0 9FF8518CB6CD3CB4AE61E35
vermagic: 2.6.9-55.ELsmp SMP 686 REGPARM 4KSTACKS gcc-3.4
depends: libata
alias: pci:v00001166d00000240sv*sd*bc*sc*i*
alias: pci:v00001166d00000241sv*sd*bc*sc*i*
alias: pci:v00001166d00000242sv*sd*bc*sc*i*
alias: pci:v00001166d0000024Asv*sd*bc*sc*i*
alias: pci:v00001166d0000024Bsv*sd*bc*sc*i*
[root@xxxxxx~]#

4. Configure the Kernel

Once you have the source, the next step is to configure the kernel.

You can configure the kernel using any of the following :

1. make config - This is a text based command line interface that will ask each and every configuration question in order.
2. make xconfig - This is a graphical editor that requires x to be installed in the system. Hence it is not used in servers.
3. make oldconfig - A text based interface that takes an existing configuration file and queries for any variable not enabled in that configuration file.
4. make menuconfig - A text based menu configurator based on cursor-control libraries. This is the most commonly used method for configuring kernels in servers.

If you are a newbie, I would recommend using the existing configuration and use make menuconfig to configure the kernel.

Steps for configuring your kernel are :
Step 1: Copy the current kernel configuration to your new kernel source.

[root@XXXXX ~]#pwd
/usr/src/kernels/linux-2.6.19.2
[root@XXXXX ~]#cp /boot/config-<current_kernel_version> .config
[root@XXXXX ~]#make oldconfig

where <current_kernel_version> should be replaced with the existing kernel version in the server. You can get <current_kernel_version> in the server using the command :

[root@XXXXX ~]# uname -r
2.6.9-67.ELsmp2.6.9-67.ELsmp
[root@XXXXX ~]#

When make oldconfig prompts for values, retain the old values.Even if you retain the old values, don’t forget to check the hardware of the server as well as the processor type and the model of the ethernet card. Since options change with newer kernel versions, and some options may not be there in the old .config files, it is advisable to double check all the options using menuconfig.
Step 2: make menuconfig.

[root@XXXXX ~]#make menuconfig

This is the main screen of menuconfig. Only some options can be compiled as modules. In menuconfig, they are marked < >. Press M to compile as a module. A [*] means compiled in, M means module.

kernel11

menuconfigMenuconfig offers search feature. Use “/” to search for any module. For eg: if you are not sure of the location of the module iptables, press “/” , enter the search pattern as “iptables” and press enter.

Search for configuration parameter

menuconfig search results

As there are a lot of options in menuconfig, I will just mention the important ones. The essential options needed for a kernel to be running is processor, file system, network card and hard disk. You can select the desired processor, file system, hard disk and network card from the options available in menuconfig.

Processor type and features

Subarchitecture Type : Select Generic architecture (Summit,bigsmp, ES7000, default)

Processor family : Select the matching processor from the available list. For eg : If the model name is Dual Core AMD Opteron(tm) Processor 170 , you can select Opteron/Athlon64/Hammer/K8 from the options available.

For a multiprocessor server, enable the options Symmetric multi-processing support and SMT (Hyper threading) scheduler support.

For RAM > 4 GB enable the option High Memory Support (64GB) . And the final output of the option Processor type and features would look like this :

menuconfig processor type

Networking

Iptables is enabled in this option.

Location:
-> Networking
-> Networking support (NET [=y])
-> Networking options
-> Network packet filtering (replaces ipchains) (NETFILTER [=y])
-> Core Netfilter Configuration and IP: Netfilter Configuration

All the modules under the option Core Netfilter Configuration and IP: Netfilter Configuration should be enabled as modules.

Device Drivers

This is the most confusing part. In this, the main options you need to check are :

1. Block devices : Enable RAM disk support and Loop back device support

Include Loopback device support (module)
RAM disk support [*} compiled in
Leave the default values of RAM disk number and size.
Initial RAM disk (initrd) support [*} compiled in

2. SCSI device support : Enable corresponding model in SCSI low level drivers if it is a SCSI device.

3. Serial ATA (prod) and Parallel ATA (experimental) drivers: if hard disk is SATA, enable the corresponding driver in this. For eg: if you have Intel PIIX/ICH SATA in the server enable Intel PIIX/ICH SATA support in this option

4. Network device support : Enable the corresponding network card in the server. For eg: if lspci lists the network card as follows :

Ethernet controller: Broadcom Corporation NetXtreme BCM5704 Gigabit Ethernet

Then enable

> Network device support
> Ethernet (1000 Mbit)ss
> Broadcom NetXtremeII support

File Systems

The main modules to be enabled in this section are ext2, ext3, journaling and Quota support.

Once this is complete , save the settings and quit.
5. Build the Kernel

The next step is to build the Kernel. You can use the command make bzImage to do this. This command will create a compressed file bzImage inside arch/i386/boot in the Linux source directory and that is the newly compiled kernel.

The next step is to compile and link the modules. This can be done using the command make modules.

After this you have to copy the modules to /lib/modules/. And this is done using the command make modules_install.

The command sequence is as follows :

make -j<Number> bzImage
make -j<Number> modules
make -j<Number> modules-Install

-j tells your system to do that many jobs in Makefile together which will in turn reduce the time for compilation.

<Number> is two times the number of cpus in your system or number of virtual processors. This number can be found using the command

cat /proc/cpuinfo | grep ^processor | wc -l

[root@XXXX]# cat /proc/cpuinfo | grep ^processor | wc -l
2

Once this is done copy all these to the /boot folder as follows :

cp .config /boot/config-2.6.19.2
cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.19.2
cp System.map /boot/System.map-2.6.19.2
mkinitrd /boot/initrd-2.6.9.img 2.6.19.2

mkinitrd is the program to create initial RAM Disk Image.
6. Configure Boot Loader

Boot loader is the first program that runs when a computer boots. There are two types of boot loader :

* GRUB
* LILO

1. Determine the currently installed boot loader :

Check first 512 bytes of the boot drive. Check for grub first:

# dd if=/dev/hda bs=512 count=1 2>&1 | grep GRUB

If it matches, the current boot loader is grub. Check for lilo if it did not match:

# dd if=/dev/hda bs=512 count=1 2>&1 | grep LILO

Note : If the hard disk is SCSI or SATA, use sda instead of hda..
2. Configure the boot loader

If your boot loader is LILO, add entries for the new kernel in the file /etc/lilo.conf. A typical lilo entry will be as given below :

image=/boot/vmlinuz-2.6.19.2
label=linux
initrd=/boot/initrd-2.6.19.2.img
read-only
append=”console=tty0 console=ttyS1,19200n8 clock=pmtmr root=LABEL=/”

Run the command :

lilo -v
/sbin/lilo -R “Label for new kernel”

In the case of GRUB, add the entries for the new kernel at the end of the list of kernels in the file /etc/grub.conf. The first entry in GRUB gets the index 0. An example entry is below :

title Red Hat Linux (2.6.19.2)
root (hd0,0)
kernel /boot/vmlinuz-2.6.19.2 ro root=/dev/hda2 panic=3
initrd /boot/initrd-2.6.19.2

The “panic” parameter ensures that the server reboots to the old kernel, in the case of a kernel panic i.e the machine will be rebooted to the default option in grub.conf, if a panic occurs in 3 secs.

Do Not change the “default” value in the file grub.conf. Enter grub command prompt by typing the command grub at the prompt. Enter the below command at the grub prompt:

savedefault –default=3 –once

This is the case if the newly added entry is having index 3. Exit from grub-shell.
7.Reboot the Server

Reboot the server using the command reboot. If by any chance, a kernel panic occurs, server will be up with the old working kernel. If everything goes fine, the server will be up with the new kernel. Once it is up with the new kernel, do not forget to change the default value in the boot loader.
Conclusion

Booting a newly recompiled kernel in your first attempt is a tough task and is at times thought impossible. Following the above steps and keeping the compilation tricks in mind, there is no doubt Kernel Compilation will now be a piece of cake.
Acknowledgment

My sincere thanks to all my friends

Extending Disk Space with LVM

Linux No Comments »

Managing Disk space on live servers is often a complex and also a time and energy consuming job. It can be made a lot more easier with use of Logical Volume Manager, or better known as LVM in short. This article is a complete guide on managing your disk space using LVM, its requirements and also some of the most commonly used LVM commands and files.

I came to face a situation in which a VDS - Virtual Dedicated Server (similar to VPS) master server had 100% disk space usage for “/” partition and the users were not able to upload files even of KB size to theirsites. The server had lots of nodes and it might have taken at-least 2 hours for it to come back online, if we reboot the server, as per its own custom settings. I was in a situation to solve that problem as quickly as possible.

Luckily the server had ‘Logical Volume Manager’ or ‘LVM’. I created a logical volume of 20GB size and moved some files to the newly created logical volume. The issue was solved instantly and I got hooked into LVM.

I researched about the technology in more depth and thought of sharing the LVM techniques I learned with you.
Introduction to LVM

LVM stands for “Logical Volume Manager” which helps to manage the UNIX/Linux storage systems in a flexible way. LVM combines multiple hard drives into pools of storage space called Volume Groups. These volume groups are further subdivided into virtual hard disks which are called Logical Volumes. The logical volumes are used just like hard disk partitions in the non-LVM systems. The file systems will be created on these logical volumes and it will be mounted in the server. After mounting the logical volumes, we can use that logical partition. Unlike the normal hard disk partitions, the logical volumes can be expanded and shrunk without any problem, while the system is running.

LVM was added to the Linux kernel from the 2.4.x series, so it is supported by almost all Linux distributions. Basically there are 2 versions of LVM. They are LVM1 and LVM2, LVM2 being the latest. It is also the most commonly used and more efficient version of LVM. LVM 2 needs the linux kernel module “device-mapper”. Device mapper support is present in the linux 2.6 kernel tree and there are patches for the 2.4 kernels. This article mainly describes the LVM2 tools.
LVM Benefits

1. Fault tolerance can be achieved along scalability by using LVM in combination with RAID. It also provides for easy disk management.
2. It Can create a logical volume and filesystem which spans multiple disks.
3. Administrators can create different file systems for the logical volumes and can use that small partitions for different projects.
4. You can easily add the free space to the logical volume group any time without distracting the current partition setup of the server.

Terminologies Used in LVM

Every technology have their own terms and definitions. LVM has also some terms in order to define its functions. I will briefly explain LVM terms in this session.

1. Physical Partitions or Physical Volume(PV)

Physical volume (PV) are hard drives which is used as the base of LVM. It is the storage medium of LVM.
2. Volume Group(VG)

A group of “Physical Volume” is called “Volume Group”. It is the storage pool.
3. Logical Volume(LV)

Logical Volume is equivalent to a disk partition “/dev/sda” or “/dev/hda” in the non-LVM system. We have to mount the “Logical Volumes” in the server.

LVM Setup Order

The LVM setup order is given below. It starts from top to bottom.

1. Physical Drives (sda, sdb,sdc etc)
2. Physical Volumes created from the Physical Drives(/dev/sda1, /devsdc2 etc)
3. Volume Group comprising the physical volumes
4. Logical Volumes (Thease are similar to the partitions in the non-LVM system)
5. Mount points for the logical volumes(/home, /usr/, etc)

Requirements

If you need to use LVM, make sure the following support are present in your Linux system kernel.

1. Device-mapper

Device-mapper is a generic framework to map one block device into another. It forms the foundation of LVM2. Device mapper support is present in the 2.6 linux kernel tree and there are patches available for current 2.4 linux kernels. If your Linuxsystem kernel does not have the device-mapper support, you have to install device-mapper and have to recompile the Linux kernel to enable the device-mapper support.
2. LVM

LVM must be installed in the server. Once installed, there are lot of commands to manage the logical volumes in the server.
3. Device-mapper and LVM support in Linux Kernel

You must ensure that the LVM support is enabled in your kernel. If the support is not enabled, you have to recompile the Linux kernel to enable that support.

Now lets see how we can install Device-mapper and LVM, then enable their support in Kernel.
Device-mapper Installation

These steps will help you to install device-mapper in your server.

1. Change the directory to /usr/src and get the device-mapper source code from the following link.

<A href=”ftp://sources.redhat.com/pub/dm/””target=”_blank”>ftp://sources.redhat.com/pub/dm/

bash-3.1$ cd /usr/src/
bash-3.1$ wget ftp://sources.redhat.com/pub/dm/device-mapper.1.00.21.tgz
–18:01:36– ftp://sources.redhat.com/pub/dm/device-mapper.1.00.21.tgz
=> `device-mapper.1.00.21.tgz&aps
Resolving sources.redhat.com… 209.132.176.174
Connecting to sources.redhat.com|209.132.176.174|:21… connected.
Logging in as anonymous … Logged in!
==> SYST … done. ==> PWD … done.
==> TYPE I … done. ==> CWD /pub/dm … done.
==> SIZE device-mapper.1.00.21.tgz … 875083
==> PASV … done. ==> RETR device-mapper.1.00.21.tgz … done.
Length: 875083 (855K)

100%[==================================>] 875,083 115K/s in 7.4s

18:01:48 (115 KB/s) - `device-mapper.1.00.21.tgz saved [875083]

2. Untar the source code

bash-3.1$ tar -zxvf device-mapper.1.00.21.tgz

3. Change to the device-mapper source directory

bash-3.1$ cd device-mapper.1.00.21

4. Configure device-mapper

bash-3.1$ ./configure –with-kernel-dir=/usr/src/kernels/2.6.18-1.2798.fc6-i686

5. Compiling the device-mapper

bash-3.1$ make

6. Install device-mapper

bash-3.1$  make install

Now confirm the installation by checking for the module “libdevmapper.so” in the server.

LVM Installation

There are the steps to install LVM tool in the server.

1. Change the directory to /usr/src and get the LVM source code from the following link:

<A href=”ftp://sources.redhat.com/pub/lvm2/””target=”_blank”>ftp://sources.redhat.com/pub/lvm2/

bash-3.1$ cd /usr/src/
bash-3.1$ wget ftp://sources.redhat.com/pub/lvm2/LVM2.2.02.29.tgz
–18:08:21– ftp://sources.redhat.com/pub/lvm2/LVM2.2.02.29.tgz
=> `LVM2.2.02.29.tgz&aps
Resolving sources.redhat.com… 209.132.176.174
Connecting to sources.redhat.com|209.132.176.174|:21… connected.
Logging in as anonymous … Logged in!
==> SYST … done. ==> PWD … done.
==> TYPE I … done. ==> CWD /pub/lvm2 … done.
==> SIZE LVM2.2.02.29.tgz … 537138
==> PASV … done. ==> RETR LVM2.2.02.29.tgz … done.
Length: 537138 (525K)
100%[===================================================>] 537,138

140K/s in 3.7s 18:08:30 (140 KB/s) - `LVM2.2.02.29.tgz saved [537138]

2. Untar the source code

bash-3.1$ tar -zxvf LVM2.2.02.29.tgz

3. Change to the LVM source directory

bash-3.1$ cd LVM2.2.02.29

4. Configure LVM

bash-3.1$ ./configure

5. Compiling LVM

bash-3.1$ make

6. Install LVM

bash-3.1$ make install

LVM is now installed in the server.
Recompiling Kernel

Now we have to configure and recompile kernel in order to enable the device-mapper support and LVM support in the kernel.

You have to apply patch for the device-mapper in the current kernel if that does not have device-mapper support.

1. Applying Device-mapper patch
1. Change to linux kernel directory.

bash-3.1$  cd /usr/src/kernels/2.6.18-1.2798.fc6-i686/

2. Apply patch.

bash-3.1$  patch -p1 <
/usr/src/device-mapper.1.00.19/patches/kernelversion-rc1
-devmapper-ioctl.patch

2. Getting the menuconfig interface

bash-3.1$ make menuconfig

3. Enable the following options in the kernel configuration

Multi-device support (RAID and LVM)
[*] Multiple devices driver support (RAID and LVM)
[] RAID support
[ ] Linear (append) mode
[ ] RAID-0 (striping) mode
[] RAID-1 (mirroring) mode
[ ] RAID-4/RAID-5 mode
[ ] Multipath I/O support
[*] Logical volume manager (LVM) support
[*] Device-mapper support (NEW)

4. Recompile the kernel

bash-3.1$ make dep clean bzImage

Using LVM

1. Creating Physical Partition

You can start partitioning by running the command fdisk on the target hard drive (for example, /dev/sda or /dev/sdc). Note that you should use ‘8e’ type of physical partition for LVM rather that than the normal ‘83? type. In this example, I used the target hard drive as “dev/sdc”.

bash-3.1$ fdisk /dev/sdc

After executing the above command, you will get a command prompt with the message including the number of cylinders of the disk like this:

The number of cylinders for this disk is set to 1958.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)

Command (m for help):

You have to enter “n” (without quotes) in the prompt in order to create a new partition on the target hard drive. Enter ‘p’ to create a primary partition. Then you have to specify the size of the new partition in terms of cylinders within the specified limit. For that you have to enter the values which are within the specified limit.

A primary partition is now created. Next we have to change the partition type of that partition. That is, change the partition’s system id value to 8e, instead of the default 83. You have to enter “t” to change the partition type.

After changing the partition type of the selected partition, enter “w” for altering the partition table.
2. Creating Physical Volume(PV)

Now we have to create PV. PV can be created by “pvcreate” command. Lets assume that we have 2 physical partitions /dev/sdc1 and /dev/sde1.

bash-3.1$ pvcreate /dev/sdc1 /dev/sde

Now the physical volumes are ready.
3. Creating Volume Group

Now we need to create the Volume Group(VG) from the newly setup physical volumes.

bash-3.1$ vgcreate test_vgname /dev/sdc1 /dev/sde

4. Create Logical Volume

We are one step shot to create the logical volume which is similar to the physical partition in the non-LVM system. It can be created by the command “lvcreate”.

bash-3.1$ lvcreate -L 200 -n my_test_lv test_vgname

It will create a logical volume with name “my_test_lv” in the volume group “test_vgname” and size will be 200MB.
5. File system for logical volume

You have to add the file system in the newly created logical volume in order to use that.

bash-3.1$ mkfs -t ext3 /dev/test_vg/my_test_lv

6. Mount the logical volume

Create the mount point for the logical volume and then mount the logical volume.

bash-3.1$ mkdir /usr/test

bash-3.1$ mount /dev/test_vgname/my_test_lv /usr/test

7. Add entry in the “/etc/fstab” file

You have to add the following entry in the file “/etc/fstab” in order to enable that device even after the server boot.

/dev/test_vgname/my_test_lv /usr/test ext3 0 0

You will be able to see the newly created logical volume in the result of the command “df -h”.

[root@localhost /]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 15G 7.0G 6.6G 52% /
/dev/hdc1 190M 32M 149M 18% /boot
tmpfs 501M 0 501M 0% /dev/shm
/dev/mapper/my_test_lv
200M 177M 38G 1% /usr/test
[root@localhost /]#

Resizing Logical Volumes
Extend Logical Volume

There are the steps to be taken in order to extend the size of the existing logical volumes.I will explain the steps with an example. Suppose the logical volume name is “/dev/test_vgname/my_test_lv” and the mount point is “/usr/test”.

1. Unmount the mount point directory for the logical volume “/dev/test_vgname/my_test_lv” which you want to extend.

umount /usr/test

2. Extend the size of the logical volume “/dev/test_vgname/my_test_lv”.

lvextend -L500 /dev/test_vgname/my_test_lv

3. Apply the changes to the file system in the logical volume.

e2fsck -f /dev/test_vgname/my_test_lv

4. Re-size the logical volume

resize2fs /dev/test_vgname/my_test_lv

5. Mount the extended logical volume again

mount /dev/test_vgname/my_test_lv /usr/test

Shrinking/Reducing Logical Volume

First we have to shrink the filesystem of the logical volume before we reduce the logical volume’s size.

I am also explaining this section with an example. Suppose the logical volume name is “/dev/test_vgname/my_test_lv” and the mount point is “/usr/test”.

1. Unmount the mount point directory for the logical volume “/dev/test_vgname/my_test_lv” which you want to extend.

umount /usr/test

2. Apply the changes to the file system in the logical volume.

e2fsck -f /dev/test_vgname/my_test_lv

3. Re-size the file system in the logical volume.

resize2fs /dev/test_vgname/my_test_lv blocksize

4. Shrink the logical volume.

lvreduce -L200 /dev/test_vgname/my_test_lv

5. Mount the reduced logical volume again

mount /dev/test_vgname/my_test_lv /usr/test

LVM commands and Examples

1. pvcreate

pvcreate command initializes entire hard disk or the physical partitions for the LVM usage.

Syntax :

pvcreate partition partition …..

Example:

[root@localhost ~]# pvcreate /dev/hdc4
Physical volume “/dev/hdc4? successfully created
[root@localhost ~]#

The above command will initializes the 4th partition on the third hard disk for LVM usage.
2. vgcreate

vgcreate will create a logical volume from the physical partitions which are already initialized by the pvcreate command.

Syntax :

vgcreate volume_group_name partition partition …

Example :

[root@localhost ~]# vgcreate test_vgname /dev/hdc4
Volume group “test_vgname” successfully created
[root@localhost ~]#

The above command will create a volume group with the 4th partition on the third hard disk. The name for the volume group will be “test_vgname”.
3. lvcreate

lvcreate will create the logical volumes from the newly created volume group. These are similar to the physical partitions in the non-LVM systems.

Syntax :

lvcreate -L size -n logical_volume_name volume_group_name

Example :

[root@localhost ~]# lvcreate -L100 -n test_lv test_vgname
Logical volume “test_lv” created
[root@localhost ~]#

The above command will create a logical volume from the volume group “test_vgname” with a size 100MB.

You have to create file system on the newly created logical volume in order to mount that newly created logical volumes. The command will be like this.

[root@localhost ~]# mkfs -t ext3 /dev/test_vgname/test_lv
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
25688 inodes, 102400 blocks
5120 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
13 block groups
8192 blocks per group, 8192 fragments per group
1976 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729

Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 32 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@localhost ~]#

Mount command will be like the following.

[root@localhost ~]# mount /dev/test_vgname/test_lv /usr/local/test
[root@localhost ~]#

You have to add the following entry in the file “/etc/fstab” in order to make the logical volume active in the server even after the server reboot.

/dev/test_vgname/test_lv /usr/local/test ext3 0 0

4. pvdisplay

pvdisplay displays the physical partition details.

Syntax :

pvdisplay

Example : [

root@localhost ~]# pvdisplay
— Physical volume —
PV Name /dev/hdc4
VG Name test_vgname
PV Size 59.59 GB / not usable 0
Allocatable yes
PE Size (KByte) 4096
Total PE 15254
Free PE 15229
Allocated PE 25
PV UUID MUc2av-FrNc-iqQM-60aQ-5LX5-4LQt-0FfjG3

[root@localhost ~]#

The main variables in the pvdisplay command result are given below.

PV Name : Name of the physical partition
VG Name : Volume group name in which the specified physical partition contains
PV Size : Size of the physical partition

5. vgdisplay

vgdisplay displays the volume group details in the server, ie the container for the logical volumes.

Syntax:

vgdisplay

Example:

[root@localhost ~]# vgdisplay
— Volume group —
VG Name test_vgname
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 2
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 1
Act PV 1
VG Size 59.59 GB
PE Size 4.00 MB
Total PE 15254
Alloc PE / Size 25 / 100.00 MB
Free PE / Size 15229 / 59.49 GB
VG UUID 63hHkT-HWEG-Gz5C-yzu0-nm1D-D2BV-xFMVnU

[root@localhost ~]#

VG Name : Volume group name
VG Size : Size of the volume group
Cur LV : Number of LV&apss created from that Volume Group
Open LV : Number of active LV&apss of that Volume Group
Cur PV : Number of Physical Volumes contained in the Volume Group
Act PV : Active Physical Volume of that Volume Group
Format : This is the type of LVM

6. lvdisplay

lvdisplay displays the logical volume details of the server.

Syntax :

lvdisplay

Example :

[root@localhost ~]# lvdisplay
— Logical volume —
LV Name /dev/test_vgname/test_lv
VG Name test_vgname
LV UUID 6FKjS4-cusv-zXRH-Zjmx-Qi6T-tAoO-SZhKVw
LV Write Access read/write
LV Status available
# open 1
LV Size 100.00 MB
Current LE 25
Segments 1
Allocation inherit
Read ahead sectors 0
Block device 253:0

[root@localhost ~]#

The main variables in the pvdisplay result are given below.

LV Name : Logical volume name
VG Name : The volume group from which that logical volume is created
LV Status : The status of the logical volume
LV Size : Size of the logical volume

7. vgextend

vgextend command extends the size of the volume group by adding new physical partitions or hard disks to the already created volume group.

Syntax:

vgextend volume_group new_physical_ partition

Example :

[root@localhost ~]# vgdisplay
— Volume group —
VG Name new
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 100.00 MB
PE Size 4.00 MB
Total PE 25
Alloc PE / Size 0 / 0
Free PE / Size 25 / 100.00 MB
VG UUID oAzDGc-InRZ-6HCn-EnJ2-Hkk9-0pL2-e7jKNE

[root@localhost ~]# vgextend new /dev/hdc4 Volume group “new” successfully extended [root@localhost ~]#

[root@localhost ~]# vgdisplay
— Volume group —
VG Name new
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 2
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size 59.68 GB
PE Size 4.00 MB
Total PE 15279
Alloc PE / Size 0 / 0
Free PE / Size 15279 / 59.68 GB
VG UUID oAzDGc-InRZ-6HCn-EnJ2-Hkk9-0pL2-e7jKNE

8. lvextend

lvextend command extends the logical volume size in the server.

Syntax :

lvextend -L+size logical_volume_name

Example :

[root@localhost ~]# umount /root/test
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 15G 7.0G 6.6G 52% /
/dev/hdc1 190M 32M 149M 18% /boot
tmpfs 501M 0 501M 0% /dev/shm
[root@localhost ~]#

[root@localhost ~]# lvextend -L+30G /dev/test_vgname/test_lv
Extending logical volume test_lv to 40.00 GB
Logical volume test_lv successfully resized
[root@localhost ~]#

[root@localhost ~]# e2fsck -f /dev/test_vgname/test_lv
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/test_vgname/test_lv: 11/1310720 files (9.1% non-contiguous),
46895/2621440 blocks
[root@localhost ~]#

[root@localhost ~]# resize2fs /dev/test_vgname/test_lv
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/test_vgname/test_lv to 10485760 (4k) blocks.
The filesystem on /dev/test_vgname/test_lv is now 10485760 blocks long.
[root@localhost ~]#

[root@localhost ~]# mkdir test2
[root@localhost ~]# mount /dev/test_vgname/test_lv test2
[root@localhost ~]#

[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 15G 7.0G 6.6G 52% /
/dev/hdc1 190M 32M 149M 18% /boot
tmpfs 501M 0 501M 0% /dev/shm
/dev/mapper/test_vgname-test_lv
40G 30M 38G 1% /root/test2
[root@localhost ~]#

9. lvremove

lvremove command removes the existing logical volumes from the server.

Syntax :

lvremove logical_volume_name

Example :

[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 15G 7.0G 6.6G 52% /
/dev/hdc1 190M 32M 149M 18% /boot
tmpfs 501M 0 501M 0% /dev/shm
/dev/mapper/test_vgname-hello
20M 172K 19M 1% /root/test
/dev/mapper/test_vgname-test_lv
49G 5.1M 46G 1% /usr/local/test
[root@localhost ~]#
[root@localhost ~]# umount /root/test
[root@localhost ~]# lvremove /dev/test_vgname/hello
Do you really want to remove active logical volume “hello”? [y/n]: y
Logical volume “hello” successfully removed
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 15G 7.0G 6.6G 52% /
/dev/hdc1 190M 32M 149M 18% /boot
tmpfs 501M 0 501M 0% /dev/shm
/dev/mapper/test_vgname-test_lv
49G 5.1M 46G 1% /usr/local/test
[root@localhost ~]#

10. lvreduce

lvreduce command will reduce the size of the logical volumes.

Syntax:

lvreduce -Lsize logical_volume_name

Example :

[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 15G 7.0G 6.6G 52% /
/dev/hdc1 190M 32M 149M 18% /boot
tmpfs 501M 0 501M 0% /dev/shm
/dev/mapper/test_vgname-hello
20M 172K 19M 1% /root/test
[root@localhost ~]#
[root@localhost ~]# umount /root/test
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# e2fsck -f /dev/test_vgname/hello
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/test_vgname/hello: 11/5136 files (9.1% non-contiguous), 825/20480 blocks
[root@localhost ~]# e2fsck -f /dev/test_vgname/hello
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/test_vgname/hello: 11/5136 files (9.1% non-contiguous), 825/20480 blocks
[root@localhost ~]# lvreduce -L10M /dev/test_vgname/hello
Rounding up size to full physical extent 12.00 MB
WARNING: Reducing active logical volume to 12.00 MB
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce hello? [y/n]: y
Reducing logical volume hello to 12.00 MB
Logical volume hello successfully resized
[root@localhost ~]# mount /dev/test_vgname/hello test
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 15G 7.0G 6.6G 52% /
/dev/hdc1 190M 32M 149M 18% /boot
tmpfs 501M 0 501M 0% /dev/shm
/dev/mapper/test_vgname-hello
10M 172K 19M 1% /root/test
[root@localhost ~]#

11. pvmove

The above command will move the data from one physical volume to another.

Syntax :

pvmove physical_volume1 physical_volume2

Example :

pvmove /dev/sdc1 /dev/sdc2

This will move the data from the physical volume /dev/sdc1 to /dev/sdc1

LVM Files

1. Configuration File

The lvm configuration file is “lvm.conf” and it is located in “/etc/lvm”.

[root@localhost lvm]# pwd
/etc/lvm
[root@localhost lvm]# ll lvm.conf
-rw-r–r– 1 root root 10538 May 13 01:33 lvm.conf
[root@localhost lvm]#

2. LVM archive directory

The archive directory is located in “/etc/lvm”.

[root@localhost archive]# pwd
/etc/lvm/archive
[root@localhost archive]# ls
myvgm_00000.vg new_00000.vg
test_vgname_00001.vg test_vgname_00006.vg test_vgname_00011.vg
myvgm_00001.vg new_00001.vg
test_vgname_00002.vg test_vgname_00007.vg test_vgname_00012.vg
myvgm_00002.vg new_00002.vg
test_vgname_00003.vg test_vgname_00008.vg test_vgname_00013.vg
myvgm_00003.vg new_00003.vg
test_vgname_00004.vg test_vgname_00009.vg test_vgname_00014.vg
myvgm_00004.vg test_vgname_00000.vg
test_vgname_00005.vg test_vgname_00010.vg test_vgname_00015.vg
[root@localhost archive]#

3. Backup Directory

Backup directory is “/etc/lvm/backup“.

It contains the details about the volume groups which we create in the server.

LVM Options

By default some of the options for LVM are not enabled. You can change the options in the configuration file “/etc/lvm.conf” to change the default values. Some of the important variables are given below.

1. The volume group location

The volume groups are creates in the location “/dev” by default. You can change that settings by changing the value of the variable “dir” in the configuration file.
2. LVM log file

By defult there will not be any log file for the LVM. You can enable the log file for LVM by adding the log file location to the variable “file” in the configuration file.

Example:

file = “/var/log/lvm2.log

3. Log file Overwrite

You can overwrite or append the details to the LVM file. The variable is “overwrite”. Its a binary variable. If the valuse is “0?, the contents will be appended to the log file. If it is “1?, the log file will be overwritten.
4. Level of log file.

The level of lvm log message can be determined by the variable “level”. The level ranges from 0-7. The most verbose level is 7.
5. Metadata Backup

You can enable the backup for the metadata of the lvm using the variable “backup”. Its also a binary variable. If the value is “0?, backup will not be there. If the value is “1?, backup will be kept in the server.
6. Backup Directory

The backup directory can be added to the variable “backup_dir”. By default the location will be “/etc/lvm/backup”.
7. Metadata Archive

You can enable archive for the metadata of lvm using the variable “archive”. Its also a binary variable. If the value is “0?, archive will not be there. If the value is “1?, archive will be kept in the server.
8. Metadata Directory

The archive directory can be added to the variable “archive_dir”. By default the location will be “/etc/lvm/archive”.
9. Minimum Number of Archive Files

You can set the minimum number of archive files in the variable “retain_min”.
10. Minimum time of Archive Files

You can set the minimum number of days in which archive files can be kept in the server by changing the value of the variable “retain_days”.

Conclusion

We usually give large space for the partitions which we use more and give less space to the partitions which we do not use regularly. In some situations, the disk space for the regularly using partition will be filled up quickly even though there are lot of space in the hard disk. LVM helps to shrink the space of the unused partitions and to extend the space filled partitions easily and effectively

LVM also helps to manage the disk space utilization by combining the space of all the hard disks of the server. So its time to start your experiments with LVM.

htaccess introduction

.htaccess No Comments »

.htaccess (Hypertext Access) is the default name of Apache’s directory-level configuration file. It allows webmasters to customize configuration directives, normally available in the main httpd.conf.

htaccess allows webmasters to do a range of customization to a webservers behaviour in a directory, including password protecting them, denying access, error handlers, redirects and a lot more. htaccess is particularly useful when you don’t have root access to the server. For example, in virtual Web Hosting and ISPs.

Before making any of these configurations, however, the following points need to be kept in mind.

Your webserver Administrator should allow you to make these
changes by using “AllowOverride All” in the main configuration
file(httpd.conf).

You need to make sure that you are not using Microsoft Frontpage
on your website. Frontpage uses htaccess for its own directives.

Changing the .htaccess files to insert new directives “will” break
your website.

Test, Test, Test. Test new htaccess configurations on an empty
directory before making it LIVE.

A .htaccess file controls the directory it is in, plus all subdirectories. However, by placing additional .htaccess files in the subdirectories, this can be overruled. Therefore, if you have an .htaccess file in a subdirectory and another one in a parent directory, the one in the subdirectory will be followed.
Showing error pages

Error handlers are setup so that custom pages can be displayed to users, should they encounter an error on your website. For example, if they should encounter a “Not found” 404 error, they could get directed to a good looking page, rather than the boring default error page.

To achieve this, simply put this little snippet in your .htaccess file.

ErrorDocument 400 /errors/404.html

ErrorDocument 403 /errors/403.html

ErrorDocument 404 /errors/404.html

ErrorDocument 500 /errors/500.html

You can name the pages anything you want, provided it is linked correctly in the .htaccess file.

The most common error pages are

404 - Page not found error400 - Bad Request

403 - Forbidden error

500 - Internal server error

Password protect

Password protecting a web directory can be achieved by putting this little snippet in your .htaccess file in the directory you want to protect.

AuthType Basic

AuthName “Password Required”

AuthUserFile /www/passwords/.htpasswd

In order for the password protect to work, you should create a .htpasswd file. You can create it by doing these steps.

[root@localhost ~]# cd /var/passwords

[root@localhost ~]# htpasswd -c .passwd username

New password:

Re-type new password:

Adding password for user username

[root@localhost ~]# cat .passwd

username:wLU7nnYVpdXO2

[root@localhost ~]#

In order for this to work, your Web administrator should have allowed “AllowOverride AuthConfig” in the server wide httpd.conf.
Denying users by IP or domain

You can deny users based on IP or IP block by putting in this snippet in your .htaccess.

order allow,denydeny from 98.654.321.12

deny from 98.654.322.

allow from all

The second line, specifically denies one IP 98.654.321.12. The third line denies all the IPs starting with 98.654.322. . This is particularly useful if you have seen strange activity on your website by unknown IPs in your access logs.

Some webmasters use this feature to deny whole ISPs or datacenters access, especially if they find credit card fraud or increased attempts from poorly secured servers.

You can also deny by domain name. For example “deny from .madguy.com”, denies all users from www.madguy.com or abc.madguy.com .
Changing the default page

Assume you are using index.php instead of index.html as your main home page. But the webserver is configured to access index.html first. All you need to do is to add this to your .htaccess.

DirectoryIndex index.php index.html

This makes the php file the default file. In case the php file is not around, it will look for the index.html file.
Controlling PHP using htaccess

The good thing about htaccess is that I can use it to control the php variables as well. PHP’s behaviour is controlled a large extent by the /etc/php.ini file. In a server shared by many websites, it may not be possible to change the php.ini file for everyone’s special needs. Thats where the .htaccess file comes in.

For example, if you want to turn the register globals off, simply put this in the .htaccess file

php_flag register_globals Off

In this way, you can override any php.ini variable, by putting such entries in the .htaccess file. Of course, this works only if it is allowed by the administrator.
Redirects

Webmasters use Redirects during maintenance(to redirect from index.html to tempmessage.html) or to redirect from an old file to a new file.

In order to redirect from http://yoursite.com/old/file.html to http://yoursite.com/new/file.html, simply put this line in your .htaccess file.

Redirect /old/file.html http://yoursite.com/new/file.html

The /old is relative to the root of your website. i.e at http://yoursite.com/old.
SSI

In order to allow SSI(Server Side Includes) in one directory, simply include this snippet in the .htaccess file in that directory.

Options +Includes AddType text/html shtml AddHandler server-parsed shtml

Tips and Tricks to increase site speed

Cpanel No Comments »

When your equipment is not in tune with demand, your customers bail out and hit the road to a new service. In the world of Internet business, your equipment is your site. Every second is precious to your customer. What would be your reaction to a site that comes up so slow that you feel your time is wasted just trying to visit it? You would rather use your time to visit another site that loads faster. The same would be the reaction of your customer, when he sees that your site loads too slow. So, that’s the question:

Does your website load quickly enough?

Being in the support industry, I often see the following quotes:

My sites are slow…….
Site running slow…..
I was wondering, the site is running extremely slow! ….. etc etc

And once a customer asked me whether it’s possible to increase site speed using “http” headers.
Answer is Yes :)

Assuming that your site is hosted in a reasonably fast server and have a
good uptime, optimizing site codes is the most important factor in improving site speed. Other than that, another method is to use server files which are accessible by end users.

One such file is .htaccess. This file can be used to improve your site’s loading time greatly, if mod_expires and mod_headers are compiled with
Apache. Apart from this, there is one more simple method; gzip compression (using htaccess). Both are described in this article.

Obviously, these two techniques can also be added to “Htaccess Uses” list.
Defining htaccess

.htaccess, commonly known as “end user’s apache configuration file”, is used to customize configurations for a particular directory using the directives provided by apache.

This file is only used when users don’t have access to the main server configuration file. You can also give another name to htaccess file. If you want to call your “htaccess” file by another name, you can do it by using “AccessFileName” directive. For example:, if you wish to call .htaccess by the name niyas, it can be done by using the following directive.

AccessFileName .niyas

How Caching increases site speed?

Caching is a temporary storage of frequently accessed data closer to client browser, avoids round trips to original server and thereby saves time, reduces bandwidth consumption and server load. The basic idea behind caching is simple. Instead of wasting efforts by re-downloading a resource every time it is needed, keep a local copy, and reuse it for as long as it is still valid.
From Askapache

“A Web cache sits between one or more Web servers (also known as origin servers) and a client or many clients, and watches requests come by, saving copies of the responses - like HTML pages, images and files (collectively known as representations) - for itself. Then, if there is another request for the same URL, it can use the response that it has, instead of asking the origin server for it again.”

Freshness and validation are the two main concepts in web caching. Freshness refers whether a cached representation is in the same state, as, that resource on the origin server. Validation information is used by servers and caches to communicate when a representation has changed.

If server confirms that the cached object is still fresh, browser will “use” it, otherwise a fresh copy is served. In this way, servers “tell” cache how long the associated information/representation remains fresh.
Let’s see how cache works:

Caching is based on a set of rules. Most of these rules are determined by protocols and some of these rules are set by cache admin. Some of the common rules are:

* If the request is authoritative or genuine or secure, it won’t be cached.

* If the response header do not contain any validators (eg:- ETag or Last-Modified header) or freshness information, it will be considered uncacheable.

* A cached representation is deemed as fresh, if an expiry time or other age-controlling header set is defined, and is still within the fresh period.

* If the cached content is stale, the origin server will be asked to validate it.

Ways to Implement Caching:

Here are two awesome ways to implement caching on your website using Apache .htaccess file. Both methods are extremely simple to set up and will speed up your sites!
1. Using mod_expires

Requirements : mod_expires and mod_headers must be compiled with apache (static/dynamic).

Using mod_expires we can set life time for pages served or for contents in web pages. By this way, servers tell cache, how long the associated information/representation remains fresh. After this period, contents will be requested from origin. So it basically sets a time for web pages. This method is excellent for pages that change at known times or if they change very rarely. The only value valid in expire headers is the “Date” which is in GMT, not local time.

Eg: Expires: Sun, 25 Jun 2006 14:57:12 GMT

How can this be done using htaccess?

We can target files by their extensions

<ifmodule mod_expires.c>
<filesmatch “\.(jpg|gif|png|css|js)$”>
ExpiresActive on
ExpiresDefault “access plus 1 year”
</filesmatch>
</ifmodule>

or by their type

<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault “access plus 1 month”
ExpiresByType text/html “access plus 1 month 15 days 2 hours”
ExpiresByType image/gif “modification plus 1 month”
ExpiresByType image/png “modification plus 1 month”
ExpiresByType image/jpg “modification plus 1 month”
</IfModule>

Here “ExpiresDefault” defines the default expiry time for all files that are not specified separately using “ExpiresByType”.

You may also use formats “ExpiresDefault A300?, “Expires A300?, Expires M300? etc. Here the first two sets the expiry time to 300 seconds after access (A) and the last one sets expiry time to 300 seconds after modification.

Although this seems useful, there are some limitations in using “Expires” headers. First thing is that clocks on web server and cache must be synchronized. Also it’s easy to forget that we’ve set some content to expire at a particular time.

Due to these limitations HTTP 1.1 introduced a new type of header known as cache-control header.
2. Using Cache-control Headers

Here are some of common Cache-control Headers.

* max-age — Maximum amount of freshness time (in seconds).

* no-cache — When this is set, caches contact origin server for validation before releasing cached copy.

* public — Server responses are always cached even if it’s behind authentication.

* private — All or a part of server responses are intended for a particular use and must not be cached by a shared cache.

* no-store — Tells cache not to keep a copy of representation.

* must-revalidate — Caches must follow every freshness information given to them by the server.

Let’s see how this can be implemented using .htaccess

All text files, javascripts, pdf documents and style sheets are cached for 7days (604800 secs).

<FilesMatch “\.(js|css|pdf|txt)$”>
Header set Cache-Control “max-age=604800, public”
</FilesMatch>

All html files for two hours.

<FilesMatch “\.(html|htm)$”>
Header set Cache-Control “max-age=7200, public”
</FilesMatch>

No caching for php, perl and cgi scripts.

<FilesMatch “\.(php|cgi|pl)$”>
Header set Cache-Control “no-store, no-cache, must-revalidate, max-age=0″
</FilesMatch>

Also we can use “Expires” along with “cache-control”. Let’s modify the above.

<FilesMatch “\.(php|cgi|pl)$”>
ExpiresDefault A0
Header set Cache-Control “no-store, no-cache, must-revalidate, max-age=0″
</FilesMatch>

or

<FilesMatch “\.(php|cgi|pl)$”gt;
Header unset Cache-Control
Header unset Expires
</FilesMatch>

Suppose you want some of the files say mp3 and mp4 files to be cached for ever, use

<FilesMatch “\.(mp3|mp4)$”>
Header set Cache-Control “max-age=31536000, public”
</FilesMatch>

31536000 == 1 year (effectively infinite on Internet time).

So that’s all about caching and site speed. Now let’s see how we can speedup sites using compression.
Improving site-speed using Compression (mod_gzip)

Requirements : mod_gzip must be compiled with apache (static/dynamic).

Mod_gzip is an apache module which compresses the contents before sending it to the client browser. It uses same compression as gzip and no plugins or additional softwares are needed by the browser to take advantage of this. In this way less content is transferred which increases the download time and hence saves bandwidth.

Time taken to compress the contents, transfer to client and restore these at client end is faster than transferring original uncompressed files across the wire. Mod_gzip can be compiled with apache as static or dynamic module.

When client sends a request, apache determines whether it should use mod_gzip by checking whether “Accept-Encoding” HTTP request header has been sent by the client. If the request contains something like “Accept-encoding: gzip”, mod_gzip will compress all configured file types when they are served to clients. Here client announces to apache that it can understand files that have been encoded in “gzip” format. mod_gzip then compress the outgoing contents and include following response headers:

Content-Type: text/html
Content-Encoding: gzip

This means that content from the server is GZIP-encoded but after uncompressing, it should be treated as HTML files. This type of compression can be used for static files, dynamic pages such as those produced by Server-Side Includes (SSI). You can also use this type of compression for your Cascading Stylesheets(CSS).

Now let us see how gzip compression can be enabled via .htaccess:

The following code explicitly states the following:

* All text files (text/css, text/html etc.) and php files will be compressed.

* All PDF documents will be compressed.

* All javascript application files (that aren’t text/javascript) not to be compressed.

mod_gzip_on       Yes
mod_gzip_item_include         file       \.html$
mod_gzip_item_include         file       \.htm$
mod_gzip_item_include         file       \.shtml$
mod_gzip_item_include         mime       ^text/html.*

mod_gzip_item_include         file       \.css$
mod_gzip_item_include         mime       ^text/css.*
mod_gzip_item_include         file       \.php$

mod_gzip_item_include         file       \.pdf$
mod_gzip_item_include         mime       ^application/pdf.*

mod_gzip_item_exclude         file       \.js$
mod_gzip_item_exclude         mime    ^application/x-javascript.*

Other commonly used directives are:

mod_gzip_minimum_file_size — Minimum size ( in bytes ) of a file eligible for compression.
mod_gzip_maximum_file_size — Maximum size ( in bytes ) of a file eligible for compression.

mod_gzip is for Apache 1.3. If you’re using Apache 2.x, you’ll need to use mod_deflate which is not included here.
Pros and Cons:

Since it compresses the contents prior to transfer, lot of bandwidth is saved resulting in faster download times. Downside is that it will create additional load on server. Also some browsers still have trouble with compressed contents.
Conclusion

Kewl! If you’ve made it this far, you now know the easiest methods to optimize your site.

Generally speaking, caching and compression are two simple techniques which can be used to improve site’s performance. Expired header denotes a point in time after which the representation should be considered out of date (stale). In such cases Cache-Control header takes precedence.

By caching objects that change infrequently for longer periods, and caching frequently-updated content for shorter periods (or not at all) you can speed up perceived load times while maintaining fresh content.

Effective Server Monitoring using Nagios NRPE

Linux No Comments »

Monitoring and Security has always been a concern of Webhosting Industry. A web host is always in the look out of services, which will guarantee minimal downtime. Similarly, a web hosting client requires a service with which he can promise maximum uptime to his customers and gain the trust of future prospects.

Monitoring a web server essentially means alerting the server owner about the status of a service. It can be done internally where a software checks the service status and notifies the owner if some service goes down, or it can be external, where you have a web server monitoring company to the check the services status with a certain frequency.

There are many server monitoring and website monitoring tools or services available. Ideally every server you have should be monitored, every service you use, along with every domain name you own. If your server goes down for more than a certain interval of time, you should receive a message about the problem. However, if you use the aid of external monitoring companies, this can be very expensive and service fees can quickly exceed your income. You may have to end up monitoring only the most important servers or the websites of most important clients.

In addition, you will have to answer some of the major queries that arise in the mind of customers:

a) How effectively are my servers monitored ?
b) How will I monitor my servers without any external help ?
c) Am I alerted if something goes wrong in my servers

and the list goes on ….

Achieving these goals in an effective manner is a pretty daunting task for system administrators. To know why monitoring servers is so important, lets see it through the eyes of customers. Lets think of a customer who runs his business online or he is in the middle of an Ad-campaign or a customer who travels around the world and his work depends lots on e-mail. So when the critical systems like webserver or mailserver are down, it actually effects their business and there is no wrong in customers getting so frustrated about their Webhosts.

The only way this can be achieved is thorough effective server monitoring. As I said, there are lots of tools available in the market, but my article will concentrate on one of the best open source tool that is preferred by most of the webhosting industries called Nagios. Also, I am not going to tell you how to install and configure Nagios because you already have a well documented article in their website, but I am here to tell how efficiently you can use Nagios to monitor remote servers.

Lets take it in a step by step basis. Lets answer their queries.

1)How effectively are my servers monitored ?

The Nagios plugins has about 50 plugins when installed and only very few plugins monitor the remote services i.e those services that runs on the public ports. The remaining plugins only runs in the local machine unless the client machine which as to be monitored by the Nagios is configured properly.

Apart from the services running in the server, the customer is always inquisitive to know about the disk space, load, memory etc. and wants them to be alerted before they can cause any fatal damage. Now here comes the role of a system administrator who can configure the client machine to retrieve these data. In Nagios, this can be done in three ways:

1) SSH
2) SNMP
3) NRPE

It is possible to execute Nagios plugins on remote Linux/Unix machines through SSH. There is a check_by_ssh plugin that allows you to do this. Using SSH is not an ideal good option as you have to create user in the client side, install keys and also may have to give full privileges to run the Nagios commands. It also imposes a larger (CPU) overhead on both the monitoring and remote machines. This can become an issue when you start monitoring a large number of machines.

SNMP is a network management protocol used by the more expert system administrators. Using SNMP, you can access any information that includes information about routers, temperature etc. in your server room to read statistics, alarms and status messages.

Well the third one is the use of NRPE and out of the three, it is more easier and is readily manageable. NRPE is designed is to allow Nagios to monitor “local” resources (like CPU load, memory usage, etc.) on remote machines. Its main advantages include:

1) Installation is very easy
2) You can write you own scripts in bash or perl to monitor process in client servers in NRPE
3) NRPE uses nagios plugins to monitor the client servers, so make sure you install it.

It uses the check_nrpe plugin, which resides on the monitoring machine and the NRPE daemon, which runs on the remote machine. Installation of NRPE is pretty simple. Its so well documented that you just need to exactly follow those steps. NRPE can be run as a daemon or as an xinetd service whichever you feel is more comfortable.

In order to enable it via xinetd edit the file

service nrpe

{

flags           = REUSE

socket_type     = stream

port            = 5666

wait            = no

user            = nagiosb

group           = nagiosb

server          = /usr/bin/nrpe

server_args     = -c /etc/nrpe.cfg --inetd

log_on_failure  += USERID

disable         = no

only_from       = 127.0.0.1

}

If you are running it as stand alone just run the command:

nrpe -c /etc/nrpe.cfg -d

Well, as you can see /etc/nrpe.cfg is the main configuration file that is used. Make sure that

server_port=5666

If there is a firewall or router, make sure you mention the IP’s in allowed_hosts. For example:

allowed_hosts==x.x.x.x,127.0.0.1

To allow arguments for plugins, set:”

dont_blame_nrpe=1

Also you need to define the plugins using arguments for which the examples as been given in the configuration file itself.

To check whether the nrpe is working properly you can use this command from the konsole:

/usr/local/nagios/libexec/check_nrpe -H;IP of the client machine; -c check_load

The check nrpe plugin is installed when we install the NRPE from the source. Once installed copy it to /usr/local/nagios/libexec.

Once installed you can use it in combination with all the nagios plugins and you can monitor almost everything in the client servers.

2) How will I monitor my servers without any external help ?

Yes, you can monitor your servers on your own. Individual user accounts can be created in Nagios and can be provided to the customers so that they can always keep an eye on their servers. Of-course the webhosting service should provide you with such privileges.

3) Am I alerted if something goes wrong in my servers

Yes its the most important feature and the customers gets alerts through e-mails.

Well if you do not avail any of the above said basic features from a webhosting service, most probably you are choosing a wrong host.

Monitoring the servers can solve many issues which causes headaches for both the sysadmins and the customers. By regularly monitoring the servers, you are making sure that none of the services in server are down and as a result the problems will be very less. As a guy working in support industry, I have seen many problems recurring due to service failures, load surge and system down which can be avoided by implementing effective monitoring systems. Try implementing the monitoring systems and see the difference for yourself. You have just reduced half of your workload !!!

Using Phusion Passenger (a.k.a mod_rails) On cPanel Server

Cpanel No Comments »

Phusion Passenger (mod_rails or mod_rack ) makes execution of Ruby web applications more easier on Apache webserver. It requires no maintenance from our part and minimal port management. It was designed keeping in mind performance, stability and security.

Here I am explaining more about deploying this module on Linux servers using cPanel as the control panel.

Currently in cPanel, by default, the Ruby On Rails(RoR) applications are using Mongrel webserver. By Phusion Passenger, we can use Apache itself for RoR applications, instead of redirecting the application to Mongrel.

Installation

We can install Phusion Passenger using different methods. An Easy way is to use gem to install Phusion Passenger in two simple steps. Make sure that RoR is already installed on your cPanel server using ‘/scripts/installruby‘.

Step 1: #gem install passenger
Step 2: #passenger-install-apache2-module

In the second step, while installing ‘passenger-install-apache2-module’, I ran into two errors. The errors and corresponding solutions are given below.

Error 1: Apache 2 development headers were not detected by the script.

Checking for required software...

 * GNU C++ compiler... found at /usr/bin/g++
 * Ruby development headers... found
 * OpenSSL support for Ruby... found
 * RubyGems... found
 * Rake... found at /usr/bin/rake
 * Apache 2... found at /usr/local/apache/bin/httpd
 * Apache 2 development headers... missing..(some error here)

Solution: Here the script is checking for apxs installation path. On a cPanel server, the default path is ‘/usr/local/apache/bin/apxs‘. But the script was looking for ‘/usr/sbin/apxs’. To solve this, I created a symbolic link from ‘/usr/sbin/apxs‘ to ‘/usr/local/apache/bin/apxs‘.

Error 2: Another error that came up was:

/usr/local/apache/include/apr_file_info.h:200: error: 'apr_ino_t' does not name a type ..."

Solution: There were two installation of apr on the server. One by default and one by cPanel. The passenger script was taking binary path from one installation and include files from other. I moved the default installation on the server to a backup folder and created a symbolic link from default installation’s include directory to apr include directory of cPanel. The command for this is given below:

#ln -s /usr/local/apache/include/ /usr/include/apr-1

Loading Modules

After completing the ‘passenger-install-apache2-module’ step successfully, add the corresponding Modules to Apache configuration file.

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-
2.0.2/ext/apache2/mod_passenger.so
   PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.2
   PassengerRuby /usr/bin/ruby

Save and restart Apache.

#/usr/local/cpanel/bin/apache_conf_distiller --update
#/usr/local/cpanel/bin/build_apache_conf
#/etc/init.d/httpd restart.

Deploying RoR application:

Suppose, we have a RoR application in “/home/username/testapp”. Follow the steps given below to redirect the main domain to this application.

Step 1: By default the Document root of this domain will be /home/username/public_html/. Create a symbolic link from /home/username/public_html/ to the RoR application’s public directory, /home/username/testapp/public/.

-bash-3.2# ln -s  /home/username/testapp/public/ /home/username/public_html

Step 2: Then add the following rule in the virtual host entry of the domain.

RailsBaseURI /

Note : If you want to redirect a subdirectory under public_html like http://domainname/rails to the RoR’s application, change the symbolic link accordingly and specify the rule in the domain’s virtualhost entry as:

RailsBaseURI /subdirectory_name

It is not recommended to edit the virtual host entry directly. You can add this rule in the include file mentioned in the virtual host entry of the domain.

Include "/usr/local/apache/conf/userdata/std/2/username/domain_name/*.conf"

By default these include files will be commented in the configuration file. We have to manually create directories corresponding to this include file.

Directories up-to /usr/local/apache/conf/ were already there in the server. I created new sub-directories from ‘userdata’ to ‘domain_name’. Under the directory /usr/local/apache/conf/userdata/std/2/username/domain_name/, you can create any file with .conf extension. I created the file rails.conf to add the “RailsBaseURI” rule.

-bash-3.2# ll /usr/local/apache/conf/userdata/std/2/username/domain_name/
total 4
-rw-r--r-- 1 root root 15 Jul 31 04:05 rails.conf

Step 3: After that, execute the below command,

#/scripts/ensure_vhost_includes --user=username  (Use cpanel username of that domain)

Step 4: You can restart the RoR application by restarting Apache or using the command,

#touch /path_to_application/tmp/restart.txt

In this case,

#touch /home//username/testapp/tmp/restart.txt

The domain will now work fine using this new mod_rails installation. :) Make sure that you are not starting or restarting this application from cPanel >> Ruby On Rails option. It will switch to Mongrel webserver.

You can check Apache error log file itself for errors.

Conclusion

Although cPanel is not using this module (mod_rails) with Easyapache script and in their Ruby Ob Rails interface. By following this method, we can use this module on a cPanel server with much ease.

Phusion Passenger conflicts with some Apache modules like mod_rewrite and mod_alias. They may be installed together with mod_passenger and used outside virtual hosts that contain a Rails application. Phusion Passenger recommend not to use their features inside virtual hosts that contain a Rails application. Rewrite rules are mainly used to accelerate caching of pages. Phusion Passenger supports page caching without mod_rewrite. So there is no need to worry about this.

Tips:

Firstly make sure you add the generated code to :

/usr/local/apache/conf/includes/pre_main_global.conf

and not

/etc/httpd/conf/httpd.conf

or otherwise cPanel will overwrite it when it does updates.

Another way or running the command to install the passenger Apache2 Module without creating a link is :

APXS2=/usr/local/apache/bin/apxs PATH=$PATH:/usr/local/apache/bin passenger-install-apache2-module

If  you are executing the application using any scripts in the scripts directory of rails application, make sure that rails/ruby is installed in the interpreter path defined in that file. You can see the shebang line as,

===================
#!/usr/bin/env ruby
===================

In this case, ruby should be installed in /usr/bin/ruby. Like this, check your ruby installation path.

Wordpress Themes by Natty WP. Web Hosting
Images by our golf tips desEXign.