アフィリエイト広告を利用しています

広告

この広告は30日以上更新がないブログに表示されております。
新規記事の投稿を行うことで、非表示にすることが可能です。
posted by fanblog

【sqlite3】create table asってそういう仕様だったんですね・・・

SQLite3でテーブルをコピーする方法の一つ、create table as構文にはちょっとした罠があります。
「create table 新しいテーブル名 as select * from 元となるテーブル名」

これで「元となるテーブル」と同じスキーマーの「新しいテーブル」が作成され、さらにデータもコピーできると思い込んでいました。

主キーが設定されたテーブルのcreate table asで作成された「新しいテーブル」には、primary keyが存在しませんでした。

SQLite3ではprimary keyはcreate tableのみ設定することができます。ALTER TABLE構文では対応していません顔3(かなしいカオ)

同一データベースファイル中であれば、ALTER TABLEで名前を変えるのが一番手っ取り早いです。

attach databaseで別のデータベースファイルにあるテーブルのコピー手段として、create table asを使っていました。

この場合の対策案は、2つあります。
  1. 1 主キーのあるテーブルは、create table asでコピーしない。
    create table 新しいテーブル( pk primary key ... )
    insert into 新しいテーブル select * from 元となるテーブル

    テーブルのスキーマーは、以下SQLで取得できます。
    SELECT sql FROM SQLITE_MASTER WHERE name='元となるテーブル'


  2. 2 dumpを使って経由する
    sqlite3 元.sqlite3 .dump 元となるテーブル | sqlite3 運用.sqlite3
    → 元となるテーブルが正しくコピーされます。
    sqlite3 運用.sqlite3 "alter table 元となるテーブル rename to 新しいテーブル"

    運用.sqlite3に「元となるテーブル」名と同名がある場合は、上記を応用し、一時的なsqlite3データベースを作成して、経由することで別名を実現可能です。



レンタルサーバーならエックスサーバーがおすすめ、今( 2022/4/7まで)お得ですよ【2022年3月7日時点】

数あるレンタルサーバーの中でエックスサーバーがとてもいいと思うポイントは「満足度が高い」ところです。
  1. 【契約者に優しい対応】以前に契約した古いサーバーでも自動的に最新サーバーに移行してくれた(数時間のストップあり、ユーザーはほぼ何もしなくてOKでした)。

  2. 【速い】サーバー自体素早いレスポンス(Google PageSpeed Insightsでサーバーの応答性に関する問題は発生しづらいです)

  3. 【満足】継続する増強 KUSANAGI対応、転送量上限無制限化


ずーっと使い続けても「速い」が維持されるところがいいですよ。

続きを読む...

HTMLを更新後、表示が変更前のままです。コレで直ります【エックスサーバー】

データベースや、テキストファイルのデータを表示するPHPのオリジナルサイト、フレームワークを使ってサイトは、データベースやテキストファイルを最新の内容に書き換えても修正内容が反映されないことが起きやすいです。ワードプレスのサイトはこれには該当しないので安心して利用できます。PHPオリジナルサイトの話です。

HTMLを更新後、表示が変更前のままです。コレで直ります【エックスサーバー】


エックスサーバーは、PHPの初回実行時に、PHPの内容を最適化した状態でキャッシュしておき、次回以降、 同じPHPにアクセスがあった際にキャッシュしたPHPで高速になる機能が標準装備されています。(APC / OPcache)
コンパイル済みPHPプログラムをメモリに格納して、メモリ上のプログラムを再利用しています。

PHPプログラムから読むテキストファイルに変更を加えても、サイトの表示は変更前のままでした。
利用しているとプログラムの実行結果もキャッシュされていると感じることが多いです。


また、「mod_pagespeed設定」を有効にすると、ファイルを圧縮してデータ転送量を削減する、同種のファイルを一まとめにして無駄な通信を削減するなどの最適化処理を実行しています。
今このmod_pagespeedはOFFの設定でも、表示が修正前のままの状態になっています


HTMLテキストファイルを更新し、表示が反映されないのは、キャッシュが原因です。
キャッシュをクリアするには、PHPファイルの日付を最新にするのが最も簡単な方法です。


以下、sshでxserverにログインして、PHPファイルの日付を更新する方法です。
cd ドメイン/public_html/
(ドメインの公開フォルダに移動します。)

ls *.php
(PHPファイルの一覧を表示させます。)

目的のファイルの日付を更新します。
touch php-file-name.php

touchコマンドは、存在するファイルの日付を最新にします。
ファイルが存在しない場合、新規作成してしまうので、打ち間違いに注意してください。

間違ってファイルを作ってしまったら、以下コマンドで消すことができます。
rm -i 間違って作ってしまったファイル名
-iパラメーターを指定することで確認メッセージが表示されます。


これで、ブラウザで表示を更新すると最新の内容に反映されたことが確認できます。


もし、直っていない方は、更新すべきphpファイルを間違えている可能性があります。
.htaccessでRewriteしている場合、index.phpも合わせてtouchしてみると直る可能性があります。



エックスサーバーで30秒以上のCronを上手に運用する3つのコツ

エックサーバーはcronが利用できます。cronはWindowsでいうatコマンドやスケジューラーみたいな機能です。
お好みのプログラムを10分毎に処理を実行させたり、毎日決まった時間に実行させることができます。

cronが使えるレンタルサーバーは、さくらレンタルサーバー、ロリポップ!などcron レンタルサーバーで探すことで対応しているレンタルサーバーが見つかります。

登録できるスケジュールの数、動いたスケジュールの稼働時間など何かしらのリミットがもうけられています。エックサーバーの場合は、CPUを100%使って良い時間に制限があります。

1回の実行で許容されるCPUフルの時間が30秒を超えると、そのプログラムが強制終了されます。
具体的には、Maximum execution time of 30 seconds exceededというメッセージとともに強制終了されます。

sleepやusleepで実行率を下げればいける!?と思いましたが、完了するまでの時間を伸ばすだけで、実処理のCPU時間の上限は変わりません。考えると当たり前ですね・・そのためほぼ同じ位置で処理が止まります。

CPUをぶん回し、30秒以内に完了するプログラムは、そのままなんの工夫もしないでいけます。

30秒をちょっとでも超えるプログラムは、強制的にプロセスが終了してしまうので対策が必要です。

エックスサーバーで30秒以上のCronを上手に運用する3つのコツ


これからご紹介するのは、エックスサーバーに限らず、PHPをcron実行させ、時間制限のあるサーバーでCronを使うためのコツとして使えます。

同じ処理を何度もcron実行させ、目的の処理を完了させるように変更します。

コツ1 ループ処理の実行時間を計測する


microtime()で経過時間を測定します。これは、強制終了で中途半端な位置で終了を防ぐ目的です。

以下のようなループ回数が多いパターンなどで使えます。
foreach( $datas as $key => $data ){
1つあたりの処理時間は大したことがない関数();
ループ回数が多いと強制終了される
}


このように実行から28秒経過した時点でループ処理を抜けることが可能になります。
$st = array_sum( explode(' ', microtime() ));
$実行時間タイムアウト=false;
foreach( $datas as $key => $data ){
if( (array_sum( explode(' ', microtime() )) - $st ) >= 28 ){
$実行時間タイムアウト=true;break;
}
1つあたりの処理時間は大したことがない関数();
ループ回数が多いと強制終了される
}
if( $実行時間タイムアウト ){
// タイムアウト用処理
}
完了処理();

これで許容されるCPUフルの時間前に処理を停止することが可能になります。

コツ2 処理結果を記録する


コツ1で実行時間を判断することが可能になりました。このままでは毎回先頭から始まってしまうので、何度やっても同じところで止まってしまいます。これを回避するにはやった処理を記録し、スキップさせます。
$st = array_sum( explode(' ', microtime() ));
$実行時間タイムアウト=false;
$進捗=array(); if( file_exists("進捗.json") ){ $進捗 =json_decode(file_get_contents("進捗.json"),true);}
foreach( $datas as $key => $data ){
if( array_key_exists( $key , $進捗 ) == true) { continue;}
if( (array_sum( explode(' ', microtime() )) - $st ) >= 28 ){
$実行時間タイムアウト=true;break;
}
1つあたりの処理時間は大したことがない関数();
$進捗[$key]=true;
ループ回数が多いと強制終了される
}
file_put_contents( "進捗.json", json_encode($進捗) );
if( $実行時間タイムアウト ){
// タイムアウト用処理
}
完了処理();

実行した処理を処理済み配列$進捗に格納していきます。ファイルに保存して、次回実行時に読み込まれるので、複数回呼ばれても同じ処理を実行することがなくなります。
スキップさせたい単位の処理済み配列は、この例では、キーワード単位にしています。粒度はご自身の処理に合わせて変更することが可能です。


コツ3 throwを使ってシンプルにする


コツ1、コツ2で大抵対応できます。throwを使うと処理をシンプルに書くことが可能です。
時間を計測して、タイムアウトを検出したら、次の処理に進まずに処理を終了させたいですよね。
この際、throwを使います。
function main(){
try{
前処理();
時間計測している処理1();
時間計測している処理2();
時間計測している処理3();
後処理();
}catch(Exception $e ){

}
}
function 時間計測している処理1(){
ループ処理でタイムアウトを検出、throw new Exception("タイムアウト処理1");
}


メイン処理の中から個別に呼び出した処理でそれぞれタイムアウトを検出するようにしています。
通常、処理1が終了すると続けて、2、3、と流れていきます。throw new Exception("")で例外を発生させると次の処理に進まずに、メイン処理のcatch部に流れてきます。

これにより、メイン処理の構造を変えずに、シンプルに処理を中断させることができます。

おまけ PHPのバージョン指定を忘れずに


エックスサーバーは複数のバージョンのPHPを利用することができる環境になっています。
そのため、通常何もバージョンを指定しないphpは、PHP 5.3.3 です。
PHPのバージョンの違いによって思わぬ副作用があったりするので、必ずバージョンを指定して利用しましょう
PHP7系は以下のパスにあります。
/usr/bin/php7.1 (PHP 7.1.2)
/usr/bin/php7.0 (PHP 7.0.16)

おまけ2 cronの設定はsshからできるよ


エックスサーバーのコンソール(ブラウザ)からスケジュールを指定できます。
これ以外に、sshログインした後、以下コマンドでスケジュールを編集することができます。
$ crontab -e 

viの使い方や、cronの書き方がわからない場合は、ググると詳しいサイトが見つかります。

先頭に#をつけるとコメントアウトできます。もし何か異常があったら先頭に#をつけて停止しておきましょう。

以下コマンドでスケジュールの一覧を確認することができます。
$ crontab -l



まとめ


ここまで、エックスサーバーで30秒以上のCronを上手に運用する3つのコツをご紹介してきました。
この記事にたどり着いた方はコアな方に違いない!って思ってます。



エックスサーバーでSIRIUSサイト(iPhone)は500サーバエラーになりがちです

『sv1〜sv1999サーバー』ハードウェアの大幅増強および最新サーバー環境への移行(2017年11月告知)
新サーバー移行後、本記事の内容は不要です。うまく動作しなくなる可能性があります。
すでにSIRIUSの.htaccessに記載されている方は、suPHP_ConfigPath、AddHandler、FCGIWrapperの記載をコメントアウト、または削除してください。


エックスサーバーはとても快適に使えるサーバーとして評価されています。
SIRIUSの上位版を使ってHTMLサイトをアップロードして、iPhoneで確認するとエラーになります。
アクセスしようとしたページは表示できませんでした
「>アクセスしようとしたページは表示できませんでした。」
500 Internal Server Error

パソコンからEdge/Chrome/Safari/FireFoxでアクセスすると正常に表示されます。

そのため見逃しがちになりやすいエックスサーバー特有の現象です。

エックスサーバーでSIRIUSサイト(iPhone)は500サーバエラーになりがちの理由

続きはこちら

エックスサーバーは料金据え置きでオールSSDに対応してくれました♪

エックスサーバーX10 契約中です。
本日(2017年7月11日)、エックサーバーからメールが届きました。

ディスク読み込み速度が48倍以上!新規受付サーバーへのオールSSD RAID10構成採用のお知らせ


今日からエックスサーバに申し込んだ方は、
200GBのRAD10のSSD環境をレンタルすることが可能です。

このメールで初めて知ったんですが、
※MySQLサーバーは既に全サーバーSSDを採用済みです。
って書いてありました。



サーバー用途のHDDは、RAID構成で単品HDDより高速かつ信頼性の高いものになっているのが一般的です。

RAID構成の場合、アクセス速度が高速化できるので、SSDより速くできることもあります。


今回のオールSSD化は、RAID構成を採用しています。

今までのHDDより48倍以上も読み込み速度が向上しています。




しかも、既存ユーザーもオールSSD構成の最新サーバー環境へ移行することが決定しています!

sv1.xserver.jpからsv1999.xserver.jpのサーバーをレンタルしている方は、
なんと、今日から最新サーバーへ移行する手続きができます!

sv2001.xserver.jp〜sv2999.xserver.jp サーバーの方は、2017年冬から移行手続きを受け付ける予定みたいです。

今日から新サーバー簡単移行が行えるサーバーだったので、早速移行しようとしましたが、
ちょうど契約更新月だったようで、チャージしないといけないみたいでした。

移行しようとしましたが、以下のような警告が表示されていました。

サーバー利用期限まで残り1ヶ月のため、移行手続きを行うことができません。
(サーバー利用期限:2017-07-31)



後日、手続き等をアップしますね!



↓↓↓ エックスサーバーはこちらをクリックしてください ↓↓↓

月額900円(税抜)から、高速・多機能・高安定レンタルサーバー『エックスサーバー』



SSDっていいの?


ブラウザでキャッシュする仕組みもあるし、ワードプレスもW3TotalやJetPackなどでキャッシュできるから別にHDDでもいいんじゃないの?
SSDの方が良い結果に結びつきます。


SSDは、HDDの48倍高速です。(エックサーバー)

キャッシュは、どこにあるかご存知ですか?

全部ディスクです。OSのスワップファイル、ワードプレスのキャッシュファイル、全部ディスクアクセスです。
ディスクが高速だと、その分レスポンスが速くなります。


まとめ


今回は、全部SSDのレンタルサーバーを月額900円〜でレンタルできるようになりました。
というご報告です。


メインサイトは、エックスサーバーがオススメです。

↓↓↓ オールSSD & 無料SSLならエックサーバーはこちらをクリック ↓↓↓

月額900円(税抜)から、高速・多機能・高安定レンタルサーバー『エックスサーバー』
















エックスサーバーのsqlite3でどハマりした件

データベースっていいですよね!
MySQLとか、SQLiteとか、レンタルサーバーで使いたい放題です。

そんな感じなので、サーバー移転とか、とっても安易に考えていました・・・


今回、お名前共用サーバーからエックスサーバーへ乗り換えようと思い立った理由は、
お名前共用サーバーの月額1000円、エックスサーバーの月額1000円、金額が同じだからです。

お名前共有サーバーを使っていて、すごい困った事っていうのは特にありませんでした。
ちょっと困ったなってことはいくつかあって
  1. お名前共有サーバーから外部へ接続(FTP/HTTP)する経路がブロックされていることがある
  2. 上の影響か、wordpressのアップデートを実行すると、とても遅く感じる
  3. PageSpeed Insightsでサーバーの応答速度の指摘事項を消す事ができなかった
  4. mod_deflate/mod_expiresが使えない

振り返ると結構あるもんですね

ま、いいんです、お名前COMで賢威も安く買えたので、満足しています。







今回エックスサーバーに変えたのは、php7が使える事、mod_pagespeedが使えたりすること、
あと、お友達に聞くと、みんな揃ってエックスサーバーがいいってオススメされたこともでかいです。


と、かる〜い気持ちで、X10を契約しました。
(お名前 共用サーバーは、しばらくお別れする予定です)


お名前共用サーバ vs エックスサーバー X10を軽く比較


ほぼデフォルトの.htaccessでエックスサーバーX10は、
「PageSpeed Insights サーバーの応答速度は合格」です。
これだけでも、結構満足度高いです。

ちなみに、お名前共用サーバーではあがいてあがいて、不合格のままでした。



gccも使えたので、コンパイルし放題かもしれません。


ただ、libcは2.5。gccは4.1.2と結構古めです。
今時のバイナリを持ってきても、libcが古いので動かない可能性大です。
コンパイルしましょうね!(make/configureはちゃんと動きました)



前置きが長くなってしまいました、ようやく本題に入ります。
現時点では解決できていません。

エックスサーバーのsqlite3でどハマりした件


エックスサーバーは、php7への取り組みがとても早かったので、スペック最新なんだね!
という印象でした。

だから、あまり細かいところまで確認しないで契約してしまったのがいけないんですけど・・

お名前.comの共用サーバーでは、pdo_sqliteのバージョンは、3.7系でした。

エックスサーバーでは、pdo_sqliteのバージョンは、3.3系でした。

そう、とっても古いバージョンなんです。

全文検索を前提に組んでしまったシステムがあり、VIRTUAL テーブルとFTSを使っています。
実はこれがネックになっていて、3.3系では弾かれエラーになりました。(ー ー;)

sqlite3.3.6では対応していないんです・・・

問い合わせしてみたら、1時間あまりで即応答もらえました。
(エックスサーバーのサポートいいね!)

sqlite3.3.6以外は使えないとの回答でした。ガッテム・・・


システムを組んでいるひとは、必要なモジュールのバージョンをしっかり確認しましょう
と、少し失敗してしまった私が言います(笑)


じゃ、どうするか・・・
エックスサーバーのX10は
50個のMySQLサーバーデータベースで、1つあたり500MBまでの容量が使えます。

1データベース500MBの制限はちょっと厳しい感じですが、データベースを複数個使ったシステムに変更しようと計画中です。

あまり手を加えたくないんですけどね・・・

もう一つの方法は、こちらの記事「sqlite3, pdo_sqlite モジュールの全文検索(FTS)対応コンパイル手順」に書いてある方法です。
FTSが有効なpdo_sqliteを自分で用意して、php.iniに適用する方法です。
この方法は、エックスサーバーのサポート外、自己責任となります。
ただ、既存ソースコードに手を加えなくていいっていうところが魅力です。

エックスサーバー SQLite3 は 3.8系だった


pdo_sqlite(PDO)SQLite Library:3.3.6
sqlite3(Native)SQLite3 module version:0.7-dev
SQLite Library:3.8.10.2

PDOとSQLite3のバージョンは一緒だと思っていたんですが、違いました!

ちなみにPHPは、php-7.0.7を使っています。

3.8系はFTS、全文検索がサポートされているので期待大です。

ただ・・・

PDOとSQLite3は別物です。似ているけど使い方が違います


この違い、差分を吸収できるクラスを知っているって方はコメントから教えていただけると幸いです。
PDOで使っていたソースを
new SQLite3差分クラス()的な呼び出しをすると
後はPDOとSQLite3の差分を吸収してくれて、ソースを修正する必要ないって感じが望みなんです。

  1. トランザクション PDO::beginTransaction() vs $sqlite3->exec("BEGIN ;");
  2. フェッチ PDOStatement::fetch() vs SQLite3Result::fetchArray()

    SQLite3はカーソルっていう概念がないんです><


  3. Exec PDOは行数を返します、SQLite3は成功、失敗だけです

まだまだ違いはたくさんあります。

そのまま修正するとソースコード修正箇所もうなぎのぼり!


と、ちょっと断念気味です。

エックスサーバーのsqlite3でどハマりした件 修正方法のまとめ


ここまでの修正方法をまとめると3つの方法がありました。
  1. 1)sqlite3をやめて、MySQL+FULLTEXTを活用する

    PDOを使っているので、ソースコードの修正は部分的です。でもqueryの方法が違うので、それなりの規模感を感じています。

  2. 2)pdo_sqlite3を自前で用意する

    エックスサーバーと同じようなLinuxのバージョン、gccなどを揃えて、pdo_sqlite3を作る必要があります。
    ソースコードの修正は一切不要です。
    コンパイル環境を用意したりするのが面倒ですね

  3. 3)PDO=>new SQLite3()に変更する

    エックスサーバーのpdo_sqliteのバージョンは古かったですが、SQLite3のバージョンは3.8系で新しかったです。
    PDOとSQLite3クラスは考え方が違うので、ソースコードの修正は広範囲になりそうです。



いずれにしても、いばらの道の予感がビリビリ来ています(笑)

コンパイル済みのpdo_sqlite3(FTS有効)があればベストなんですけどね・・





最後に


ここで書いているのは独自のPHPでシステムを組んでいる場合の話で、
ワードプレスを使い倒す分には、エックサーバーという選択は正しいと感じています。

速くて、PHPのバージョンも豊富だからオススメできます。

詳しくはこちらから↓↓↓↓↓



X10じゃ何もないかと思っていたんですが、ドメイン1つもらえました。
サーバ使っている限りはずっと更新料がかからないやつでした。
地味に嬉しいです(笑)






エックスサーバーのsqlite3でどハマりした件 修正方法のまとめの追記(7/14)


最終的に移行できたので、その顛末をご報告しておきます。
  1. 1)sqlite3をやめて、MySQL+FULLTEXTを活用する

    最後の手段として残しておきました。結局この方法は選びませんでした。


  2. 2)pdo_sqlite3を自前で用意する

    この方法は断念しました。以下に理由を説明します。

    まず、エックスサーバーはLinux x86_64です。だから適当なRPMからpdo_sqlite3を抜き出せばいけるんじゃ?
    RedHat EL 6 for x86_64のpdo_sqliteをダウンロードし、抽出、そしてエックスサーバーに適用してみました。
    =>エラーでロードできませんでした。PHP Warning: PHP Startup: Unable to load dynamic library
    pdo_sqlite.so: undefined symbol: __zend_calloc in Unknown on line 0

    別途環境を用意するのは面倒だったので、エックスサーバーにはgccがあるじゃないか!

    phpをコンパイルし、エックスサーバーでphpizeコマンドを作りました。
    phpizeコマンドでpdo_sqliteをコンパイルし、適用してみました。
    =>うまくいきません>< 
    調べてみるとphp.iniでフルパスextensionを指定しても、
    所定のフォルダ以外に置かれたものは適用できない旨の情報をみつけました。
    つまり、root(管理者)じゃなきゃ、無理って思い、この時点で諦めました。



  3. 3)PDO=>new SQLite3()に変更する

    結局この方法を採用しました。
    PDO(sqlite3)からnew SQLite3への変更箇所をまとめる以下6点でした。
    ごにょごにょやりながらメモっていたので抜けがあるかもしれません。ご了承ください。

    • 1.接続文字列のsqlite:=>””に変更する
    • 2.fetch(PDO::FETCH_ASSOC)=>fetchArray(SQLITE3_ASSOC)に変更する
    • 3.プリペアを使っていない closeCursor() =>finalize()
    • 4.プリペアを使っている closeCursor() =>close()
    • 5.beginTransaction() =>exec("BEGIN;")
    • 6.prepare execute(array) の流れ=>prepare bindParam(bindValue) execute(void)

      bindParamで文字列の結合を行った値を渡していたらうまく動かずかなり悩みました。
      渡した値は参照渡しが基本で、bindParamで設定した値が確定するタミングはexecute、ということで
      エラーになっていました。http://webmaster.chielog.com/php/133.htmlが参考になりました。
      bindParam(1,"xx".$xx."xx")を変数を使って、bindParam(1, $value1)とかに変更したら問題解決です。






今回のロジックではCRUD系が少なかったので楽でした。

CRUD系のロジックをPDOからnew SQLite3に変更するのはとても面倒な作業になりますね><

VPSとかだとルートにもなれるので簡単だったんですが、共用サーバーなので仕方ありませんね


ついでに、PHP5.5系からPHP7.0系に変更しましたが、こちらはすんなりと移行できました(^O^)/






最新記事
最新コメント
タグクラウド
カテゴリアーカイブ
×

この広告は30日以上新しい記事の更新がないブログに表示されております。