[技術][Git]Git初心者が絶対に覚えておくべきコマンド


Git
の使い方を覚えるにあたって、まず知っておきたいのは――git-cloneだのgit-commitだのは当然として――「操作をミスったときにどのように回復するか」である。それを実現するのは、次の3つのコマンドだ。

  1. git-commit –amend
  2. git-reset
  3. git-reflog

git-commit –amend

あるファイルをコミットしたとしよう。

$ (edit...)
$ git commit -am 'メッセージ生成処理を実装したよ。'

しかし、しばらくして彼は気づいた。

def create_massage(param)
  ...

typoしてる!massageじゃない、messageだ!マッサージを作ってどうする!

慌てるな。まずは直してステージに上げるんだ*1

def create_message(param)
 ...

$ git add .

そして…。

$ git commit --amend

…これで、typo修正は直前のコミット時に行われたことになり、恥ずかしい歴史は消える*2

つまり、git-commit –amendは、直前のコミットを作り直す操作である。このコマンドを知っていれば、ミスしてもすぐに回復できるわけだ。コミットログを修正する目的でもよく使う。

git-reset

これに安心した彼は、意気揚々と開発に没頭する。

しかし、またやってしまった。

$ git commit -am '文字化けしないようにしたよ。'

コミット先のブランチを間違えてしまった!本当はfix_garbleブランチにコミットしたかったのに、practiceブランチでやってしまった!

慌てるな。git-resetするんだ。

$ git reset HEAD^

これでコミット前の状態に戻る。もちろん、変更内容は消えたりしない。

$ git status
# On branch practice
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   view.rb
#
no changes added to commit (use "git add" and/or "git commit -a")

あとは本来のブランチに移動してコミットすればいい。臆するな、変更内容はブランチを移動しても付いてくる。

$ git checkout fix_garble
M       view.rb
Switched to branch 'fix_garble'
$ git status
# On branch fix_garble
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   view.rb
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -am '文字化けしないようにしたよ。'

git-resetは、HEADの位置を変更するコマンドである。対象コミットがわかりさえすれば、そこをHEADとすることができる。HEADより未来のコミットは履歴に表れないので、存在しなくなった = 削除したも同然である。つまり、HEADを過去のコミットに戻せば、その時点より先のコミットを取り除いたことになる。

git-reflog

二度目の窮地も無事脱した。もう安心だ、これ以上変なミスはしないだろう…。

しかし、二度あることは三度あるのだ。

git-resetを覚えた彼は、後になって不要だと気づいたコミットをサクッと取り除く。しかも、変更内容が完全に不要だとわかっているから、気持ちよく–hardを使うぞ*3

$ git reset --hard HEAD^^^^

しまった!HEAD^^^までリセットしたかっただけなのに、一つ多い!必要なコミットを取り除いてしまった!あのコミット分の変更に半日は費やしたというのに…。

慌てるな。git-reflogを使うんだ。

$ git reflog
ef1f900 HEAD@{0}: head^^^^: updating HEAD
6ebb02d HEAD@{1}: commit: 修正漏れがあった。
99a7983 HEAD@{2}: commit: バグフィックスした。
f63f70b HEAD@{3}: commit: すばらしい機能を追加した。
68da592 HEAD@{4}: commit: 機能を拡張した。
ef1f900 HEAD@{5}: commit: 基本的な機能を実装した。
...

これはHEADがどのように移り変わってきたのかを示すログだ。HEAD@{0}が現在のHEAD、そして見よ、HEAD@{1}こそがgit-reset前に参照していたコミットだ。ここめがけてgit-resetし直すのだ。

$ git reset --hard HEAD@{1}

これで全て元通りだ。今度は慎重に…。

$ git reset --hard HEAD^^^

これでよし。*4

git-reflogは、HEADがこれまでどのコミットを指してきたかというログを表示するコマンドである。git-resetしてコミットを取り除いても、それは履歴中のHEADから辿れる範囲から外れたというだけで、ちゃんと残っている。そいつをgit-reflogで探し出して、git-resetで直接跳べば元通りになる。

ちなみに同様の、より詳しい情報をgit-log -gで得ることができる。

まとめ

git-reflogを使えば、自分がこれまでHEADとして参照してきたコミット、つまり自分の過去の操作を一覧できる。これを利用して操作ミス直前の時点(コミット)を特定できれば、git-resetでその時点に――それがたとえgit-logに出てこない時点であっても――戻ることができる。つまり、この二つを覚えておけば大抵の操作ミスから回復できる。回復操作自体が誤りだった、という場合でも、同様の手法でその回復操作の直前のコミットを特定して、その時点に戻れる。どうしたってやり直せるのだ。

git-commit –amendはこれらのちょっと便利なショートカットにすぎないが、頻繁に使うので挙げておいた。

Gitはそう簡単にデータを消失しないように設計されているそうなのだが、たとえ消えてなくても、残っているデータを参照する手段を知らないのでは意味がない。ということで紹介してみた。私もgit-reflogを覚えてからとてつもなく安心感を高めたクチである。これらの操作を知っていれば、よくわからないコマンドをとりあえず叩いて動作を確認してみる、といったこともより気軽に行えるというものだ。

識者の方々から見れば「git-cherry-pickでいいんじゃね?」等のツッコミもあろうかと思うが、最低限覚えていれば、という意図なのでご容赦願いたい。

他には、git-rebase -iを覚えておくと幸せかもしれない。HEADの作り直しにはgit-commit –amendを使うが、HEAD^以前を作り直したいばあいはgit-rebase -iが必要になる。

注意事項

ここで紹介した操作は、ローカルリポジトリでのみ実施すること。公開して他者と共用しているリポジトリに対してこうした履歴の操作を行うと、いろいろ面倒なことになる。git-pushするまえに、本当に公開していいのか入念に確認する必要がある。

Database Master-Slave Replication in the Cloud

Many developers use master-slave replication to solve a number of different problems, including problems with performance, supporting the backup of different databases, and as a part of a larger solution to alleviate system failures. Traditionally, master-slave replication is done with real servers, but it can also be done with cloud database servers. This guest post from Jelastic (originally published here) describes how to set up MariaDB master-slave replication using their Jelastic PaaS (Platform as a Service).

Replication Overview

Master-slave replication enables data from one database server (the master) to be replicated to one or more other database servers (the slaves). The master logs the updates, which then ripple through to the slaves. The slave outputs a message stating that it has received the update successfully, thus allowing the sending of subsequent updates. Master-slave replication can be either synchronous or asynchronous. The difference is simply the timing of propagation of changes. If the changes are made to the master and slave at the same time, it is synchronous. If changes are queued up and written later, it is asynchronous.

dbreplication173

Usage targets for replication in MariaDB include:

  • Scale-out solutions — spreading the load among multiple slaves to improve performance. In this environment, all writes and updates must take place on the master server. Reads, however, may take place on one or more slaves. This model can improve the performance of writes (since the master is dedicated to updates), while dramatically increasing read speed across an increasing number of slaves.
  • Data security — as data is replicated to the slave, and the slave can pause the replication process, it is possible to run backup services on the slave without corrupting the corresponding master data.
  • Analytics — live data can be created on the master, while the analysis of the information can take place on the slave without affecting the performance of the master.
  • Long-distance data distribution — if a branch office would like to work with a copy of our main data, we can use replication to create a local copy of the data for their use without requiring permanent access to the master.

Let’s examine a few examples on how we can use such replication and take advantage of it:

  • Backups: to use replication as a backup solution, replicate data from the master to a slave, and then back up the data slave. The slave can be paused and shut down without affecting the running operation of the master, so we can produce an effective snapshot of “live” data that would otherwise require the master to be shut down.
  • Scale-out: we can use replication as a scale-out solution; that is, where we want to split up the load of database queries across multiple database servers, within some reasonable limitations. Because replication works from the distribution of one master to one or more slaves, using replication for scale-out works best in an environment where we have a high number of reads and low number of writes/updates. Most Web sites fit into this category, where users are browsing the Web site, reading articles, posts, or viewing products. Updates only occur during session management, or when making a purchase or adding a comment/message to a forum. Replication in this situation enables us to distribute the reads over the replication slaves, while still enabling our web servers to communicate with the replication master when a write is required.
  • Spreading the load: there may be situations when we have a single master and want to replicate different databases to different slaves. For example, we may want to distribute different sales data to different departments to help spread the load during data analysis.
  • Increasing the performance: as the number of slaves connecting to a master increases, the load, although minimal, also increases, as each slave uses a client connection to the master. Also, as each slave must receive a full copy of the master binary log, the network load on the master may also increase and create a bottleneck. If we are using a large number of slaves connected to one master, and that master is also busy processing requests (for example, as a part of a scale-out solution), then we may want to improve the performance of the replication process. One way to improve the performance of the replication process is to create a deeper replication structure that enables the master to replicate to only one slave, and for the remaining slaves to connect to this primary slave for their individual replication requirements.
  • Failover alleviating: We can set up a master and a slave (or several slaves), and then write a script that monitors the master to check whether it is up. Then instruct our applications and the slaves to change master in case of failure.
  • Security: we can use SSL for encrypting the transfer of the binary log required during replication, but both the master and the slave must support SSL network connections. If either host does not support SSL connections, replication through an SSL connection is not possible. Setting up replication using an SSL connection is similar to setting up a server and client using SSL. We must obtain (or create) a suitable security certificate that we can use on the master, and a similar certificate (from the same certificate authority) on each slave.

Now let’s examine a simple example on how to configure master-slave replication on Jelastic PaaS.

Create environments

*The instructions below only mention MariaDB but they are fully suitable for MySQL database servers.

First of all we create two environments in Jelastic for our master and slave databases.

  1. Go to jelastic.com and sign up if we haven’t done it yet or log in with our Jelastic credentials by clicking the Sign In link on the page.
  2. Ask Jelastic to create a new environment.
    alf-11
  3. In the Environment topology dialog pick MariaDB as a database we want to use. Set the cloudlet limit and type the name of our first environment, for example,masterbase.
    replication1Wait just a minute for our environment to be created.

    replication2

  4. In the same way create one more environment with MariaDB or just clone it. Let’s name it slavebase. BTW, it will be located on the other hardnode, which is even more secure and reliable for storing our data. Now we have two identical environments with two databases.

    replication4

Configure master database

Let’s configure our master database now.

  1. Click the config button for our master database.
    replication5
  2. Navigate to my.cnf file and add the following properties:
    server-id = 1
    log-bin = mysql-bin
    binlog-format=mixed
    

    dbreplication15

    We use binlog format “mixed” (binlog-format=mixed) to allow a replication of operations with foreign keys.

    Note: Do not use binlog format “statement” (otherwise we will get errors later on!)

  3. Save the changes and restart MariaDB in order to apply the new configuration parameters.

    replication7

  4. Click the Open in browser button for MariaDB. When we created the database, Jelastic will have sent us an email with credentials to it. Log in using these credentials.
  5. Navigate to the Replication tab and click on Add slave replication user.

    dbreplication1

  6. Specify the name and password for our slave replication user and click Go.

    dbreplication2

    Now our slave user is successfully created.

    dbreplication3

Configure slave database

Let’s go back to the Jelastic dashboard and configure our slave database.

  1. Click the config button for our slave database.

    dbreplication4

  2. Navigate to the my.cnf file and add the following strings:
    server-id = 2
    slave-skip-errors = all
    

    dbreplication14

    We allow our slave database to skip all errors from the master (slave-skip-errors = all) in order not to stop normal slave operations in case of errors on the master. Don’t set this option during development as we want to see and catch all bugs, large and small, before moving our code from development to production. Production code should not have any big bugs, so setting this can be useful in that it allows replication to keep working through small, innocuous errors which could stop production and cost money (downtime, lost sales, etc…). This option can be dangerous however, so proceed with caution, and make regular backups.

  3. Save the changes and restart our slave database server in order to apply the new configuration parameters.

    dbreplication6

  4. Navigate to phpMyAdmin using the credentials which Jelastic sent us when we created the environment for our slave database.
  5. Go to the Replication tab click configure for Slave replication.

    dbreplication71

  6. Configure our master server (enter the name, the password and the host of our slave replication user).

    dbreplication8

    Now our master server is configured.

    dbreplication9

  7. Click on Control slave -> Full start for the slave server in order to run Slave SQL andSlave IO threads.

    dbreplication10

  8. Check the slave status table to ensure that everything is ok.

    dbreplication11

Check the results

We have to ensure now that master-slave replication works for our databases.

  1. Let’s create a new database (e.g. Jelastic) in our master database.

    dbreplication12

  2. Navigate to the slave database and we’ll see that the new database was successfully replicated.

    dbreplication13

Connection to master-slave

Here are two examples on how to connect to our master and slave databases from Java and PHP applications.

  1. Our first example is the code of a Java application which connects to our master and slave databases.

    Database_config.cfg:

    master_host=jdbc:mysql://mariadb-master-host/mysql
    master_username=root
    master_password=abcABC123
    slave_host=jdbc:mysql://mariadb-slave-host/mysql
    slave_username=root
    slave_password=abcABC123
    
    driver=com.mysql.jdbc.Driver
    

    Dbmanager.java:

    package com.jelastic.test;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Properties;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class DbManager {
    
    private final static String createDatabase = "CREATE SCHEMA IF NOT EXISTS jelastic";
    private final static String showDatabases = "SHOW DATABASES";
    
    public Connection createMasterConnection() throws IOException, ClassNotFoundException, SQLException {
    Connection masterConnection;
    Properties prop = new Properties();
    prop.load(new FileInputStream(System.getProperty("user.home") + "/database_config.cfg"));
    String master_host = prop.getProperty("master_host").toString();
    String master_username = prop.getProperty("master_username").toString();
    String master_password = prop.getProperty("master_password").toString();
    String driver = prop.getProperty("driver").toString();
    
    Class.forName(driver);
    masterConnection = DriverManager.getConnection(master_host, master_username, master_password);
    return masterConnection;
    }
    
    public Connection createSlaveConnection() throws IOException, ClassNotFoundException, SQLException {
    Connection slaveConnection;
    Properties prop = new Properties();
    prop.load(new FileInputStream(System.getProperty("user.home") + "/database_config.cfg"));
    String slave_host = prop.getProperty("slave_host").toString();
    String slave_username = prop.getProperty("slave_username").toString();
    String slave_password = prop.getProperty("slave_password").toString();
    String driver = prop.getProperty("driver").toString();
    
    Class.forName(driver);
    slaveConnection = DriverManager.getConnection(slave_host, slave_username, slave_password);
    return slaveConnection;
    }
    
    public boolean runSqlStatementOnMaster() {
    boolean execute = false;
    Statement statement = null;
    try {
    statement = createMasterConnection().createStatement();
    execute = statement.execute(createDatabase);
    } catch (IOException ex) {
    Logger.getLogger(DbManager.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ClassNotFoundException ex) {
    Logger.getLogger(DbManager.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SQLException ex) {
    ex.printStackTrace();
    } finally {
    if (statement != null) {
    try {
    statement.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }
    return execute;
    }
    
    public List<String> runSqlStatementOnSlave() {
    List<String> stringList = new ArrayList<String>();
    Statement statement = null;
    ResultSet resultSet = null;
    try {
    statement = createSlaveConnection().createStatement();
    resultSet = statement.executeQuery(showDatabases);
    while (resultSet.next()) {
    stringList.add(resultSet.getString(1));
    }
    } catch (IOException ex) {
    Logger.getLogger(DbManager.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ClassNotFoundException ex) {
    Logger.getLogger(DbManager.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SQLException ex) {
    ex.printStackTrace();
    } finally {
    if (resultSet != null) {
    try {
    resultSet.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    if (statement != null) {
    try {
    statement.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }
    return stringList;
    }
    }
    
  2. Our second example is a connection to our master and slave databases in a PHP application:
    <?php
    /* Master settings */
    $master_server = "xx.xxx.x.xx";
    $master_username = "root";
    $master_password = "abcABC123"; /* Slave settings */
    $slave_server = "xx.xxx.x.xx";
    $slave_username = "root";
    $slave_password = "abcABC123";$link_to_master = mysqli_connect(
    $master_server,
    $master_username,
    $master_password,
    'mysql');
    
    if (!$link_to_master) {
    printf("Unable to connect master database server. Error: %sn", mysqli_connect_error());
    exit;
    }
    
    $link_to_slave = mysqli_connect(
    $slave_server,
    $slave_username,
    $slave_password,
    'mysql');
    
    if (!$link_to_slave) {
    printf("Unable to connect slave database server. Error: %sn", mysqli_connect_error());
    exit;
    }
    
    print("
    Creating database with name Jelastic on Master node ");
    
    $result = mysqli_query($link_to_master, 'CREATE DATABASE JelasticX');
    
    sleep (3);
    
    print("
    Checking if created database was replciated to slave ");
    
    if ($result = mysqli_query($link_to_slave, 'SHOW DATABASES LIKE "JelasticX"')) {
    $result_text = mysqli_fetch_array($result);
    print ("
    Replicated database is ".$result_text[0]);
    }
    
    mysqli_close($link_to_master);
    mysqli_close($link_to_slave);
    ?>
    

Conclusion

Database replication with MariaDB adds redundancy, helps to ensure high availability, simplifies certain administrative tasks such as backups, may increase performance, and much more. It’s become easy to configure database replication in the cloud, only few minutes and everything is ready. Enjoy!

http://blog.mariadb.org/database-master-slave-replication-in-the-cloud/

How to install goaccess in Centos/Fedora/Ubuntu

GoAccess is an interactive command line tool to analyse apache2/apache-httpd/ngnix logs.

It provides realtime HTTP statistics for website administrators.

GoAccess will provide following statistics:

  •  Unique visitors per day – Including spiders
  •  Requested files (Pages-URL)
  • Requested static files – (Static content: png,js,etc)
  • Referrers URLs
  •  HTTP 404 Not Found response code
  •  Operating Systems
  • Browsers
  • Hosts
  • HTTP Status Codes
  • Top Referring Sites
  • Top Keyphrases used on Google’s search engine

Install GoAccess in Ubuntu/Debian based operating systems:

$ apt-get install goaccess

Install GoAccess in RHEL/Fedora/Centos base operating systems:

In RHEL/Fedora/Centos base operating systems there is no single command available to install GoAccess. We need to install it from source code.

First install dependency packages with following command:

$ yum install glib2 glib2-devel glibc make geoip ncurses-devel

Download GoAccess source code:

$ wget http://sourceforge.net/projects/goaccess/files/0.4.2/goaccess-0.4.2.tar.gz

Uncompress source code:

$ tar xzf goaccess-0.4.2.tar.gz

Now install it by running following commands:

$ cd goaccess-0.4.2

$ ./configure

$ make; make install

Following are options available with goaccess command:

Usage: goaccess [ -b ][ -s ][ -e IP_ADDRESS][ – a ]< -f log_file >

The following options can also be supplied to the command:

-f <argument> – Path to input log file.
-b – Enable total bandwidth consumption.
For faster parsing, don’t enable this flag.
-s – Enable HTTP status codes report.
For faster parsing, don’t enable this flag.
-a – Enable a List of User-Agents by host.
For faster parsing, don’t enable this flag.
-e <argument> – Exclude an IP from being counted under the
HOST module. Disabled by default.

Example commands:

$ goaccess -f /var/log/httpd/access_log

$ goaccess -s -b -e 192.168.*.*  -f /var/log/httpd/access_log

http://viewsby.wordpress.com/2013/01/30/how-to-install-goaccess-in-centosfedoraubuntu/

Deploying iPhone Apps to Real Devices

 

In our previous article on getting started with iPhone development, you learnt how to use the iPhone SDK provided by Apple to develop your first iPhone application. For testing purposes, you used the iPhone Simulator, provided as part of the iPhone SDK. While the iPhone Simulator is a very handy tool that allows you to test your iPhone applications without needing a real device, nothing beats testing on a real device. This is especially true when you are ready to roll out your applications to the world – you must ensure that it works correctly on real devices. In addition, if your application requires accesses to hardware features on an iPhone/iPod Touch, such as the accelerometer and GPS, you need to test it on a real device – the iPhone Simulator is simply not adequate.

A repeated criticism from iPhone app developers comes from the difficulty they find in deploying their application to a real iPhone or iPod Touch. Apple, for better or worse, has designed a process involving many hoops that must be jumped through, and this has prompted developers to grumble, and others to explore alternative, non-official open tool chains, which do not require app signing. In this article, I will walk you through the steps you need to take in order to test your iPhone apps on a real device, be it iPhone, or iPod Touch, the offical Apple way.

Sign up for the iPhone Developer Program

The first step towards testing your applications on a real device is to sign up for the iPhone Developer Program athttp://developer.apple.com/iphone/program/. There are two programs available – Standard and Enterprise. For most developers wanting to release applications on the App Store, they can simply sign up for the Standard program, which costs US$99. Check out http://developer.apple.com/iphone/program/apply.html to know more about the differences between the Standard and Enterprise programs.

Start your Xcode

In order to test your iPhone applications on your device, you need to obtain an iPhone Development Certificate from the iPhone Developer Program Portal. This needs to be done once for every device you wish to test your apps on. The following sections walk you through the various steps, from obtaining your certificate, to deploying your applications onto the device.

First, obtain the 40-character identifier that uniquely identitfies your iPhone/iPod Touch. To do so, connect your device to your Mac and start Xcode. Select the Window > Organizer menu item to launch the Organizer application. Figure 1 shows the Organizer application showing the identifier of my iPhone. Copy this identifier and save it somewhere. You will need it later on.


Figure 1 Obtaining the identifier for your iPhone/iPod Touch

Generating a Certificate Signing Request

Before you can request a development certificate from Apple, you need to generate a Certificate Signing Request. This step must be performed once for every device you wish to test on. To generate the request, you can use the Keychain Access application located in the Applications/Utilities/ folder (see Figure 2).


Figure 2 Launching the Keychain Access application

In the Keychain Access application, select the Keychain Access > Certificate Assistant menu and select Request a Certificate From a Certificate Authority (see Figure 3).


Figure 3 Requesting a certificate

In the Certificate Assistant window (see Figure 4), enter your email address, check the Saved to disk radio button and check the Let me specify key pair information checkbox. Click Continue.


Figure 4 Providing certificate information

Choose a key size of 2048 bits and use the RSA algorithm (see Figure 5). Click Continue.


Figure 5 Specifying key pair information

You will be asked to save the request to a file. Use the default name suggested and click Save (see Figure 6).


Figure 6 Saving the certificate request to a file

Logging in to the iPhone Developer Program Portal

Once you have generated the certificate signing request, you need to login to Apple’s iPhone Dev Center (see Figure 7). Click on the iPhone Developer Program Portal link on the right of the page. Remember, you need to pay US$99 in order to access this page.


Figure 7 Logging in to the iPhone Dev Center

In the iPhone Developer Program Portal page, click the Launch Assistant button (see Figure 8) to walk you through the process of provisioning your iPhone and generating the development certificate.


Figure 8 Launching the provisioning assistant

You should see the welcome page as shown in Figure 9. Click Continue.


Figure 9 The welcome page of the provisioning assistant

First, you will be asked to create an App ID (see Figure 10). An App ID is a series of characters used to uniquely identify an application (or applications) on your iPhone. You only need to create an App ID once per application, i.e. you do not need a new App ID for new versions of your app. Enter a friendly name to describe this App ID (to be generated by Apple). Click Continue.


Figure 10 Creating an App ID

The next screen allows you to provide a description of your iPhone/iPod Touch. You need to provide the device ID that you have obtained earlier (see Figure 11). Click Continue.


Figure 11 Assigning a device for the provisioning

You are now ready to submit the certificate signing request to Apple (see Figure 12). The instructions on the screen show you the steps that you have performed earlier. Click Continue.


Figure 12 Generating a certificate signing request

In this screen, click the Choose File button (see Figure 13) to select the certificate signing request file that you have created earlier. Once the file has been selected, click Continue.


Figure 13 Submitting a certificate signing request

Provide a description for your provisioning profile (see Figure 14). A Provisioning profile will be generated so that you can download it at a later stage and install it on your device. Click Generate.


Figure 14 Naming your provisioning profile

A Provisioning profile will now be generated (see Figure 15). Once it is generated, click Continue.


Figure 15 Generating a provisioning profile

You are now ready to download the generated Provisioning profile onto your Mac (see Figure 16). Click Continue.


Figure 16 Downloading and installing your provisioning profile

Drag and drop the downloaded Provisioning profile (in the Downloads folder) onto Xcode (located in the Dock). This will install the Provisioning profile onto your connected iPhone/iPod Touch. Click Continue (see Figure 17).


Figure 17 Instructions to verify the installation

You can verify that the Provisioning profile is installed correctly on your device by going to the Organizer application and viewing the Provisioning section (see Figure 18) to see if the profile has been added.


Figure 18 Verifying the provisioning profile on the Organizer

Back in the iPhone Developer Program Portal, you are now ready to download and install the development certificate onto your iPhone/iPod Touch. Click the Download Now button (see Figure 19) to download the development certificate to your Mac. Click Continue.


Figure 19 Downloading and installing the development certificate

In the Downloads folder of your Mac, double-click on the developer_identify.cer file that you have just downloaded to install it into a keychain on your Mac. When prompted (see Figure 20), click OK.


Figure 20 Adding a certificate to the keychain

Back in the iPhone Developer Program Portal, you can now verify that the certificate has been installed properly in the Keychain Access application (see Figure 21). Click Continue.


Figure 21 Instructions for verifying the installation of the certificate

In the Keychain Access application, select the login keychain and look for the certificate named “iPhone Developer:” (see Figure 22). If you can see it there, your certificate is installed correctly.


Figure 22 Verifying the installation of the certificate

You are now almost ready to deploy your iPhone application onto your iPhone/iPod Touch. Click Continue (see Figure 23).


Figure 23 Instructions for installing your applications with Xcode

Click Done to dismiss the dialog (see Figure 24).


Figure 24 Finishing the installation

In Xcode, under the Active SDK item (if this item is not already on the toolbar, go to View > Customize Toolbar and add it to the toolbar), select the OS version number of the device that is currently connected to your Mac. In my case, my iPhone is running the older iPhone OS 2.0, hence I selected “iPhone Device (2.0)” (see Figure 25).


Figure 25 Selecting the active SDK

With your application project open in Xcode, press Command-R to run the application. You will now be prompted for permission to access the certificate saved in your keychain. Click Allow (or Always Allow) to go ahead with the signing (see Figure 26).


Figure 26 Signing your application with the certificate

Your application will now be deployed to the device. You can see its progress in the Summary tab of the Organizer application (see Figure 27).


Figure 27 Checking the Organizer for installation progress

Once the application is deployed onto your device, it will be running automatically. You can capture screenshots of your device by going to the Screenshot tab of the Organizer application, and pressing the capture button (see Figure 28).


Figure 28 Capturing screenshots using Organizer

Summary

In this article, you have seen the various steps required to deploy your application to your iPhone or iPod Touch. While the number of steps looked intimidating, it is actually quite straightforward. The iPhone Developer program allows you to provision up to 100 devices for testing purposes. Once a device is provisioned, you can then use the development certificate to deploy your applications onto it.

Remove Windows line endings in VIM

The Windows line endings (^M) can be easily removed with most editors. In ViM it is very easy.

To remove all windows line endings (and replace with nothing), type the following:

:%s/^V^M//g

(note that the ^V will not display).

Sometimes it is necessary to add a line break as well:

:%s/^V^M/\r/g

Some option mysqldump

–no-autocommit no-autocommit Enclose the INSERT statements for each dumped table within SET autocommit = 0 and COMMIT statements  
–no-create-db no-create-db This option suppresses the CREATE DATABASE statements  
–no-create-info no-create-info Do not write CREATE TABLE statements that re-create each dumped table  
–no-data no-data Do not dump table contents  
–no-set-names no-set-names Same as –skip-set-charset  
–no-tablespaces no-tablespaces Do not write any CREATE LOGFILE GROUP or CREATE TABLESPACE statements in output

Selectively dumping data with mysqldump

mysqldump is a command line tool for outputting table structures and data and can be used for backups etc. By default mysqldump will dump all data from a table, but it is possible to select which data to be exported with mysqldump. This post looks at how to do this.

The examples in this post have a table called “mytable” in a database called “test”. mytable has three columns: mytable_id, category_id and name, and we will be selectively exporting data that matches a specific category_id.

Using mysqldump to dump all data from the table would look like this, subsituting [username] for your username (the -t flag suppresses the table creation sql from the dump):

mysqldump -t -u [username] -p test mytable

The output from my example table looks like this, once we remove all the extra SQL commands (I’ve added linebreaks to make it more legible):

INSERT INTO `mytable` VALUES 
  (1,1,'Lorem ipsum dolor sit amet'),
  (2,1,'Ut purus est'),
  (3,2,'Leo sed condimentum semper'),
  (4,2,'Donec velit neque'),
  (5,3,'Maecenas ullamcorper');

If we only wanted to dump data from mytable in category_id 1, we would do this:

mysqldump -t -u [username] -p test mytable --where=category_id=1

which would output this:

INSERT INTO `mytable` VALUES 
  (1,1,'Lorem ipsum dolor sit amet'),
  (2,1,'Ut purus est');

You can also abbreviate –where as -w like so:

mysqldump -t -u [username] -p test mytable -wcategory_id=1

If you need to have spaces in the where query or other special shell characters (such as > and <) then you need to put quotes around the where clause like so:

mysqldump -t -u [username] -p test mytable --where="category_id = 1"
OR
mysqldump -t -u [username] -p test mytable -w"category_id = 1"

You can also use the –where flag to selectively dump data from more than one table, but obviously the columns specified in the where clause need to be in both tables.

An example of dumping data from two tables using the same where clause could look like this, where we are selecting category_id from tables “mytable” and “anothertable”:

mysqldump -t -u [username] -p test mytable anothertable --where="category_id = 1"

If category_id exists in both tables then the dump will run without error. If the column doesn’t exist, you’ll see an error like this:

mysqldump: mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `anothertable` WHERE category_id=1': Unknown column 'category_id' in 'where clause' (1054)
mysqldump: Got error: 1054: Unknown column 'category_id' in 'where clause' when retrieving data from server

mysqldump is an excellent tool for exporting data from MySQL databases. Using the –where or -w flags allows you to selectively export data from one or more tables which saves you having to export all data from a table if you only need a specific subset.

Long query log

いつの間にか会社で古株になったyamaokaです。

webアプリケーションのバックエンドにMySQLを使っている場合、
クエリ(SQL)のチューニングをする必要がありますよね。
皆さんはチューニングの計画をどのように立てていますか。

もちろん、既に明らかに重いことが想定されているページがあれば、
その処理で使われているクエリを中心にEXPLAINなどを使って解析していけばいいと思います。

でもそうではなく、全体的にクエリの見直しやチューニングを行いたい場合は
実際に実行されているクエリを確認していくという作業が必要です。
そこで使うことができる3つの方法について書きたいと思います。

遅いクエリを記録する

MySQLにはスロークエリログといって、
実行に時間がかかったクエリを記録する機能が最初から付いています。
/etc/my.cnfに次のように設定を書けば実行時間が1秒を超えたクエリが出力されるようになります。

slow_query_log = 1
slow_query_log_file = /path/to/mysql-slow.log
long_query_time = 1

オンラインでset globalを使って変更する場合は次のようにします。

set global slow_query_log = 1;
set global slow_query_log_file = '/path/to/mysql-slow.log';
set global long_query_time = 1;

出力されたログファイルをMySQLに付属しているmysqldumpslowというツールで解析すると便利です。次のように実行すれば、平均の実行時間が長い順にソートして表示してくれます。

mysqldumpslow -s at /path/to/mysql-slow.log

クエリのパラメータは数値はN、文字列はSに置換して表示してくれるので
同じクエリをまとめてチェックすることができます。

実行回数の多いクエリを記録する

実行時間は短いけれど多くの回数実行されるクエリというのもあります。
これらは通常のスローログには出てこないのですが、
実は負荷の大部分を占めている、ということもありえます。
キャッシュなど別の方法を考えることで
アプリケーションの負荷を減らすことができるかもしれません。

従来MySQLではlong_query_timeに1秒以上の値しか設定できませんでしたが、
MySQL 5.1から1秒未満の値も設定できるようになりました。
つまり、次のように/etc/my.cnfで「0」を設定すれば
全てのクエリが記録できることになります。

slow_query_log = 1
slow_query_log_file = /path/to/mysql-slow.log
long_query_time = 0

もちろん、全てのクエリの記録は負荷も大きくかかることを
理解してから設定を行うようにしてください。
また、ログの容量も大きくなるので、ディスクの空き容量にも注意が必要です。
オンラインでset globalを使って一時的に値を0に変更し、すぐに元の値(1など)に戻すのがオススメです。

set global slow_query_log = 1;
set global slow_query_log_file = '/path/to/mysql-slow.log';
set global long_query_time = 0;
# 後で set global long_query_time = 1; で元に戻す

出力されたログファイルをmysqldumpslowで次のように解析することで、
実行回数の多い順に表示することが可能です。

mysqldumpslow -s c /path/to/mysql-slow.log

mysqldumpslowは他にもいろいろ機能を持っているので、「–help」を付けて実行して
一度オプションを確認してみるといいかもしれません。

追記: MySQLでは/etc/my.cnfに次のような設定をすることで全てのクエリを記録することが可能です。
最初から全ての記録を保存したい場合はこちらの方法もいいかもしれません。

log = /path/to/mysql-query.log

インデックスを使っていないクエリを記録する

多くの場合、インデックスを使用しないクエリは遅いです。
インデックスの設計は計画的に行う必要があると思いますが、
今現在インデックスを使用していないクエリはどれなのか知りたい場合があると思います。
次のように/etc/my.cnfに記述することでインデックスを使用していないクエリを
スロークエリログに記録することができるようになります。

slow_query_log = 1
slow_query_log_file = /path/to/mysql-slow.log
long_query_time = 5
log_queries_not_using_indexes = 1

オンラインでset globalを使って設定する場合は次のようにします。

set global slow_query_log = 1;
set global slow_query_log_file = '/path/to/mysql-slow.log';
set global long_query_time = 5;
set global log_queries_not_using_indexes = 1;

出力されたログファイルは今までと同じように
mysqldumpslowを使って解析していくことになると思います。

終わりに

最近は、開発するときにフレームワークに付属のORマッパーを使ったりして
実際に発行されるクエリを意識しないことが多くなっていると思います。
もちろんそれはメリットだと思うのですが、実際に実行されるのはクエリ(SQL)である以上、
完全に意識しないで済むということはありません。

実際に発行されているクエリを眺めつつ、
少しでもパフォーマンスのよいwebアプリケーションを作っていけたらいいと思います。

追記: オプションの変数名がMySQL 5.1基準のものになっていなかったのでMySQL 5.1をベースに修正しました。

Memo

[mysqld]
long_query_time=1
log-slow-queries=/var/log/mysql/log-slow-queries.log

You must create the file manually and change owners this way:

mkdir /var/log/mysql
touch /var/log/mysql/log-slow-queries.log
chown mysql.mysql -R /var/log/mysql