Oct 29

mysql – Error in accept: Too many open files

One server is running both mysql and apache together,but the mysql get down every four hours.From PHP,it’s said ‘Error establshing a database connection’.From mysql error log,i got the some records like below:

’121029  2:47:38 [ERROR] Error in accept: Too many open files’

i know that mysql server has a config directive of open_files_limit which limit the number of file descripteors mysqld can use.so i need to check what the value in use for the current running mysqld server,from mysql client console,

Source code    
mysql -u root -p
>show global varaibles like 'open%'
>
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 1185  |

You can also check the config with following command:

Source code    
# netstat -atnp|grep 3306
tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN      5596/mysqld
 
# cat /proc/5596/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            10485760             unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             200704               200704               processes
Max open files            1185                 1185                 files
Max locked memory         32768                32768                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       200704               200704               signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0

so now we need to adjust mysql server configuration to make it feel comfortalbe.You decide the open_files_limit value by considering following factor:the databases amount, the max_connections and the table_cache value. You can also increase the number to a little higher you think is appropriate,then tune it by mysql server running status.

Source code    
# vim /etc/my.cnf
[mysqld]
open_files_limit = 3000
 
save to quit and then restart msyql server
#/etc/init.d/mysqld restart
Oct 25

hidden animated GIF images stop play in IE browser when submit form

I had met such a problem:

There is a form,a payment form to collect credit card info,below is the html code of the page.

Source code    
<form id="form1" action="PayPage.aspx" method="post">
    <input type="text" name="txtPost" value=""></td>
    <input type="text" name="txtEmail" value=""></td>
    <input type="submit" id="btnPay" onclick="return VerifyPage();" value="Submit" name="btnPay">
</form>

When click on the button to submit the form, we need to show a loading gif image to customer.  That means we are processing their request.Here is the js code below:

Source code    
function VerifyPage() {
    //do some validate
	//if all passed,show alert message box and the animated loading gif image
    sAlert("Connecting to bank......Please wait......<br/><img id='img123' alt='loading......' src='../resources/images/jindutiao.gif' />");
    return true;
}
 
function sAlert(str) {
    var msgw,msgh,bordercolor;
    msgw=400;
    msgh=100;
    titleheight=25;
    bordercolor= "#336699 ";
    titlecolor= "#99CCFF ";
    var sWidth,sHeight;
    sWidth=document.body.offsetWidth;
    sHeight=screen.height;
    var bgObj=document.createElement("div");
    bgObj.setAttribute('id','bgDiv');
    bgObj.style.position = "absolute";
    bgObj.style.display = "none";
    bgObj.style.top= "0";
    bgObj.style.background= "#777 ";
    bgObj.style.filter= "progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75 ";
    bgObj.style.opacity= "0.6";
    bgObj.style.left= "0";
    bgObj.style.width=sWidth   +   "px";
    bgObj.style.height=sHeight   +   "px";
    bgObj.style.zIndex   =   "10000";
    document.body.appendChild(bgObj);
    var msgObj=document.createElement("div");
    msgObj.setAttribute("id", "msgDiv");
    msgObj.setAttribute("align", "center");
    msgObj.style.background= "white ";
    msgObj.style.border= "1px solid "   ;
    msgObj.style.position   =   "absolute";
    msgObj.style.left = "50%";
    msgObj.style.display = 'none';
    msgObj.style.top   =   "50%";
    msgObj.style.font= "14px/1.6em   Verdana,   Geneva,   Arial,   Helvetica,   sans-serif";
    msgObj.style.marginLeft   =   "-225px"   ;
    msgObj.style.marginTop   =   -75+document.documentElement.scrollTop+ "px";
    msgObj.style.width   =   msgw   +   "px";
    msgObj.style.height   =msgh   +   "px";
    msgObj.style.textAlign   =   "center";
    msgObj.style.lineHeight   = "60px";
    msgObj.style.zIndex   =   "10001";
    document.body.appendChild(msgObj);
    var txt=document.createElement("p");
    txt.style.margin= "1em   0"
    txt.setAttribute("id", "msgTxt");
    txt.innerHTML=str;
    document.getElementById("msgDiv").appendChild(txt);
}

This works fine in all major browsers except IE.When the user click the submit button, the message dialog show,but the animated loading image is frozen.This is another know bug in IE browsers.IE didn’t play any hidden animated image after submit event.

To get around this bug,you need to let IE browser to reaload the image in a timeout. That means you need to change the image elements src attribute every moments.

Source code    
function sAlert(str) {
    var msgw,msgh,bordercolor;
    msgw=400;
    msgh=100;
    titleheight=25;
    bordercolor= "#336699 ";
    titlecolor= "#99CCFF ";
    var sWidth,sHeight;
    sWidth=document.body.offsetWidth;
    sHeight=screen.height;
    var bgObj=document.createElement("div");
    bgObj.setAttribute('id','bgDiv');
    bgObj.style.position = "absolute";
    bgObj.style.display = "none";
    bgObj.style.top= "0";
    bgObj.style.background= "#777 ";
    bgObj.style.filter= "progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75 ";
    bgObj.style.opacity= "0.6";
    bgObj.style.left= "0";
    bgObj.style.width=sWidth   +   "px";
    bgObj.style.height=sHeight   +   "px";
    bgObj.style.zIndex   =   "10000";
    document.body.appendChild(bgObj);
    var msgObj=document.createElement("div");
    msgObj.setAttribute("id", "msgDiv");
    msgObj.setAttribute("align", "center");
    msgObj.style.background= "white ";
    msgObj.style.border= "1px solid "   ;
    msgObj.style.position   =   "absolute";
    msgObj.style.left = "50%";
    msgObj.style.display = 'none';
    msgObj.style.top   =   "50%";
    msgObj.style.font= "14px/1.6em   Verdana,   Geneva,   Arial,   Helvetica,   sans-serif";
    msgObj.style.marginLeft   =   "-225px"   ;
    msgObj.style.marginTop   =   -75+document.documentElement.scrollTop+ "px";
    msgObj.style.width   =   msgw   +   "px";
    msgObj.style.height   =msgh   +   "px";
    msgObj.style.textAlign   =   "center";
    msgObj.style.lineHeight   = "60px";
    msgObj.style.zIndex   =   "10001";
    document.body.appendChild(msgObj);
    var txt=document.createElement("p");
    txt.style.margin= "1em   0"
    txt.setAttribute("id", "msgTxt");
    txt.innerHTML=str;
    document.getElementById("msgDiv").appendChild(txt);
 
    //added the following code to walk around IE BUG
    var imgurl = document.getElementById('img123').src;
    setTimeout(function() {
        document.getElementById('img123').src = imgurl;
    },200);
 
}
Oct 03

apache — let search engine fetch robots.txt based upon domain name

if you have a website with multiple domain(for some special reason),and you want google or other major search engine to fetch different robots.txt,how will you do?

first,get all ready prepared robots.txt and put them in the root folder of you website.you need to name it as robots.txt ,robots1.txt ,robots2.txt

second,create .htaccess file( if not existed)

third,add the following apache config command to the head of the file

Source code    
RewriteCond %{HTTP_HOST} abcdomain1\.com$ [NC]
RewriteRule robots.txt robots1.txt [L]
 
RewriteCond %{HTTP_HOST} abcdomain2\.com$ [NC]
RewriteRule robots.txt robots2.txt [L]
 
RewriteCond %{HTTP_HOST} abcdomain3\.com$ [NC]
RewriteRule robots.txt robots3.txt [L]
Sep 07

zen cart — all zen cart url with currency parameter will be redirected to home page

i just found that if any url in a zen cart store containing currency=value,then it will be redirected to zen cart website home page.For example,

http://www.abcdomain.com/xxxxxxxxxxx/xxxxxxxxx/?currency=EUR

This url will be redirected to http://www.abcdomain.com/,it’s a 302 redirect.

is this a zen cart bug?

From the code in this file:/includes/init_includes/init_currencies.php

Source code    
<?php
/**
 * initialise currencies
 * see {@link  http://www.zen-cart.com/wiki/index.php/Developers_API_Tutorials#InitSystem wikitutorials} for more details.
 *
 * @package initSystem
 * @copyright Copyright 2003-2007 Zen Cart Development Team
 * @copyright Portions Copyright 2003 osCommerce
 * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
 * @version $Id: init_currencies.php 6300 2007-05-11 15:49:41Z drbyte $
 */
if (!defined('IS_ADMIN_FLAG')) {
  die('Illegal Access');
}
 
// If no currency is set, use appropriate default
if (!isset($_SESSION['currency']) && !isset($_GET['currency']) ) $_SESSION['currency'] = DEFAULT_CURRENCY;
 
// Validate selected new currency, if any. Is false if valid not found.
$new_currency = (isset($_GET['currency'])) ? zen_currency_exists($_GET['currency']) : zen_currency_exists($_SESSION['currency']);
 
// Validate language-currency and default-currency if relevant. Is false if valid not found.
if ($new_currency == false || isset($_GET['language'])) $new_currency = (USE_DEFAULT_LANGUAGE_CURRENCY == 'true') ? zen_currency_exists(LANGUAGE_CURRENCY) : $new_currency;
 
// Final check -- if selected currency is bad and the "default" is bad, default to the first-found currency in order of exch rate.
if ($new_currency == false) $new_currency = zen_currency_exists(DEFAULT_CURRENCY, true);
//echo '<br />NEW = ' . $new_currency . '<br />';
 
// Now apply currency update
if (
   // Has new currency been selected?
  (isset($_GET['currency'])) ||
 
  // Does language change require currency update?
  (isset($_GET['language']) && USE_DEFAULT_LANGUAGE_CURRENCY == 'true' && LANGUAGE_CURRENCY != $_SESSION['currency']  )
 
) {
  $_SESSION['currency'] = $new_currency;
  // redraw the page without the currency/language info in the URL
  if (isset($_GET['currency']) || isset($_GET['language'])) zen_redirect(zen_href_link($current_page_base, zen_get_all_get_params(array('currency','language'))));
}
?>

the zen_redirect make this happen.

Aug 23

linux — how to exclude directory or files when bakup with rsync

rsync has been heavily used in server daily backup.I am not going to list all option of rsync. i just don’t want to backup some useless file such as cache and log file.

In a typical backup situation, you might want to exclude one or more files (or directories) from the backup. You might also want to exclude a specific file type from rsync.

To exclude a special directory,take a look at the command below:

Source code    
rsync -avze 'ssh -p7788' --exclude 'dir_abc'  /home/www  root@ip:/home/bak/

This command will not sync the /home/www/dir_abc

You can use * to match multiple directory to exclude like this:

Source code    
rsync -avze 'ssh -p7788' --exclude 'dir_*'  /home/www  root@ip:/home/bak/

You can also use multiple –exclude option to exclude:

Source code    
rsync -avze 'ssh -p7788' --exclude 'dir_abc' --exclude 'webcache' --exclude '*.log' /home/www  root@ip:/home/bak/

Keep in mind that rsync will always treat the value of the –exclude option as relative to the bakup dir even though you specified a absolute path,so

if there is a dir1 directory in /home/www

Source code    
rsync -avze --exclude '/home/www/dir1' /home/www /home/bak

rsync will explain /home/www/dir1 as /home/www/home/www/dir1,but this is not what you want.when you specified the path for –exclude option,make sure it’s relative to the source data diretory.this action will not be affected by add / to the exclude path.

Aug 21

linux — use public key authentication to log into ssh

what to do if you want to automate run rsync over ssh without specify any password to backup data?well the only way to access remote ssh server without password is to use pubkey authentication.

First,on the ssh server you need to login,config it to accept pubkey authentication:

vi /etc/ssh/sshd_config

comment out the line PubkeyAuthentication yes and restart sshd dameon:

/etc/init.d/sshd restart

Second, go to the client server,the one you need to bakup.issue the command ssh-keygen to generate a public and private keypair:

# ssh-keygen

press enter without setting any passphrase,.Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub. Copy the content of id_rsa.pub file and paste it to the backup user’s authorized_keys file on the ssh server. if the you use root user,then you need to stored the pub key to /root/.ssh/authorized_keys.This file store all authorized keys for all clients,each line for each client server.It looks like

ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAtjz9QhNQQAqDB/KoiiPLdI2aYyWWuw5QCRqsv+JmdWqWxWivfxCnG+LXw9V/jBpvGFCW4wCwIlO0pq/HGMfts2rjCElWvaeZiDuIwR38TCVbPDzl670MRcWjvp+Gy3IIkrkI7J419VNeCEuGria5t4THdHI4Gsz21nSUbFyko5E= rsa-key-20120510

Third, now you can rsync via ssh without specify ssh password for the user.ie

rsync -avze ‘ ssh -p9998 ‘/home/www/abc.com  root@ip:~/bak

Aug 19

javascript — open lots of urls in new tab

Sometimes,i need to open a lot of url to finish some work.so i need a javascript code to save time.i can run them from firebug console.

Source code    
var domains = ['url1','url2','url3'];
for(i in domains) {
    window.open(domains[i]);
}

The url to assign main shared ip to a reseller acct in WHM:

/cpsess3712993106/scripts2/dodelegatemainip?mainip=212.117.179.142&user=share033

The url to change ip of a domain/acct

/cpsess3808654605/scripts2/changeip?oldip=212.117.179.90&customip=212.117.179.96&user=airjoruk

 

Aug 18

zen cart — recover zen cart database from mysql data folder

One of my server crashed last week. They do a hard disk rescue and i only get a copy of the mysql data folder(the physical data file of all databases).The new server is ready for use,with the mysql and cpanel updated.so i got no lucky to recover with copy the mysql folder back to the new mysql data folder.it only show the database without any table.

i found i do have a mysqldump backup on 2012 -05 -24.but the lates data(2012-08-09) was stored as mysql physical data file,not sql.how to recover all the zen cart databases with the latest data?is it possible.

There is two way to try:

The first one is to install anthoer copy of mysql.it must be same version as the one before system crashed.and same /etc/my.cnf. The you can turn off the currently running mysql ,copy the the mysql data folder to the data folder of the the old copy mysql.Start the mysql and mysqldump to backup all the zen cart database. The switch mysql to the latest mysql,import all databases;

Sometimes it’s impossible to achive the last version of mysql with same configuration.The what can we do?You can mysqldump the database schema(only structure) from a zen cart database with following command:

mysqldump –no-data zencartdb > onlyschema.sql -u root -p’password’

Then create all the databases you want to recover and import the zen cart database schema to every zen cart database.

mysqladmin create database1 -u root -p’password’

mysql database1 < onlyschema.sql -u root -p’password’

Now turn of mysql dameon process to unlock all databases and tables(if exist).copy the data folder bakup to the mysql data folder.

/etc/init.d/mysqld stop
cp -Rf  /home/bak/mysql/*  /var/lib/mysql/

And all is done. However,keep in mind if you use INNODB storage engine in your old mysql database,then the recovery may be more complicated.

Aug 17

linux — fdisk and makefs.ext3 to partition and format a new disk

To show a list for disk intalled on your server,you can issue the command below:

Source code    
fdisk -l | grep '^Disk'

Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
Disk identifier: 0x0004d76c
Disk /dev/sdb: 1500.3 GB, 1500301910016 bytes
Disk identifier: 0x00065d74
Disk /dev/sdc: 1500.3 GB, 1500301910016 bytes
Disk identifier: 0x27b927b8

it shows my server has tree disk;Now let’s start to partion the second disk /dev/sdb,

Source code    
fdisk /dev/sdb

This command will switch you from shell to fdisk console,issue the m command fdisk will print all the available command.Below is a summary of the fdisk command:

  • m – print help
  • p – print the partition table
  • n – create a new partition
  • d – delete a partition
  • q – quit without saving changes
  • w - write the new partition table and exit

With those command, the new disk can be easily cut into any partitions.After partition,you need to format the newly created partition so it can be mounted.

Source code    
mkfs.ext3 /dev/sdb1

Then you can mount the partition as below:

Source code    
# mkdir /sdb1
# mount /dev/sdb1 /sdb1

To make the /dev/sdb1 partition be mounted after system reboot,you need to update /etc/fstab file as below:

Source code    
/dev/sdb1     /sdb1       ext3    defaults      1 2

or you can label the partition using e2label. For example, if you want to label the new partition /backup, enter

e2label /dev/sdb1 /backup

Then You can use label name insted of partition name to mount disk using /etc/fstab:

LABEL=/backup /sdb1 ext3 defaults 1 2