mysql実験

20198 ワード

実験手順同じパソコンにmysqlが2つ入っていて、ポート番号が違います.mysql 5.6インストール後my-defaultのファイルが1つしかないので、エラー内容を追加し、mysqlを変更しても正常に起動できます.このファイルではなくmy-defaultを使用することを示します.iniはmyと名前を変えた.ini,さらにエラー内容を追加すると起動に失敗し,mysql 5.6起動時に読み込むプロファイル名のデフォルトはmyです.Iniはフレームワークspringmvc+spring+hibernateを使用していますが、データを挿入する際に使用するJdbcDaoSupportのjdbcTempleteを使用していますので、ここでhibernateも使用していませんが、同じconnectionオブジェクトを取得するため、ここではメソッドをカプセル化しています
public static final ThreadLocal<Connection> cs = new ThreadLocal<Connection>();

    

    public static Connection getConnection(DataSource dataSource) throws SQLException{

        Connection c = cs.get();

        if(null==c){

            c=dataSource.getConnection();

            cs.set(c);

        }

        return c;

    }

daoデータコード挿入
package com.h3c.itac.alarm.dao;



import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;



import javax.annotation.PostConstruct;

import javax.annotation.Resource;

import javax.sql.DataSource;



import org.springframework.jdbc.core.support.JdbcDaoSupport;

import org.springframework.stereotype.Repository;



import com.h3c.itac.alarm.po.SyslogAlarm;

import com.h3c.itac.util.ConnectionUtil;



@Repository

public class SyslogAlarmDao extends JdbcDaoSupport{

    @Resource

    public void setDatasource(DataSource dataSource){

        this.setDataSource(dataSource);

    }

    

    private long count = 0L;

    String sql1="";

    String sql2="";

    PreparedStatement ps1 = null;

    PreparedStatement ps2 = null;

    Connection con = null;

    @PostConstruct

    public void set() throws SQLException{

        sql1 = "insert into alarm(id,adesk_alarm_id,serial_no,level,source,type,device_id,create_time,upload_time,order_id,title,location,customer_id)"

                +"values(?,?,?,?,?,?,?,?,?,?,?,?,?)";

        sql2 = "insert into syslogalarm values(?,?,?,?,?,?,?,?)";

        con = ConnectionUtil.getConnection(this.getDataSource());

//        con.setAutoCommit(false);

        ps1 = con.prepareStatement(sql1);

        ps2 = con.prepareStatement(sql2);

        PreparedStatement ps3 = con.prepareStatement("select max(id) from alarm");

        ResultSet rs = ps3.executeQuery();

        while(rs.next()){

            count = rs.getLong(1);

        }

        System.out.println("alarm id     :"+count);

    }

    public void insert(SyslogAlarm sAlarm) throws SQLException{

        count++;

        ps1.setLong(1,count);

        ps1.setLong(2,sAlarm.getAlarm().getAdeskAlarmId());

        ps1.setString(3,sAlarm.getAlarm().getSerialNo());

        ps1.setInt(4, sAlarm.getAlarm().getLevel());

        ps1.setInt(5, sAlarm.getAlarm().getSource());

        ps1.setInt(6,sAlarm.getAlarm().getType());

        ps1.setLong(7, sAlarm.getAlarm().getDevice().getId());

        ps1.setLong(8, sAlarm.getAlarm().getCreateTime());

        ps1.setLong(9, sAlarm.getAlarm().getUploadTime());

        ps1.setLong(10,count);

        ps1.setString(11, sAlarm.getAlarm().getTitle());

        ps1.setString(12, sAlarm.getAlarm().getLocation());

        ps1.setLong(13,sAlarm.getAlarm().getDevice().getCustomer().getId());

        

        ps2.setLong(1,count);

        ps2.setString(2, sAlarm.getDescription());

        ps2.setString(4,sAlarm.getReason());

        ps2.setString(5,sAlarm.getAdvise());

        ps2.setString(3, sAlarm.getVariables());

        ps2.setString(6, sAlarm.getLogContent());

        ps2.setLong(7,sAlarm.getPriginalLogId());

        ps2.setLong(8, count);

        

        ps1.addBatch();

        ps2.addBatch();

        if(count%300==0){

            excuteRemainderBatchSQL();

        }

    }

    

    public void excuteRemainderBatchSQL() throws SQLException{

        ps1.executeBatch();

        ps1.clearBatch();

        ps2.executeBatch();

        ps2.clearBatch();

//        con.commit();

//        con.setAutoCommit(true);

    }

}

テストクラス
package com.h3c.itac.alarm.dao;



import java.sql.SQLException;

import java.util.Date;



import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



import com.h3c.itac.alarm.po.Alarm;

import com.h3c.itac.alarm.po.SyslogAlarm;

import com.h3c.itac.customer.Customer;

import com.h3c.itac.device.Device;



public class TestSyslogAlarmDao {



    public SyslogAlarmDao getSyslogAlarmDao() {

        ApplicationContext ac = new ClassPathXmlApplicationContext(

                "applicationContext.xml");

        return (SyslogAlarmDao) ac.getBean("syslogAlarmDao");

    }

    @Test

    public void init(){

        ApplicationContext ac = new ClassPathXmlApplicationContext(

                "applicationContext.xml");

    }

    /**    1800

     * 2,    (2.388,2.388,2.871,2.809,2.683)  2.6278

     * 1,    (2.825,2.717,2.294,2.076,2.169)  2.4162

     *    ,  1800

     * 2,    (2.981,3.261,3.433,1.888,1.935)

     * 1,    (2.091,2.293,3.354,1.95,2.371,)

     * 5000

     * 2,    (6.397,5.43,6.584,6.35,4.853)                       5.9228

     * 1,    (4.166,5.913,4.634,2.762,4.962)   4.4874

     */

    @Test

    public void testInsert() throws SQLException, ClassNotFoundException{

        double start = System.currentTimeMillis();

        SyslogAlarmDao sad = this.getSyslogAlarmDao();

        for(int i=1;i<5001;i++){

            Customer c = new Customer();

            c.setId(1L);

            Device d = new Device();

            d.setId(1L);

            d.setCustomer(c);

            

            Alarm alarm = new Alarm();

            alarm.setAdeskAlarmId((long) i);

            alarm.setCreateTime(new Date().getTime());

            alarm.setDevice(d);

            alarm.setLevel(1);

            alarm.setLocation("location "+i);

            alarm.setSerialNo("serialno "+i);

            alarm.setSource(1);

            alarm.setTitle("title "+i);

            alarm.setType(0);

            alarm.setUploadTime(new Date().getTime());

            

            SyslogAlarm sa = new SyslogAlarm();

            sa.setAdvise("advise "+i);

            sa.setAlarm(alarm);

            sa.setDescription("description "+i);

            sa.setLogContent("logcontent "+i);

            sa.setPriginalLogId(1);

            sa.setReason("reason "+i);

            sa.setVariables("variable "+1);

            

            sad.insert(sa);

        }

        sad.excuteRemainderBatchSQL();

        double end300 = System.currentTimeMillis();

        System.out.println((end300-start)/1000);

    }

    

}

my-defaultだけをiniファイルはmyと名前を変更します.Iniファイルは、内部構成ではなくtestInsertを実行する際に速度が遅くなり、600本挿入しても20秒近くかかります.
他のバージョンのmyを探してiniファイル、名前を変えたmyを置き換えます.iniファイルは、速度が速く、前のバージョンのmyに問題があると考えられます.iniと改名後のmy.iniのファイル構成内容上
そして名前を変えた前後のmyをCompareで比較します.iniファイルの内容はCompareアシストツールを使用してテストします.(名前を変更したmy.iniファイルに存在しないコンテンツをCompareを使用して、以前のバージョンのmy.iniファイルの内容を行ごとに名前を変更したファイルに追加し、mysqlサービスを停止し、変更後のファイルを保存し、データベースを空にし、testInsertメソッドを実行し、実行時間を観察します.
その後、ある構成が機能していることに気づきました.
# If set to 1, InnoDB will flush (fsync) the transaction logs to the# disk at each commit, which offers full ACID behavior. If you are# willing to compromise this safety, and you are running small# transactions, you may set this to 0 or 2 to reduce disk I/O to the# logs. Value 0 means that the log is only written to the log file and# the log file flushed to disk approximately once per second. Value 2# means the log is written to the log file at each commit, but the log# file is only flushed to disk approximately once per second.innodb_flush_log_at_trx_commit = 2
一、この構成が2の場合、コードが上記のようにトランザクションを自動的にコミットすると、挿入データの速度が著しく向上し、以前のバージョンのmy.iniファイルとほぼ同じになります.
二、この構成が1の場合、コードは依然として上記のように、自動的にトランザクションをコミットすると、データの挿入速度が著しく遅くなる
三、この構成が依然として1の場合、手動でトランザクションを提出し、上記のコードcon.settAutoCommit(false);とcon.commit()の注釈を削除すると、挿入データも著しく向上し、第1の状況と差が少なく、挿入データが多すぎると第1の状況より速くなる.
四、この構成が2の場合、上記のコードcon.settAutoCommit(false)とcon.commit()の注釈を削除すると、挿入速度も著しく向上します.
五、innodb_flush_log_at_trx_commit=2の構成を削除し、手動でトランザクションをコミットするように設定すると、挿入速度も著しく向上する
六、innodb_flush_log_at_trx_commit=2構成を削除し、自動的にトランザクションをコミットし、速度が明らかに遅い.
 
 
以上、mysql 5.6バージョンでデフォルト構成を変更する場合は、my-default.iniファイル名をmy.iniファイル名に変更することで、ファイル構成の変更が可能になります.
上記のテスト結果からも分かるように、1または2の構成にかかわらず、手動でトランザクションをコミットすれば、jdbcで行われるテストであり、hibernateの必要性は不明である.
my.ini
# For advice on how to change settings please see

# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html

# *** DO NOT EDIT THIS FILE. It's a template which will be copied to the

# *** default location during install, and will be replaced if you

# *** upgrade to a newer version of MySQL.

[mysqld]



# generic configuration options

port        = 3306

socket        = /tmp/mysql.sock

character-set-server=utf8



innodb_print_all_deadlocks=1



innodb_locks_unsafe_for_binlog=1



expire_logs_days=2



event_scheduler=1



# If set to 1, InnoDB will flush (fsync) the transaction logs to the

# disk at each commit, which offers full ACID behavior. If you are

# willing to compromise this safety, and you are running small

# transactions, you may set this to 0 or 2 to reduce disk I/O to the

# logs. Value 0 means that the log is only written to the log file and

# the log file flushed to disk approximately once per second. Value 2

# means the log is written to the log file at each commit, but the log

# file is only flushed to disk approximately once per second.

innodb_flush_log_at_trx_commit = 2