4
votes

I am using Rails 2.3.5 and Oracle 10 as my database, use "oracle_adapter" , and ruby-oci8 to connect to the Oracle host.

I get this exception:

Completed in 463ms (View: 18, DB: 166) | 200 OK [http://192.168.30.128/auctions?page=1]
/!\ FAILSAFE /!\  Mon Feb 01 19:02:11 +0800 2010
  Status: 500 Internal Server Error
  ORA-12541: TNS:no listener
    env.c:257:in oci8lib.so
    /home/qichunren/.gem/ruby/1.8/gems/ruby-oci8-1.0.7/lib/oci8.rb:229:in `initialize'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:623:in `new'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:623:in `new_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:659:in `initialize'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:35:in `new'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:35:in `oracle_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:223:in `send'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:223:in `new_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:245:in `checkout_new_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:188:in `checkout'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:184:in `loop'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:184:in `checkout'
    /usr/local/ruby187/lib/ruby/1.8/monitor.rb:242:in `synchronize'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:183:in `checkout'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:98:in `connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:326:in `retrieve_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_specification.rb:123:in `retrieve_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_specification.rb:115:in `connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/query_cache.rb:9:in `cache'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/query_cache.rb:28:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/string_coercion.rb:25:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/head.rb:9:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/methodoverride.rb:24:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/params_parser.rb:15:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/session/cookie_store.rb:93:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/failsafe.rb:26:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `synchronize'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:114:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/reloader.rb:34:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:108:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/cgi_process.rb:44:in `dispatch_cgi'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:101:in `dispatch_cgi'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:27:in `dispatch'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:76:in `process'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `synchronize'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `process'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:159:in `process_client'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `each'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `process_client'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `initialize'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `new'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `initialize'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `new'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:282:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:281:in `each'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:281:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/command.rb:212:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281
    /home/qichunren/.gem/ruby/1.8/bin/mongrel_rails:19:in `load'
    /home/qichunren/.gem/ruby/1.8/bin/mongrel_rails:19

it seems that the connection to Oracle often disconnects. It shows oracle error:**ORA-12541: TNS:no listener**.

How do I fix this?

oci8.c:270:in oci8lib.so: ORA-12541: TNS:no listener (OCIError)
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_oci_connection.rb:223:in `new'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_oci_connection.rb:223:in `new_connection'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_oci_connection.rb:328:in `initialize'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_oci_connection.rb:24:in `new'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_oci_connection.rb:24:in `initialize'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_connection.rb:9:in `new'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_connection.rb:9:in `create'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_adapter.rb:50:in `oracle_enhanced_connection'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/c                                                                         onnection_specification.rb:291:in `send'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/c                                                                         onnection_specification.rb:291:in `connection='
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/c                                                                         onnection_specification.rb:259:in `retrieve_connection'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/c                                                                         onnection_specification.rb:78:in `connection'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2438:in `quoted_table_                                                                         name'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1259:in `find_one'
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1250:in `find_from_ids                                                                         '
        from /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:504:in `find'
        from script/maintenance/adjust_settlement.rb:19
4

4 Answers

2
votes

At first you should use oracle_enhanced adapter as original oracle adapter is not supported anymore. And also I recommend to use latest ruby-oci8 version 2.0.3. And also check which Oracle client version are you using - I recommend Oracle Instant Client 10.2.0.4 or later

But if you get ORA-12541: TNS:no listener error then it seems that the issue could be in network connectivity to database or some issue on Oracle server side. But please try oracle_enhanced adapter and latest ruby-oci8 version and tell if it fixes your problem.

2
votes

Make sure:

  • You correctly set up the connection name in ${ORACLE_HOME}/network/admin/tnsnames.ora .
  • You set ORACLE_HOME before the oci8 driver is loaded.

If that doesn't work, explicitly specify the host[:port]/sid as the database name.

E.g. if your host is mydbhost.myorg.org, port number is 1522 and sid is employeedb, you'd use this:

database: mydbhost.myorg.org:1522/employeedb

If your port is the default 1521, you can omit the colon and port number.

0
votes

I think your listener is timing out due to no activity. I suspect you're opening the connection, issuing a query, then leaving the connection open as the code idles waiting for another client request. That's OK if your database is set up to allow connections to be permanent but that can use up all the pool, which is something most sites don't want.

You can either tweak the database to allow longer sessions, or tell it to not disconnect at all, or modify your code to check for a connection before attempting to send a query, reconnect if necessary, then continue.

Not all database adapters allow you to do a keep-alive/heartbeat or even to ask if the server connection is alive, so I've had to revert to wrapping a simple select 1 from a table within an exception handler, just to poke the connection before continuing.

Another alternative would be to put a simple "keep-alive" routine in a separate thread that periodically does a simple request, like select 1, to keep the database happy. If that routine senses the connection has dropped then it would be responsible for setting a "db_connection_up" flag to false or to reconnect.

You have to determine the best way of handling it based on the number of requests you'll be handling. Connecting, issuing a tiny request, then disconnecting repeatedly, is a different kind of bad thing to do so you have to find a happy medium.

Talk to your DBA to see what the timeout is in the Oracle DB, and whether it can be changed or if you can get a permanent connection. If not, tweak your code.

Search the googles for "oracle listener timeout" for more info.

0
votes

Kelvin's answer works for me. additionally, there's another approach.

I was using rails 4.1.x, Gemfile:

gem 'activerecord-oracle_enhanced-adapter', '~> 1.5.0'
gem 'ruby-oci8', '2.2.3'

database.yml:

# not work!
host:  218.5.173.xxx/my_db

# works, solution 1:  
database: 218.5.173.xxx/my_db


# works, solution 2: 
database: "(DESCRIPTION=
(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=218.5.173.xxx)(PORT=1521)))
(CONNECT_DATA=(SERVICE_NAME=my_db))
)"